Linux Input/HID development
 help / color / mirror / Atom feed
* [dtor-input:next] BUILD SUCCESS 2960d4c8e77aba365df80b69e72f88b29011b111
From: kernel test robot @ 2024-06-03 17:26 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next
branch HEAD: 2960d4c8e77aba365df80b69e72f88b29011b111  Input: tablet - use sizeof(*pointer) instead of sizeof(type)

elapsed time: 759m

configs tested: 163
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha                             allnoconfig   gcc  
alpha                            allyesconfig   gcc  
alpha                               defconfig   gcc  
arc                              allmodconfig   gcc  
arc                               allnoconfig   gcc  
arc                              allyesconfig   gcc  
arc                                 defconfig   gcc  
arc                   randconfig-001-20240603   gcc  
arc                   randconfig-002-20240603   gcc  
arm                              allmodconfig   gcc  
arm                               allnoconfig   clang
arm                              allyesconfig   gcc  
arm                                 defconfig   clang
arm                   randconfig-001-20240603   gcc  
arm                   randconfig-002-20240603   gcc  
arm                   randconfig-003-20240603   gcc  
arm                   randconfig-004-20240603   gcc  
arm64                            allmodconfig   clang
arm64                             allnoconfig   gcc  
arm64                               defconfig   gcc  
arm64                 randconfig-001-20240603   gcc  
arm64                 randconfig-002-20240603   gcc  
arm64                 randconfig-003-20240603   clang
arm64                 randconfig-004-20240603   gcc  
csky                             allmodconfig   gcc  
csky                              allnoconfig   gcc  
csky                             allyesconfig   gcc  
csky                                defconfig   gcc  
csky                  randconfig-001-20240603   gcc  
csky                  randconfig-002-20240603   gcc  
hexagon                          allmodconfig   clang
hexagon                           allnoconfig   clang
hexagon                          allyesconfig   clang
hexagon                             defconfig   clang
hexagon               randconfig-001-20240603   clang
hexagon               randconfig-002-20240603   clang
i386                             allmodconfig   gcc  
i386                              allnoconfig   gcc  
i386                             allyesconfig   gcc  
i386         buildonly-randconfig-001-20240603   clang
i386         buildonly-randconfig-002-20240603   clang
i386         buildonly-randconfig-003-20240603   gcc  
i386         buildonly-randconfig-004-20240603   gcc  
i386         buildonly-randconfig-005-20240603   gcc  
i386         buildonly-randconfig-006-20240603   clang
i386                                defconfig   clang
i386                  randconfig-001-20240603   clang
i386                  randconfig-002-20240603   gcc  
i386                  randconfig-003-20240603   gcc  
i386                  randconfig-004-20240603   clang
i386                  randconfig-005-20240603   clang
i386                  randconfig-006-20240603   gcc  
i386                  randconfig-011-20240603   clang
i386                  randconfig-012-20240603   clang
i386                  randconfig-013-20240603   clang
i386                  randconfig-014-20240603   clang
i386                  randconfig-015-20240603   clang
i386                  randconfig-016-20240603   gcc  
loongarch                        allmodconfig   gcc  
loongarch                         allnoconfig   gcc  
loongarch                           defconfig   gcc  
loongarch             randconfig-001-20240603   gcc  
loongarch             randconfig-002-20240603   gcc  
m68k                             allmodconfig   gcc  
m68k                              allnoconfig   gcc  
m68k                             allyesconfig   gcc  
m68k                                defconfig   gcc  
microblaze                       allmodconfig   gcc  
microblaze                        allnoconfig   gcc  
microblaze                       allyesconfig   gcc  
microblaze                          defconfig   gcc  
mips                              allnoconfig   gcc  
mips                             allyesconfig   gcc  
nios2                            allmodconfig   gcc  
nios2                             allnoconfig   gcc  
nios2                            allyesconfig   gcc  
nios2                               defconfig   gcc  
nios2                 randconfig-001-20240603   gcc  
nios2                 randconfig-002-20240603   gcc  
openrisc                          allnoconfig   gcc  
openrisc                         allyesconfig   gcc  
openrisc                            defconfig   gcc  
parisc                           allmodconfig   gcc  
parisc                            allnoconfig   gcc  
parisc                           allyesconfig   gcc  
parisc                              defconfig   gcc  
parisc                randconfig-001-20240603   gcc  
parisc                randconfig-002-20240603   gcc  
parisc64                            defconfig   gcc  
powerpc                          allmodconfig   gcc  
powerpc                           allnoconfig   gcc  
powerpc                          allyesconfig   clang
powerpc               randconfig-001-20240603   gcc  
powerpc               randconfig-002-20240603   gcc  
powerpc               randconfig-003-20240603   gcc  
powerpc64             randconfig-001-20240603   gcc  
powerpc64             randconfig-002-20240603   gcc  
powerpc64             randconfig-003-20240603   clang
riscv                            allmodconfig   clang
riscv                             allnoconfig   gcc  
riscv                            allyesconfig   clang
riscv                               defconfig   clang
riscv                 randconfig-001-20240603   clang
riscv                 randconfig-002-20240603   clang
s390                             allmodconfig   clang
s390                              allnoconfig   clang
s390                             allyesconfig   gcc  
s390                                defconfig   clang
s390                  randconfig-001-20240603   clang
s390                  randconfig-002-20240603   clang
sh                               allmodconfig   gcc  
sh                                allnoconfig   gcc  
sh                               allyesconfig   gcc  
sh                                  defconfig   gcc  
sh                    randconfig-001-20240603   gcc  
sh                    randconfig-002-20240603   gcc  
sparc                            allmodconfig   gcc  
sparc                             allnoconfig   gcc  
sparc                               defconfig   gcc  
sparc64                          allmodconfig   gcc  
sparc64                          allyesconfig   gcc  
sparc64                             defconfig   gcc  
sparc64               randconfig-001-20240603   gcc  
sparc64               randconfig-002-20240603   gcc  
um                               allmodconfig   clang
um                                allnoconfig   clang
um                               allyesconfig   gcc  
um                                  defconfig   clang
um                             i386_defconfig   gcc  
um                    randconfig-001-20240603   clang
um                    randconfig-002-20240603   gcc  
um                           x86_64_defconfig   clang
x86_64                            allnoconfig   clang
x86_64                           allyesconfig   clang
x86_64       buildonly-randconfig-001-20240603   gcc  
x86_64       buildonly-randconfig-002-20240603   gcc  
x86_64       buildonly-randconfig-003-20240603   gcc  
x86_64       buildonly-randconfig-004-20240603   clang
x86_64       buildonly-randconfig-005-20240603   clang
x86_64       buildonly-randconfig-006-20240603   gcc  
x86_64                              defconfig   gcc  
x86_64                randconfig-001-20240603   gcc  
x86_64                randconfig-002-20240603   clang
x86_64                randconfig-003-20240603   clang
x86_64                randconfig-004-20240603   gcc  
x86_64                randconfig-005-20240603   gcc  
x86_64                randconfig-006-20240603   gcc  
x86_64                randconfig-011-20240603   gcc  
x86_64                randconfig-012-20240603   gcc  
x86_64                randconfig-013-20240603   clang
x86_64                randconfig-014-20240603   gcc  
x86_64                randconfig-015-20240603   gcc  
x86_64                randconfig-016-20240603   clang
x86_64                randconfig-071-20240603   clang
x86_64                randconfig-072-20240603   clang
x86_64                randconfig-073-20240603   clang
x86_64                randconfig-074-20240603   clang
x86_64                randconfig-075-20240603   gcc  
x86_64                randconfig-076-20240603   gcc  
x86_64                          rhel-8.3-rust   clang
xtensa                            allnoconfig   gcc  
xtensa                randconfig-001-20240603   gcc  
xtensa                randconfig-002-20240603   gcc  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* Re: [PATCH v3 2/2] input: Add support for "Do Not Disturb"
From: Aseda Aboagye @ 2024-06-03 17:44 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: Jiri Kosina, Benjamin Tissoires, linux-input
In-Reply-To: <Zljhp-u-s-RPPXDj@google.com>


> >  #define KEY_ACCESSIBILITY              0x24e   /* Toggles the system bound accessibility UI/command (HUTRR116) */
> > +#define KEY_DO_NOT_DISTURB             0x24f   /* Toggles the system-wide "Do Not Disturb" control (HUTRR94)*/
> 
> Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> 
> Feel free to merge through HID tree.

Thank you for the review!

-- 
Aseda Aboagye

^ permalink raw reply

* Re: [PATCH v10 1/8] x86/vmware: Introduce VMware hypercall API
From: Borislav Petkov @ 2024-06-03 17:58 UTC (permalink / raw)
  To: Alexey Makhalov
  Cc: linux-kernel, virtualization, hpa, dave.hansen, mingo, tglx, x86,
	netdev, richardcochran, linux-input, dmitry.torokhov, zackr,
	linux-graphics-maintainer, pv-drivers, timothym, akaher,
	dri-devel, daniel, airlied, tzimmermann, mripard,
	maarten.lankhorst, horms, kirill.shutemov
In-Reply-To: <9ca6230c-740c-4f1a-8fdf-73f74cf025a1@broadcom.com>

On Wed, May 29, 2024 at 05:44:32PM -0700, Alexey Makhalov wrote:
> While most of the vmware_hypercall callers are executed after alternative
> patching applied, there are small amount of hypercalls running before that.
> Only for them we have the logic of analyzing vmware_hypercall_mode as a
> default alternative code. And there are 2 constraints:
> 1. vmcall/vmmcall are not supported by old ESXi/Workstation/Fusion. We have
> to use in/out instructions. After the end of support of old hypervisors the
> alternative can be simplified as follow:
> ALTERNATIVE("vmcall", "vmmcall", X86_FEATURE_VMW_VMMCALL);
> 2. SEV-ES enabled VMs should use _only_ vmcall/vmmcall as in/out
> instructions cause faults.
> 
> Another approach that we discussed internally was to use
> ALTERNATIVE_2("movw %[port], %%dx; "inl (%%dx), %%eax", "vmcall",
> X86_FEATURE_VMW_VMCALL, "vmmcall", X86_FEATURE_VMW_VMMCALL) for
> vmware_hypercallX family of functions, _and_ to have a separate API
> vmware_sev_hypercallX, with the silly dance without an alternative inside,
> to be used only by early boot code, before alternative application. But,
> it's error prone when things come to boot time related code movements or
> rearrangements as it puts additional requirement for SEV-ES
> understanding/testing for VMware guests.

Right, so since we're exporting that alternatives_patched thing already,
you might also try to do:

	if (unlikely(!alternatives_patched))
		return slow_hypercall_X_in_c();

	asm_inline volatile(VMWARE_HYPERCALL...

where that slow_hypercall_X_in_c()* set of APIs does the checks in C.

And the VMWARE_HYPERCALL thing is a lot simpler then.

All in all, you'll have a lot less unreadable asm to pay attention to
and those APIs should be all easy and readable.

But in the end of the day, your call.

Thanks for explaining the situation.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

^ permalink raw reply

* Re: [PATCH v13 3/3] Input: Add TouchNetix axiom i2c touchscreen driver
From: Dmitry Torokhov @ 2024-06-04  0:02 UTC (permalink / raw)
  To: Kamel Bouhara
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
	linux-input, linux-kernel, devicetree, Marco Felsch, Jeff LaBundy,
	catalin.popescu, mark.satterthwaite, Thomas Petazzoni,
	Gregory Clement, bsp-development.geo
In-Reply-To: <20240603153929.29218-4-kamel.bouhara@bootlin.com>

Hi Kamel,

On Mon, Jun 03, 2024 at 05:39:25PM +0200, Kamel Bouhara wrote:
> Add a new driver for the TouchNetix's axiom family of
> touchscreen controllers. This driver only supports i2c
> and can be later adapted for SPI and USB support.
> 
> Signed-off-by: Kamel Bouhara <kamel.bouhara@bootlin.com>
> ---
>  MAINTAINERS                                  |   2 +
>  drivers/input/touchscreen/Kconfig            |  14 +
>  drivers/input/touchscreen/Makefile           |   1 +
>  drivers/input/touchscreen/touchnetix_axiom.c | 657 +++++++++++++++++++
>  4 files changed, 674 insertions(+)
>  create mode 100644 drivers/input/touchscreen/touchnetix_axiom.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 225309db4110..a3ece12e32d7 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -22744,9 +22744,11 @@ F:	drivers/platform/x86/toshiba-wmi.c
>  
>  TOUCHNETIX AXIOM I2C TOUCHSCREEN DRIVER
>  M:	Kamel Bouhara <kamel.bouhara@bootlin.com>
> +M:	bsp-development.geo@leica-geosystems.com
>  L:	linux-input@vger.kernel.org
>  S:	Maintained
>  F:	Documentation/devicetree/bindings/input/touchscreen/touchnetix,ax54a.yaml
> +F:	drivers/input/touchscreen/touchnetix_axiom.c
>  
>  TPM DEVICE DRIVER
>  M:	Peter Huewe <peterhuewe@gmx.de>
> diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
> index c821fe3ee794..1ce8f1c25625 100644
> --- a/drivers/input/touchscreen/Kconfig
> +++ b/drivers/input/touchscreen/Kconfig
> @@ -834,6 +834,20 @@ config TOUCHSCREEN_MIGOR
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called migor_ts.
>  
> +config TOUCHSCREEN_TOUCHNETIX_AXIOM
> +	tristate "TouchNetix AXIOM based touchscreen controllers"
> +	depends on I2C
> +	select CRC16
> +	select REGMAP_I2C
> +	help
> +	  Say Y here if you have a axiom touchscreen connected to
> +	  your system.
> +
> +	  If unsure, say N.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called axiom.
> +
>  config TOUCHSCREEN_TOUCHRIGHT
>  	tristate "Touchright serial touchscreen"
>  	select SERIO
> diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
> index a81cb5aa21a5..6ce7b804adc7 100644
> --- a/drivers/input/touchscreen/Makefile
> +++ b/drivers/input/touchscreen/Makefile
> @@ -91,6 +91,7 @@ obj-$(CONFIG_TOUCHSCREEN_SUR40)		+= sur40.o
>  obj-$(CONFIG_TOUCHSCREEN_SURFACE3_SPI)	+= surface3_spi.o
>  obj-$(CONFIG_TOUCHSCREEN_TI_AM335X_TSC)	+= ti_am335x_tsc.o
>  obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213)	+= touchit213.o
> +obj-$(CONFIG_TOUCHSCREEN_TOUCHNETIX_AXIOM)	+= touchnetix_axiom.o
>  obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT)	+= touchright.o
>  obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN)	+= touchwin.o
>  obj-$(CONFIG_TOUCHSCREEN_TS4800)	+= ts4800-ts.o
> diff --git a/drivers/input/touchscreen/touchnetix_axiom.c b/drivers/input/touchscreen/touchnetix_axiom.c
> new file mode 100644
> index 000000000000..09550847392e
> --- /dev/null
> +++ b/drivers/input/touchscreen/touchnetix_axiom.c
> @@ -0,0 +1,657 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * TouchNetix axiom Touchscreen Driver
> + *
> + * Copyright (C) 2020-2023 TouchNetix Ltd.
> + *
> + * Author(s): Bart Prescott <bartp@baasheep.co.uk>
> + *            Pedro Torruella <pedro.torruella@touchnetix.com>
> + *            Mark Satterthwaite <mark.satterthwaite@touchnetix.com>
> + *            Hannah Rossiter <hannah.rossiter@touchnetix.com>
> + *            Kamel Bouhara <kamel.bouhara@bootlin.com>
> + *
> + */
> +#include <linux/bitfield.h>
> +#include <linux/crc16.h>
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/i2c.h>
> +#include <linux/input.h>
> +#include <linux/input/mt.h>
> +#include <linux/input/touchscreen.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/regmap.h>
> +
> +#include <asm/unaligned.h>
> +#define AXIOM_PROX_LEVEL		-128
> +#define AXIOM_DMA_OPS_DELAY_USEC	250
> +#define AXIOM_STARTUP_TIME_MS		110
> +/*
> + * Register group u31 has 2 pages for usage table entries.
> + */
> +#define AXIOM_U31_MAX_USAGES		0xff
> +#define AXIOM_U31_BYTES_PER_USAGE	6
> +#define AXIOM_U31_PAGE0_LENGTH		0x0C
> +#define AXIOM_U31_BOOTMODE_MASK		BIT(7)
> +#define AXIOM_U31_DEVID_MASK		GENMASK(14, 0)
> +
> +#define AXIOM_MAX_REPORT_LEN		0x7f
> +
> +#define AXIOM_CMD_HEADER_READ_MASK	BIT(15)
> +#define AXIOM_U41_MAX_TARGETS		10
> +
> +#define AXIOM_U46_AUX_CHANNELS		4
> +#define AXIOM_U46_AUX_MASK		GENMASK(11, 0)
> +
> +#define AXIOM_COMMS_MAX_USAGE_PAGES	3
> +#define AXIOM_COMMS_PAGE_SIZE		256
> +#define AXIOM_COMMS_REPORT_LEN_MASK	GENMASK(6, 0)
> +
> +#define AXIOM_REPORT_USAGE_ID		0x34
> +#define AXIOM_DEVINFO_USAGE_ID		0x31
> +#define AXIOM_USAGE_2HB_REPORT_ID	0x01
> +#define AXIOM_USAGE_2AUX_REPORT_ID	0x46
> +#define AXIOM_USAGE_2DCTS_REPORT_ID	0x41
> +
> +#define AXIOM_PAGE_OFFSET_MASK		GENMASK(6, 0)
> +
> +struct axiom_devinfo {
> +	__le16 device_id;
> +	u8 fw_minor;
> +	u8 fw_major;
> +	u8 fw_info_extra;
> +	u8 tcp_revision;
> +	u8 bootloader_fw_minor;
> +	u8 bootloader_fw_major;
> +	__le16 jedec_id;
> +	u8 num_usages;
> +} __packed;
> +
> +/*
> + * Describes parameters of a specific usage, essentially a single element of
> + * the "Usage Table"
> + */
> +struct axiom_usage_entry {
> +	u8 id;
> +	u8 is_report;

This is probably a 'bool'.

> +	u8 start_page;
> +	u8 num_pages;
> +};
> +
> +/*
> + * Represents state of a touch or target when detected prior to a touch (eg.
> + * hover or proximity events).
> + */
> +enum axiom_target_state {
> +	AXIOM_TARGET_STATE_NOT_PRESENT = 0,
> +	AXIOM_TARGET_STATE_PROX = 1,
> +	AXIOM_TARGET_STATE_HOVER = 2,
> +	AXIOM_TARGET_STATE_TOUCHING = 3,
> +};
> +
> +struct axiom_u41_target {
> +	enum axiom_target_state state;
> +	u16 x;
> +	u16 y;
> +	s8 z;
> +	bool insert;

What does "insert" mean here?

> +	bool touch;
> +};
> +
> +struct axiom_target_report {
> +	u8 index;
> +	u8 present;

bool?

> +	u16 x;
> +	u16 y;
> +	s8 z;
> +};
> +
> +struct axiom_cmd_header {
> +	__le16 target_address;
> +	__le16 length;
> +} __packed;

You do not need to declare this as packed, it is naturally aligned. You
can also make it a union with __le32 to ensure overall alignment.

> +
> +struct axiom_data {
> +	struct axiom_devinfo devinfo;
> +	struct device *dev;
> +	struct gpio_desc *reset_gpio;
> +	struct i2c_client *client;
> +	struct input_dev *input_dev;
> +	u32 max_report_len;
> +	u8 rx_buf[AXIOM_COMMS_MAX_USAGE_PAGES * AXIOM_COMMS_PAGE_SIZE];
> +	struct axiom_u41_target targets[AXIOM_U41_MAX_TARGETS];
> +	struct axiom_usage_entry usage_table[AXIOM_U31_MAX_USAGES];
> +	bool usage_table_populated;
> +	struct regmap *regmap;
> +	struct touchscreen_properties	prop;
> +};
> +
> +static const struct regmap_config axiom_i2c_regmap_config = {
> +	.reg_bits = 32,
> +	.reg_format_endian = REGMAP_ENDIAN_LITTLE,
> +	.val_bits = 8,
> +	.val_format_endian = REGMAP_ENDIAN_LITTLE,
> +};
> +
> +/*
> + * axiom devices are typically configured to report touches at a rate
> + * of 100Hz (10ms) for systems that require polling for reports.
> + * When reports are polled, it will be expected to occasionally
> + * observe the overflow bit being set in the reports.
> + * This indicates that reports are not being read fast enough.
> + */
> +#define POLL_INTERVAL_DEFAULT_MS 10
> +
> +/* Translate usage/page/offset triplet into physical address. */
> +static u16 axiom_usage_to_target_address(struct axiom_data *ts, u8 usage, u8 page,
> +					 char offset)
> +{
> +	/* At the moment the convention is that u31 is always at physical address 0x0 */
> +	if (!ts->usage_table_populated) {
> +		if (usage == AXIOM_DEVINFO_USAGE_ID)
> +			return ((page << 8) + offset);
> +		else
> +			return 0xffff;
> +	}
> +
> +	if (page >= ts->usage_table[usage].num_pages) {
> +		dev_err(ts->dev, "Invalid usage table! usage: u%02x, page: %02x, offset: %02x\n",
> +			usage, page, offset);
> +		return 0xffff;
> +	}
> +
> +	return ((ts->usage_table[usage].start_page + page) << 8) + offset;
> +}
> +
> +static int axiom_read(struct axiom_data *ts, u8 usage, u8 page, void *buf, u16 len)
> +{
> +	struct axiom_cmd_header cmd_header;
> +	u32 preamble;
> +	int ret;
> +
> +	cmd_header.target_address = cpu_to_le16(axiom_usage_to_target_address(ts, usage, page, 0));
> +	cmd_header.length = cpu_to_le16(len | AXIOM_CMD_HEADER_READ_MASK);
> +
> +	preamble = get_unaligned_le32(&cmd_header);
> +
> +	ret = regmap_write(ts->regmap, preamble, 0);
> +	if (ret) {
> +		dev_err(ts->dev, "failed to write preamble, error %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = regmap_raw_read(ts->regmap, 0, buf, len);
> +	if (ret) {
> +		dev_err(ts->dev, "failed to read target address %04x, error %d\n",
> +			cmd_header.target_address, ret);
> +		return ret;
> +	}
> +
> +	/* Wait device's DMA operations */
> +	usleep_range(AXIOM_DMA_OPS_DELAY_USEC, AXIOM_DMA_OPS_DELAY_USEC + 50);

What exactly are we waiting for after getting the data?

> +
> +	return 0;
> +}
> +
> +/*
> + * One of the main purposes for reading the usage table is to identify
> + * which usages reside at which target address.
> + * When performing subsequent reads or writes to AXIOM, the target address
> + * is used to specify which usage is being accessed.
> + * Consider the following discovery code which will build up the usage table.
> + */
> +static u32 axiom_populate_usage_table(struct axiom_data *ts)
> +{
> +	struct axiom_usage_entry *usage_table;
> +	u8 *rx_data = ts->rx_buf;
> +	u32 max_report_len = 0;
> +	u32 usage_id;
> +	int error;
> +
> +	usage_table = ts->usage_table;
> +
> +	/* Read the second page of usage u31 to get the usage table */
> +	error = axiom_read(ts, AXIOM_DEVINFO_USAGE_ID, 1, rx_data,
> +			   (AXIOM_U31_BYTES_PER_USAGE * ts->devinfo.num_usages));
> +
> +	if (error)
> +		return error;
> +
> +	for (usage_id = 0; usage_id < ts->devinfo.num_usages; usage_id++) {
> +		u16 offset = (usage_id * AXIOM_U31_BYTES_PER_USAGE);
> +		u8 id = rx_data[offset + 0];
> +		u8 start_page = rx_data[offset + 1];
> +		u8 num_pages = rx_data[offset + 2];
> +		u32 max_offset = ((rx_data[offset + 3] & AXIOM_PAGE_OFFSET_MASK) + 1) * 2;
> +
> +		usage_table[id].is_report = !num_pages;
> +
> +		/* Store the entry into the usage table */
> +		usage_table[id].id = id;
> +		usage_table[id].start_page = start_page;
> +		usage_table[id].num_pages = num_pages;
> +
> +		dev_dbg(ts->dev, "Usage u%02x Info: %*ph\n", id, AXIOM_U31_BYTES_PER_USAGE,
> +			&rx_data[offset]);
> +
> +		/* Identify the max report length the module will receive */
> +		if (usage_table[id].is_report && max_offset > max_report_len)
> +			max_report_len = max_offset;
> +	}
> +
> +	ts->usage_table_populated = true;
> +
> +	return max_report_len;
> +}
> +
> +static int axiom_discover(struct axiom_data *ts)
> +{
> +	int error;
> +
> +	/*
> +	 * Fetch the first page of usage u31 to get the
> +	 * device information and the number of usages
> +	 */
> +	error = axiom_read(ts, AXIOM_DEVINFO_USAGE_ID, 0, &ts->devinfo, AXIOM_U31_PAGE0_LENGTH);
> +	if (error)
> +		return error;
> +
> +	dev_dbg(ts->dev, "  Boot Mode      : %s\n",
> +		FIELD_GET(AXIOM_U31_BOOTMODE_MASK,
> +			  le16_to_cpu(ts->devinfo.device_id)) ? "BLP" : "TCP");
> +	dev_dbg(ts->dev, "  Device ID      : %04lx\n",
> +		FIELD_GET(AXIOM_U31_DEVID_MASK, le16_to_cpu(ts->devinfo.device_id)));
> +	dev_dbg(ts->dev, "  Firmware Rev   : %02x.%02x\n", ts->devinfo.fw_major,
> +		ts->devinfo.fw_minor);
> +	dev_dbg(ts->dev, "  Bootloader Rev : %02x.%02x\n", ts->devinfo.bootloader_fw_major,
> +		ts->devinfo.bootloader_fw_minor);
> +	dev_dbg(ts->dev, "  FW Extra Info  : %04x\n", ts->devinfo.fw_info_extra);
> +	dev_dbg(ts->dev, "  Silicon        : %04x\n", le16_to_cpu(ts->devinfo.jedec_id));
> +	dev_dbg(ts->dev, "  Number usages        : %04x\n", ts->devinfo.num_usages);
> +
> +	ts->max_report_len = axiom_populate_usage_table(ts);
> +	if (!ts->max_report_len || !ts->devinfo.num_usages ||
> +	    ts->max_report_len > AXIOM_MAX_REPORT_LEN) {
> +		dev_err(ts->dev, "Invalid report length or usages number");
> +		return -EINVAL;
> +	}
> +
> +	dev_dbg(ts->dev, "Max Report Length: %u\n", ts->max_report_len);
> +
> +	return 0;
> +}
> +
> +/*
> + * Support function to axiom_process_u41_report.
> + * Generates input-subsystem events for every target.
> + * After calling this function the caller shall issue
> + * a Sync to the input sub-system.
> + */
> +static bool axiom_process_u41_report_target(struct axiom_data *ts,
> +					    struct axiom_target_report *target)
> +{
> +	struct input_dev *input_dev = ts->input_dev;
> +	struct axiom_u41_target *target_prev_state;
> +	enum axiom_target_state current_state;
> +	int id;
> +
> +	/* Verify the target index */
> +	if (target->index >= AXIOM_U41_MAX_TARGETS) {
> +		dev_err(ts->dev, "Invalid target index! %u\n", target->index);
> +		return false;
> +	}
> +
> +	target_prev_state = &ts->targets[target->index];
> +
> +	current_state = AXIOM_TARGET_STATE_NOT_PRESENT;
> +
> +	if (target->present) {
> +		if (target->z >= 0)
> +			current_state = AXIOM_TARGET_STATE_TOUCHING;
> +		else if (target->z > AXIOM_PROX_LEVEL && target->z < 0)
> +			current_state = AXIOM_TARGET_STATE_HOVER;
> +		else if (target->z == AXIOM_PROX_LEVEL)
> +			current_state = AXIOM_TARGET_STATE_PROX;
> +	}
> +
> +	if (target_prev_state->state == current_state &&
> +	    target_prev_state->x == target->x &&
> +	    target_prev_state->y == target->y &&
> +	    target_prev_state->z == target->z)
> +		return false;

Why is this needed? Input/MT core already tries to suppress duplicate
events, I do not think we need to do it here.

> +
> +	id = target->index;
> +
> +	dev_dbg(ts->dev, "U41 Target T%u, present:%u, x:%u, y:%u, z:%d\n",
> +		target->index, target->present,
> +		target->x, target->y, target->z);
> +
> +	switch (current_state) {
> +	case AXIOM_TARGET_STATE_NOT_PRESENT:
> +	case AXIOM_TARGET_STATE_PROX:
> +		if (!target_prev_state->insert)
> +			break;
> +		target_prev_state->insert = false;
> +
> +		if (!id)
> +			input_report_key(input_dev, BTN_TOUCH, 0);
> +
> +		input_mt_report_slot_inactive(input_dev);
> +		/*
> +		 * make sure the previous coordinates are
> +		 * all off screen when the finger comes back
> +		 */
> +		target->x = 65535;
> +		target->y = 65535;
> +		target->z = AXIOM_PROX_LEVEL;
> +		break;
> +	case AXIOM_TARGET_STATE_HOVER:
> +	case AXIOM_TARGET_STATE_TOUCHING:
> +		target_prev_state->insert = true;
> +		input_report_abs(input_dev, ABS_MT_TRACKING_ID, id);
> +		input_report_abs(input_dev, ABS_MT_POSITION_X, target->x);
> +		input_report_abs(input_dev, ABS_MT_POSITION_Y, target->y);
> +
> +		if (current_state == AXIOM_TARGET_STATE_TOUCHING) {
> +			input_report_abs(input_dev, ABS_MT_DISTANCE, 0);
> +			input_report_abs(input_dev, ABS_DISTANCE, 0);
> +			input_report_abs(input_dev, ABS_MT_PRESSURE, target->z);
> +			input_report_abs(input_dev, ABS_PRESSURE, target->z);

You only need to emit ABS_MT_DISTANCE and ABS_MT_PRESSURE. The
single-touch variants should be generated by the input core as part of
sending out the frame.

> +		} else {
> +			input_report_abs(input_dev, ABS_MT_DISTANCE, -target->z);
> +			input_report_abs(input_dev, ABS_DISTANCE, -target->z);
> +			input_report_abs(input_dev, ABS_MT_PRESSURE, 0);
> +			input_report_abs(input_dev, ABS_PRESSURE, 0);
> +		}
> +
> +		if (!id)
> +			input_report_key(input_dev, BTN_TOUCH, (current_state ==
> +					 AXIOM_TARGET_STATE_TOUCHING));

Why do you emit BTN_TOUCH manually instead of replying on
input_mt_sync_frame() calling input_mt_pointer_emulation().

> +		break;
> +	default:
> +		break;
> +	}
> +
> +	target_prev_state->state = current_state;
> +	target_prev_state->x = target->x;
> +	target_prev_state->y = target->y;
> +	target_prev_state->z = target->z;
> +
> +	return true;
> +}
> +
> +/*
> + * U41 is the output report of the 2D CTS and contains the status of targets
> + * (including contacts and pre-contacts) along with their X,Y,Z values.
> + * When a target has been removed (no longer detected),
> + * the corresponding X,Y,Z values will be zeroed.
> + */
> +static bool axiom_process_u41_report(struct axiom_data *ts, u8 *rx_buf)
> +{
> +	struct axiom_target_report target;
> +	bool update_done = false;
> +	u16 target_status;
> +	int i;
> +
> +	target_status = get_unaligned_le16(rx_buf + 1);
> +
> +	for (i = 0; i < AXIOM_U41_MAX_TARGETS; i++) {
> +		u8 *target_step = &rx_buf[i * 4];
> +
> +		target.index = i;
> +		input_mt_slot(ts->input_dev, i);
> +		input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
> +		target.present = ((target_status & (1 << i)) != 0) ? 1 : 0;
> +		target.x = get_unaligned_le16(target_step + 3);
> +		target.y = get_unaligned_le16(target_step + 5);
> +		target.z = (s8)(rx_buf[i + 43]);
> +		touchscreen_report_pos(ts->input_dev, &ts->prop, target.x, target.y, true);

I find it confusing that you send out coordinates here, and the rest of
events in axiom_process_u41_report_target()... Can it all be done in one
place?

> +		update_done |= axiom_process_u41_report_target(ts, &target);
> +	}
> +
> +	return update_done;
> +}
> +
> +/*
> + * U46 report contains a low level measurement data generated by the capacitive
> + * displacement sensor (CDS) algorithms from the auxiliary channels.
> + * This information is useful when tuning multi-press to assess mechanical
> + * consistency in the unit's construction.
> + */
> +static void axiom_process_u46_report(struct axiom_data *ts, u8 *rx_buf)
> +{
> +	struct input_dev *input_dev = ts->input_dev;
> +	u32 event_value;
> +	u16 aux_value;
> +	int i;
> +
> +	for (i = 0; i < AXIOM_U46_AUX_CHANNELS; i++) {
> +		u8 *target_step = &rx_buf[i * 2];
> +
> +		input_mt_slot(input_dev, i);
> +		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, true);
> +		aux_value = get_unaligned_le16(target_step + 1) & AXIOM_U46_AUX_MASK;
> +		event_value = (i << 16) | (aux_value);
> +		input_event(input_dev, EV_MSC, MSC_RAW, event_value);

This does not really belong to the input subsystem. I recommend using
debugfs to provide this data. Some drivers also use v4l to provide a
"picture" of the heat map.

> +	}
> +}
> +
> +/*
> + * Validates the crc and demultiplexes the axiom reports to the appropriate
> + * report handler
> + */
> +static int axiom_handle_events(struct axiom_data *ts)
> +{
> +	struct input_dev *input_dev = ts->input_dev;
> +	u8 *report_data = ts->rx_buf;
> +	struct device *dev = ts->dev;
> +	u16 crc_report;
> +	u8 *crc_bytes;
> +	u16 crc_calc;
> +	int error;
> +	u8 len;
> +
> +	error = axiom_read(ts, AXIOM_REPORT_USAGE_ID, 0, report_data, ts->max_report_len);
> +	if (error)
> +		return error;
> +
> +	len = (report_data[0] & AXIOM_COMMS_REPORT_LEN_MASK) << 1;
> +	if (len <= 2) {
> +		dev_err(dev, "Zero length report discarded.\n");
> +		return -ENODATA;
> +	}
> +
> +	/* Validate the report CRC */
> +	crc_bytes = &report_data[len];
> +
> +	crc_report = get_unaligned_le16(crc_bytes - 2);
> +	/* Length is in 16 bit words and remove the size of the CRC16 itself */
> +	crc_calc = crc16(0, report_data, (len - 2));
> +
> +	if (crc_calc != crc_report) {
> +		dev_err(dev,
> +			"CRC mismatch! Expected: %#x, Calculated CRC: %#x.\n",
> +			crc_report, crc_calc);
> +		return -EINVAL;
> +	}
> +
> +	switch (report_data[1]) {
> +	case AXIOM_USAGE_2DCTS_REPORT_ID:
> +		if (axiom_process_u41_report(ts, &report_data[1])) {
> +			input_mt_sync_frame(input_dev);
> +			input_sync(input_dev);
> +		}
> +		break;
> +
> +	case AXIOM_USAGE_2AUX_REPORT_ID:
> +		/* This is an aux report (force) */
> +		axiom_process_u46_report(ts, &report_data[1]);
> +		input_mt_sync(input_dev);
> +		input_sync(input_dev);
> +		break;
> +
> +	case AXIOM_USAGE_2HB_REPORT_ID:
> +		/* This is a heartbeat report */
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static void axiom_i2c_poll(struct input_dev *input_dev)
> +{
> +	struct axiom_data *ts = input_get_drvdata(input_dev);
> +
> +	axiom_handle_events(ts);
> +}
> +
> +static irqreturn_t axiom_irq(int irq, void *dev_id)
> +{
> +	struct axiom_data *ts = dev_id;
> +
> +	axiom_handle_events(ts);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static void axiom_reset(struct gpio_desc *reset_gpio)
> +{
> +	gpiod_set_value_cansleep(reset_gpio, 1);
> +	usleep_range(1000, 2000);
> +	gpiod_set_value_cansleep(reset_gpio, 0);
> +	msleep(AXIOM_STARTUP_TIME_MS);
> +}
> +
> +static int axiom_i2c_probe(struct i2c_client *client)
> +{
> +	struct device *dev = &client->dev;
> +	struct input_dev *input_dev;
> +	struct axiom_data *ts;
> +	u32 poll_interval;
> +	int target;
> +	int error;
> +
> +	ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
> +	if (!ts)
> +		return -ENOMEM;
> +
> +	i2c_set_clientdata(client, ts);
> +	ts->client = client;
> +	ts->dev = dev;
> +
> +	ts->regmap = devm_regmap_init_i2c(client, &axiom_i2c_regmap_config);
> +	error = PTR_ERR_OR_ZERO(ts->regmap);
> +	if (error) {
> +		dev_err(dev, "Failed to initialize regmap: %d\n", error);
> +		return error;
> +	}
> +
> +	error = devm_regulator_get_enable(dev, "vddi");
> +	if (error)
> +		return dev_err_probe(&client->dev, error,
> +				     "Failed to enable VDDI regulator\n");
> +
> +	error = devm_regulator_get_enable(dev, "vdda");
> +	if (error)
> +		return dev_err_probe(&client->dev, error,
> +				     "Failed to enable VDDA regulator\n");
> +
> +	ts->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
> +	if (IS_ERR(ts->reset_gpio))
> +		return dev_err_probe(dev, PTR_ERR(ts->reset_gpio), "failed to get reset GPIO\n");
> +
> +	if (ts->reset_gpio)
> +		axiom_reset(ts->reset_gpio);
> +	else
> +		msleep(AXIOM_STARTUP_TIME_MS);

Should this be called unconditionally (and matching msleep() be removed
from axiom_i2c_probe)?

> +
> +	error = axiom_discover(ts);
> +	if (error)
> +		return dev_err_probe(dev, error, "Failed touchscreen discover\n");
> +
> +	input_dev = devm_input_allocate_device(ts->dev);
> +	if (!input_dev)
> +		return -ENOMEM;
> +
> +	input_dev->name = "TouchNetix axiom Touchscreen";
> +	input_dev->phys = "input/axiom_ts";
> +
> +	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);

The only tool you report is finger, who do you declare more?

> +	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);
> +
> +	touchscreen_parse_properties(input_dev, true, &ts->prop);
> +
> +	/* Registers the axiom device as a touchscreen instead of a mouse pointer */
> +	error = input_mt_init_slots(input_dev, AXIOM_U41_MAX_TARGETS, INPUT_MT_DIRECT);
> +	if (error)
> +		return error;
> +
> +	/* Enables the raw data for up to 4 force channels to be sent to the input subsystem */
> +	set_bit(EV_REL, input_dev->evbit);

The driver does not emit any relative events...

> +	set_bit(EV_MSC, input_dev->evbit);
> +	/* Declare that we support "RAW" Miscellaneous events */
> +	set_bit(MSC_RAW, input_dev->mscbit);
> +
> +	ts->input_dev = input_dev;
> +	input_set_drvdata(ts->input_dev, ts);
> +
> +	/* Ensure that all reports are initialised to not be present. */
> +	for (target = 0; target < AXIOM_U41_MAX_TARGETS; target++)
> +		ts->targets[target].state = AXIOM_TARGET_STATE_NOT_PRESENT;
> +
> +	error = devm_request_threaded_irq(dev, client->irq, NULL,
> +					  axiom_irq, IRQF_ONESHOT, dev_name(dev), ts);
> +	if (error) {
> +		dev_info(dev, "Request irq failed, falling back to polling mode");

I do not think you should fall back to polling mode if you fail to get
interrupt. If it was not specified (client->irq) then I can see that we
might want to fall back, but if the system configured for using
interrupt and you can not get it you should bail out.

> +
> +		error = input_setup_polling(input_dev, axiom_i2c_poll);
> +		if (error)
> +			return dev_err_probe(ts->dev, error, "Unable to set up polling mode\n");
> +
> +		if (!device_property_read_u32(ts->dev, "poll-interval", &poll_interval))
> +			input_set_poll_interval(input_dev, poll_interval);
> +		else
> +			input_set_poll_interval(input_dev, POLL_INTERVAL_DEFAULT_MS);
> +	}
> +
> +	return input_register_device(input_dev);

Please use

	error = input_register_device(..);
	if (error)
		return dev_err_probe(...);

	return 0;

Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH v2] HID: hid-goodix: Add Goodix HID-over-SPI driver
From: Dmitry Torokhov @ 2024-06-04  0:50 UTC (permalink / raw)
  To: Charles Wang; +Cc: jikos, bentiss, hbarnor, dianders, linux-input, linux-kernel
In-Reply-To: <20240527042945.57054-1-charles.goodix@gmail.com>

Hi Charles,

> This patch introduces a new driver to support the Goodix GT7986U
> touch controller. The data reported is packaged according to the
> HID protocol but uses SPI for communication to improve speed. This
> enables the device to transmit not only coordinate data but also
> corresponding raw data that can be accessed by user-space programs
> through the hidraw interface. The raw data can be utilized for
> functions like palm rejection, thereby improving the touch experience.
> 
> Key features:
> - Device connection confirmation and initialization
> - IRQ-based event reporting to the input subsystem
> - Support for HIDRAW operations (GET_REPORT and SET_REPORT)

Can you  please mention in the patch description that this device is not
compatible with Microsoft's HID-over-SPI protocol and therefore needs to
implement its own flavor.

> 
> Signed-off-by: Charles Wang <charles.goodix@gmail.com>
> ---
> Changes in v2:
> - Fixed build warnings reported by kernel test robot
> ---
>  drivers/hid/Kconfig      |   6 +
>  drivers/hid/Makefile     |   1 +
>  drivers/hid/hid-goodix.c | 652 +++++++++++++++++++++++++++++++++++++++

Do you have similar i2c parts that are not compatible with MS
HID-over-I2C, and if you do have them do you have plans to add support
for them to this driver? If not maybe call this hid-goodix-spi.c?
Or maybe create drivers/hid/spi-hid/hid-goodix.c to separate HID upper
layer drivers from the HID low layer/transport drivers?


>  3 files changed, 659 insertions(+)
>  create mode 100644 drivers/hid/hid-goodix.c
> 
> diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
> index 4c682c650..f57d8fb88 100644
> --- a/drivers/hid/Kconfig
> +++ b/drivers/hid/Kconfig
> @@ -404,6 +404,12 @@ config HID_VIVALDI_COMMON
>  	  option so that drivers can use common code to parse the HID
>  	  descriptors for vivaldi function row keymap.
>  
> +config HID_GOODIX
> +	tristate "Goodix GT7986U SPI HID touchscreen"
> +	depends on SPI_MASTER
> +	help
> +	  Support for Goodix GT7986U SPI HID touchscreen device.
> +
>  config HID_GOOGLE_HAMMER
>  	tristate "Google Hammer Keyboard"
>  	select HID_VIVALDI_COMMON
> diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
> index 082a728ea..4e799f7e5 100644
> --- a/drivers/hid/Makefile
> +++ b/drivers/hid/Makefile
> @@ -54,6 +54,7 @@ obj-$(CONFIG_HID_GEMBIRD)	+= hid-gembird.o
>  obj-$(CONFIG_HID_GFRM)		+= hid-gfrm.o
>  obj-$(CONFIG_HID_GLORIOUS)  += hid-glorious.o
>  obj-$(CONFIG_HID_VIVALDI_COMMON) += hid-vivaldi-common.o
> +obj-$(CONFIG_HID_GOODIX)	+= hid-goodix.o
>  obj-$(CONFIG_HID_GOOGLE_HAMMER)	+= hid-google-hammer.o
>  obj-$(CONFIG_HID_GOOGLE_STADIA_FF)	+= hid-google-stadiaff.o
>  obj-$(CONFIG_HID_VIVALDI)	+= hid-vivaldi.o
> diff --git a/drivers/hid/hid-goodix.c b/drivers/hid/hid-goodix.c
> new file mode 100644
> index 000000000..a67f7d9ef
> --- /dev/null
> +++ b/drivers/hid/hid-goodix.c
> @@ -0,0 +1,652 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Goodix GT7986U SPI Driver Code for HID.
> + *
> + * Copyright (C) 2024 Godix, Inc.
> + */
> +#include <asm/unaligned.h>
> +#include <linux/delay.h>
> +#include <linux/hid.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/sizes.h>
> +#include <linux/spi/spi.h>
> +
> +#define GOODIX_DEV_CONFIRM_ADDR		0x10000
> +#define GOODIX_HID_DESC_ADDR		0x1058C
> +#define GOODIX_HID_REPORT_DESC_ADDR	0x105AA
> +#define GOODIX_HID_SIGN_ADDR		0x10D32
> +#define GOODIX_HID_REPORT_ADDR		0x22C8C

I wonder if some if not all of these should come from DT/device
properties.

> +
> +#define GOODIX_HID_GET_REPORT_CMD	0x02
> +#define GOODIX_HID_SET_REPORT_CMD	0x03
> +
> +#define GOODIX_HID_MAX_INBUF_SIZE	128
> +#define GOODIX_HID_ACK_READY_FLAG	0x01
> +#define GOODIX_HID_REPORT_READY_FLAG	0x80
> +
> +#define GOODIX_DEV_CONFIRM_VAL		0xAA
> +
> +#define GOODIX_SPI_WRITE_FLAG		0xF0
> +#define GOODIX_SPI_READ_FLAG		0xF1
> +#define GOODIX_SPI_TRANS_PREFIX_LEN	1
> +#define GOODIX_REGISTER_WIDTH		4
> +#define GOODIX_SPI_READ_DUMMY_LEN	3
> +#define GOODIX_SPI_READ_PREFIX_LEN	(GOODIX_SPI_TRANS_PREFIX_LEN + \
> +					 GOODIX_REGISTER_WIDTH + \
> +					 GOODIX_SPI_READ_DUMMY_LEN)
> +#define GOODIX_SPI_WRITE_PREFIX_LEN	(GOODIX_SPI_TRANS_PREFIX_LEN + \
> +					 GOODIX_REGISTER_WIDTH)
> +
> +#define GOODIX_CHECKSUM_SIZE		sizeof(u16)
> +#define GOODIX_NORMAL_RESET_DELAY_MS	150
> +
> +struct goodix_hid_report_header {
> +	u8 flag;
> +	__le16 size;
> +} __packed;
> +#define GOODIX_HID_ACK_HEADER_SIZE	sizeof(struct goodix_hid_report_header)
> +
> +struct goodix_hid_report_package {
> +	__le16 size;
> +	u8 data[];
> +};
> +
> +#define GOODIX_HID_PKG_LEN_SIZE		sizeof(u16)
> +#define GOODIX_HID_COOR_DATA_LEN	82
> +#define GOODIX_HID_COOR_PKG_LEN		(GOODIX_HID_PKG_LEN_SIZE + \
> +					 GOODIX_HID_COOR_DATA_LEN)
> +
> +#define GOODIX_REPORT_DATA_ADDR		(GOODIX_HID_REPORT_ADDR + \
> +					 GOODIX_HID_ACK_HEADER_SIZE + \
> +					 GOODIX_HID_PKG_LEN_SIZE)
> +
> +struct goodix_hid_report_event {
> +	struct goodix_hid_report_header hdr;
> +	u8 data[GOODIX_HID_COOR_PKG_LEN];
> +} __packed;
> +
> +struct goodix_hid_desc {
> +	__le16 desc_length;
> +	__le16 bcd_version;
> +	__le16 report_desc_lenght;
> +	__le16 report_desc_register;
> +	__le16 input_register;
> +	__le16 max_input_length;
> +	__le16 output_register;
> +	__le16 max_output_length;
> +	__le16 cmd_register;
> +	__le16 data_register;
> +	__le16 vendor_id;
> +	__le16 product_id;
> +	__le16 version_id;
> +	__le32 reserved;
> +} __packed;
> +
> +struct goodix_ts_data {
> +	struct device *dev;
> +	struct spi_device *spi;
> +	struct hid_device *hid;
> +	struct goodix_hid_desc hid_desc;
> +
> +	struct gpio_desc *reset_gpio;
> +
> +	/* Buffer used to store hid report data */
> +	u8 xfer_buf[SZ_4K];

Maybe have it as ____cacheline_aligned to allow SPI controller to DMA to
it directly. 

> +};
> +
> +static int goodix_spi_read(struct goodix_ts_data *ts, u32 addr,
> +			   u8 *data, unsigned int len)
> +{
> +	struct spi_device *spi = to_spi_device(&ts->spi->dev);
> +	struct spi_transfer xfers;
> +	struct spi_message spi_msg;
> +	u8 *buf;
> +	int error;
> +
> +	buf = kzalloc(GOODIX_SPI_READ_PREFIX_LEN + len, GFP_KERNEL);
> +	if (!buf)
> +		return -ENOMEM;

Can you try using ts->xfer_buf without making allocations and copies?
Maybe have goodix_spi_read() have data as u8 **data, and do

	*data = buf + GOODIX_SPI_READ_PREFIX_LEN;
	return 0;

at the end. I.e. callers do not supply buffer but rather are given one.
Of course you need to make sure there are no concurrent calls to
goodix_spi_read(), but I do not think you have them anyways.


> +
> +	spi_message_init(&spi_msg);
> +	memset(&xfers, 0, sizeof(xfers));
> +
> +	/* buffer format: 0xF1 + addr(4bytes) + dummy(3bytes) + data */
> +	buf[0] = GOODIX_SPI_READ_FLAG;
> +	put_unaligned_be32(addr, buf + GOODIX_SPI_TRANS_PREFIX_LEN);
> +	memset(buf + GOODIX_SPI_TRANS_PREFIX_LEN + GOODIX_REGISTER_WIDTH,
> +	       0xff, GOODIX_SPI_READ_DUMMY_LEN);

Does the "data" have to be set to 0xff?

> +
> +	xfers.tx_buf = buf;
> +	xfers.rx_buf = buf;
> +	xfers.len = GOODIX_SPI_READ_PREFIX_LEN + len;
> +	xfers.cs_change = 0;
> +	spi_message_add_tail(&xfers, &spi_msg);
> +
> +	error = spi_sync(spi, &spi_msg);
> +	if (error)
> +		dev_err(ts->dev, "spi transfer error:%d", error);
> +	else
> +		memcpy(data, buf + GOODIX_SPI_READ_PREFIX_LEN, len);
> +
> +	kfree(buf);
> +	return error;
> +}
> +
> +static int goodix_spi_write(struct goodix_ts_data *ts, u32 addr,
> +			    u8 *data, unsigned int len)
> +{
> +	struct spi_device *spi = to_spi_device(&ts->spi->dev);
> +	struct spi_transfer xfers;
> +	struct spi_message spi_msg;
> +	u8 *buf;
> +	int error;
> +
> +	buf = kzalloc(GOODIX_SPI_WRITE_PREFIX_LEN + len, GFP_KERNEL);
> +	if (!buf)
> +		return -ENOMEM;

Same comments here as for goodix_spi_write()...

> +
> +	spi_message_init(&spi_msg);
> +	memset(&xfers, 0, sizeof(xfers));
> +
> +	/* buffer format: 0xF0 + addr(4bytes) + data */
> +	buf[0] = GOODIX_SPI_WRITE_FLAG;
> +	put_unaligned_be32(addr, buf + GOODIX_SPI_TRANS_PREFIX_LEN);
> +	memcpy(buf + GOODIX_SPI_WRITE_PREFIX_LEN, data, len);
> +
> +	xfers.tx_buf = buf;
> +	xfers.len = GOODIX_SPI_WRITE_PREFIX_LEN + len;
> +	xfers.cs_change = 0;
> +	spi_message_add_tail(&xfers, &spi_msg);
> +
> +	error = spi_sync(spi, &spi_msg);
> +	if (error)
> +		dev_err(ts->dev, "spi transfer error:%d", error);
> +
> +	kfree(buf);
> +	return error;
> +}
> +
> +static int goodix_dev_confirm(struct goodix_ts_data *ts)
> +{
> +	u8 tx_buf[8], rx_buf[8];
> +	int retry = 3;
> +	int error;
> +
> +	gpiod_set_value_cansleep(ts->reset_gpio, 0);
> +	usleep_range(4000, 4100);
> +
> +	memset(tx_buf, GOODIX_DEV_CONFIRM_VAL, sizeof(tx_buf));
> +	while (retry--) {
> +		error = goodix_spi_write(ts, GOODIX_DEV_CONFIRM_ADDR,
> +					 tx_buf, sizeof(tx_buf));
> +		if (error)
> +			return error;
> +
> +		error = goodix_spi_read(ts, GOODIX_DEV_CONFIRM_ADDR,
> +					rx_buf, sizeof(rx_buf));
> +		if (error)
> +			return error;
> +
> +		if (!memcmp(tx_buf, rx_buf, sizeof(tx_buf)))
> +			return 0;
> +
> +		usleep_range(5000, 5100);
> +	}
> +
> +	dev_err(ts->dev, "device confirm failed, rx_buf:%*ph", 8, rx_buf);
> +	return -EINVAL;
> +}
> +
> +/**
> + * goodix_hid_parse() - hid-core .parse() callback
> + * @hid: hid device instance
> + *
> + * This function gets called during call to hid_add_device
> + *
> + * Return: 0 on success and non zero on error
> + */
> +static int goodix_hid_parse(struct hid_device *hid)
> +{
> +	struct goodix_ts_data *ts = hid->driver_data;
> +	u16 rsize;
> +	u8 *rdesc;
> +	int error;
> +
> +	rsize = le16_to_cpu(ts->hid_desc.report_desc_lenght);
> +	if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
> +		dev_err(ts->dev, "invalid report desc size %d", rsize);
> +		return -EINVAL;
> +	}
> +
> +	rdesc = kzalloc(rsize, GFP_KERNEL);

We now have nifty

	u8 *rdesc __free(kfree) = kzalloc(rsize, GFP_KERNEL);

(see include/linux/cleanup.h) and you do not need to free memory by
hand.

> +	if (!rdesc)
> +		return -ENOMEM;
> +
> +	error = goodix_spi_read(ts, GOODIX_HID_REPORT_DESC_ADDR, rdesc, rsize);
> +	if (error) {
> +		dev_err(ts->dev, "failed get report desc, %d", error);
> +		goto free_mem;
> +	}
> +
> +	error = hid_parse_report(hid, rdesc, rsize);
> +	if (error)
> +		dev_err(ts->dev, "failed parse report, %d", error);
> +
> +free_mem:
> +	kfree(rdesc);
> +	return error;
> +}
> +
> +/* Empty callbacks with success return code */

Hmm, I see you are using falling edge interrupt. Don't you have concern
of having it "stuck" here? I do not think all these should be stubs...

Does the device have low power mode that can be used when controller is
not in use (inhibited for example)?

> +static int goodix_hid_start(struct hid_device *hid)
> +{
> +	return 0;
> +}
> +
> +static void goodix_hid_stop(struct hid_device *hid)
> +{
> +}
> +
> +static int goodix_hid_open(struct hid_device *hid)
> +{
> +	return 0;
> +}
> +
> +static void goodix_hid_close(struct hid_device *hid)
> +{
> +}
> +
> +/* Return date length of response data */
> +static int goodix_hid_check_ack_status(struct goodix_ts_data *ts)
> +{
> +	struct goodix_hid_report_header hdr;
> +	int retry = 20;
> +	int error;
> +
> +	while (retry--) {
> +		/*
> +		 * 3 bytes of hid request response data
> +		 * - byte 0:    Ack flag, value of 1 for data ready
> +		 * - bytes 1-2: Response data length
> +		 */
> +		error = goodix_spi_read(ts, GOODIX_HID_REPORT_ADDR,
> +					(u8 *)&hdr, sizeof(hdr));
> +		if (!error && (hdr.flag & GOODIX_HID_ACK_READY_FLAG))
> +			return le16_to_cpu(hdr.size);
> +
> +		/* Wait 10ms for another try */
> +		usleep_range(10000, 11000);
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +/**
> + * goodix_hid_get_raw_report() - Process hidraw GET REPORT operation
> + * @hid: hid device instance
> + * @reportnum: Report ID
> + * @buf: Buffer for store the reprot date
> + * @len: Length fo reprot data
> + * @report_type: Report type
> + *
> + * The function for hid_ll_driver.get_raw_report to handle the HIDRAW ioctl
> + * get report request. The transmitted data follows the standard i2c-hid
> + * protocol with a specified header.
> + *
> + * Return: The length of the data in the buf on success, negative error code
> + */
> +static int goodix_hid_get_raw_report(struct hid_device *hid,
> +				     unsigned char reportnum,
> +				     __u8 *buf, size_t len,
> +				     unsigned char report_type)
> +{
> +	struct goodix_ts_data *ts = hid->driver_data;
> +	u16 data_register = le16_to_cpu(ts->hid_desc.data_register);
> +	u16 cmd_register = le16_to_cpu(ts->hid_desc.cmd_register);
> +	u8 tmp_buf[GOODIX_HID_MAX_INBUF_SIZE];
> +	int tx_len = 0, args_len = 0;
> +	int response_data_len;
> +	u8 args[3];
> +	int error;
> +
> +	if (report_type == HID_OUTPUT_REPORT)
> +		return -EINVAL;
> +
> +	if (reportnum == 3) {
> +		/* Get win8 signature data */
> +		error = goodix_spi_read(ts, GOODIX_HID_SIGN_ADDR, buf, len);
> +		if (error) {
> +			dev_err(ts->dev, "failed get win8 sign:%d", error);
> +			return -EINVAL;
> +		}
> +		return len;
> +	}
> +
> +	if (reportnum >= 0x0F) {
> +		args[args_len++] = reportnum;
> +		reportnum = 0x0F;
> +	}
> +	put_unaligned_le16(data_register, args + args_len);
> +	args_len += sizeof(data_register);
> +
> +	/* Clean 3 bytes of hid ack header data */
> +	memset(tmp_buf, 0, GOODIX_HID_ACK_HEADER_SIZE);
> +	tx_len += GOODIX_HID_ACK_HEADER_SIZE;
> +
> +	put_unaligned_le16(cmd_register, tmp_buf + tx_len);
> +	tx_len += sizeof(cmd_register);
> +
> +	tmp_buf[tx_len++] = ((report_type == HID_FEATURE_REPORT ? 0x03 : 0x01) << 4) | reportnum;
> +	tmp_buf[tx_len++] = GOODIX_HID_GET_REPORT_CMD;
> +
> +	memcpy(tmp_buf + tx_len, args, args_len);
> +	tx_len += args_len;
> +
> +	/* Step1: write report request info */
> +	error = goodix_spi_write(ts, GOODIX_HID_REPORT_ADDR, tmp_buf, tx_len);
> +	if (error) {
> +		dev_err(ts->dev, "failed send read feature cmd, %d", error);
> +		return error;
> +	}
> +
> +	/* No need read response data */
> +	if (!len)
> +		return 0;
> +
> +	/* Step2: check response data status */
> +	response_data_len = goodix_hid_check_ack_status(ts);
> +	if (response_data_len <= 0)
> +		return -EINVAL;
> +
> +	/* Step3: read response data(skip 2bytes of hid pkg length) */
> +	error = goodix_spi_read(ts, GOODIX_REPORT_DATA_ADDR, buf,
> +				response_data_len - GOODIX_HID_PKG_LEN_SIZE);
> +	if (error) {
> +		dev_err(ts->dev, "failed read hid response data, %d", error);
> +		return error;
> +	}
> +
> +	return response_data_len - GOODIX_HID_PKG_LEN_SIZE;
> +}
> +
> +/**
> + * goodix_hid_set_raw_report() - process hidraw SET REPORT operation
> + * @hid: HID device
> + * @reportnum: Report ID
> + * @buf: Buffer for communication
> + * @len: Length of data in the buffer
> + * @report_type: Report type
> + *
> + * The function for hid_ll_driver.get_raw_report to handle the HIDRAW ioctl
> + * set report request. The transmitted data follows the standard i2c-hid
> + * protocol with a specified header.
> + *
> + * Return: The length of the data sent, negative error code on failure
> + */
> +static int goodix_hid_set_raw_report(struct hid_device *hid,
> +				     unsigned char reportnum,
> +				     __u8 *buf, size_t len,
> +				     unsigned char report_type)
> +{
> +	struct goodix_ts_data *ts = hid->driver_data;
> +	u16 data_register = le16_to_cpu(ts->hid_desc.data_register);
> +	u16 cmd_register = le16_to_cpu(ts->hid_desc.cmd_register);
> +	int tx_len = 0, args_len = 0;
> +	u8 tmp_buf[GOODIX_HID_MAX_INBUF_SIZE];
> +	u8 args[5];
> +	int error;
> +
> +	if (reportnum >= 0x0F) {
> +		args[args_len++] = reportnum;
> +		reportnum = 0x0F;
> +	}
> +
> +	put_unaligned_le16(data_register, args + args_len);
> +	args_len += sizeof(data_register);
> +
> +	put_unaligned_le16(GOODIX_HID_PKG_LEN_SIZE + len, args + args_len);
> +	args_len += GOODIX_HID_PKG_LEN_SIZE;
> +
> +	/* Clean 3 bytes of hid ack header data */
> +	memset(tmp_buf, 0, GOODIX_HID_ACK_HEADER_SIZE);
> +	tx_len += GOODIX_HID_ACK_HEADER_SIZE;
> +
> +	put_unaligned_le16(cmd_register, tmp_buf + tx_len);
> +	tx_len += sizeof(cmd_register);
> +
> +	tmp_buf[tx_len++] = ((report_type == HID_FEATURE_REPORT ? 0x03 : 0x02) << 4) | reportnum;
> +	tmp_buf[tx_len++] = GOODIX_HID_SET_REPORT_CMD;
> +
> +	memcpy(tmp_buf + tx_len, args, args_len);
> +	tx_len += args_len;
> +
> +	memcpy(tmp_buf + tx_len, buf, len);
> +	tx_len += len;
> +
> +	error = goodix_spi_write(ts, GOODIX_HID_REPORT_ADDR, tmp_buf, tx_len);
> +	if (error) {
> +		dev_err(ts->dev, "failed send report %*ph", tx_len, tmp_buf);
> +		return error;
> +	}
> +	return len;
> +}
> +
> +static int goodix_hid_raw_request(struct hid_device *hid,
> +				  unsigned char reportnum,
> +				  __u8 *buf, size_t len,
> +				  unsigned char rtype, int reqtype)
> +{
> +	switch (reqtype) {
> +	case HID_REQ_GET_REPORT:
> +		return goodix_hid_get_raw_report(hid, reportnum, buf,
> +						 len, rtype);
> +	case HID_REQ_SET_REPORT:
> +		if (buf[0] != reportnum)
> +			return -EINVAL;
> +		return goodix_hid_set_raw_report(hid, reportnum, buf,
> +						 len, rtype);
> +	default:
> +		return -EIO;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static struct hid_ll_driver goodix_hid_ll_driver = {
> +	.parse = goodix_hid_parse,
> +	.start = goodix_hid_start,
> +	.stop = goodix_hid_stop,
> +	.open = goodix_hid_open,
> +	.close = goodix_hid_close,
> +	.raw_request = goodix_hid_raw_request
> +};
> +
> +static irqreturn_t goodix_hid_irq(int irq, void *data)
> +{
> +	struct goodix_ts_data *ts = data;
> +	struct goodix_hid_report_event event;
> +	struct goodix_hid_report_package *pkg;
> +	u16 report_size;
> +	int error;
> +
> +	/*
> +	 * First, read buffer with space for header and coordinate package:
> +	 * - event header = 3 bytes
> +	 * - coordinate event = GOODIX_HID_COOR_PKG_LEN bytes
> +	 *
> +	 * If the data size info in the event header exceeds
> +	 * GOODIX_HID_COOR_PKG_LEN, it means that there are other packages
> +	 * besides the coordinate package.
> +	 */
> +	error = goodix_spi_read(ts, GOODIX_HID_REPORT_ADDR, (u8 *)&event,
> +				sizeof(event));
> +	if (error) {
> +		dev_err(ts->dev, "failed get coordinate data, %d", error);
> +		return IRQ_HANDLED;
> +	}
> +
> +	/* Check coordinate data valid falg */
> +	if (event.hdr.flag != GOODIX_HID_REPORT_READY_FLAG) {
> +		dev_err(ts->dev, "invalid event flag 0x%x", event.hdr.flag);
> +		return IRQ_HANDLED;
> +	}
> +
> +	pkg = (struct goodix_hid_report_package *)event.data;
> +	hid_input_report(ts->hid, HID_INPUT_REPORT, pkg->data,
> +			 le16_to_cpu(pkg->size) - GOODIX_HID_PKG_LEN_SIZE, 1);
> +
> +	report_size = le16_to_cpu(event.hdr.size);
> +	/* Check if there are other packages */
> +	if (report_size <= GOODIX_HID_COOR_PKG_LEN)
> +		return IRQ_HANDLED;
> +
> +	if (report_size - GOODIX_HID_COOR_PKG_LEN > sizeof(ts->xfer_buf)) {
> +		dev_err(ts->dev, "invalid package size, %d", report_size);
> +		return IRQ_HANDLED;
> +	}
> +
> +	/* Read the package behind the coordinate data */
> +	error = goodix_spi_read(ts, GOODIX_HID_REPORT_ADDR + sizeof(event),
> +				ts->xfer_buf,
> +				report_size - GOODIX_HID_COOR_PKG_LEN);
> +	if (error) {
> +		dev_err(ts->dev, "failed read data, %d", error);
> +		return IRQ_HANDLED;
> +	}
> +
> +	pkg = (struct goodix_hid_report_package *)ts->xfer_buf;
> +	hid_input_report(ts->hid, HID_INPUT_REPORT, pkg->data,
> +			 le16_to_cpu(pkg->size) - GOODIX_HID_PKG_LEN_SIZE, 1);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int goodix_hid_init(struct goodix_ts_data *ts)
> +{
> +	struct hid_device *hid;
> +	int error;
> +
> +	/* Get hid descriptor */
> +	error = goodix_spi_read(ts, GOODIX_HID_DESC_ADDR, (u8 *)&ts->hid_desc,
> +				sizeof(ts->hid_desc));
> +	if (error) {
> +		dev_err(ts->dev, "failed get hid desc, %d", error);
> +		return error;
> +	}
> +
> +	hid = hid_allocate_device();
> +	if (IS_ERR(hid))
> +		return PTR_ERR(hid);
> +
> +	hid->driver_data = ts;
> +	hid->ll_driver = &goodix_hid_ll_driver;
> +	hid->bus = BUS_SPI;
> +	hid->dev.parent = &ts->spi->dev;
> +
> +	hid->version = le16_to_cpu(ts->hid_desc.bcd_version);
> +	hid->vendor = le16_to_cpu(ts->hid_desc.vendor_id);
> +	hid->product = le16_to_cpu(ts->hid_desc.product_id);
> +	snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", "hid-gdix",
> +		 hid->vendor, hid->product);
> +
> +	error = hid_add_device(hid);
> +	if (error) {
> +		dev_err(ts->dev, "failed add hid device, %d", error);
> +		hid_destroy_device(hid);
> +		return error;
> +	}
> +
> +	ts->hid = hid;
> +	return 0;
> +}
> +
> +static int goodix_spi_probe(struct spi_device *spi)
> +{
> +	struct device *dev = &spi->dev;
> +	struct goodix_ts_data *ts;
> +	int error;
> +
> +	/* init spi_device */
> +	spi->mode            = SPI_MODE_0;
> +	spi->bits_per_word   = 8;
> +	error = spi_setup(spi);
> +	if (error)
> +		return error;
> +
> +	ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
> +	if (!ts)
> +		return -ENOMEM;
> +
> +	spi_set_drvdata(spi, ts);
> +	ts->spi = spi;
> +	ts->dev = dev;
> +	ts->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
> +	if (IS_ERR(ts->reset_gpio))
> +		return dev_err_probe(dev, PTR_ERR(ts->reset_gpio),
> +				     "Failed to request reset gpio\n");
> +
> +	error = goodix_dev_confirm(ts);
> +	if (error)
> +		return error;
> +
> +	/* Waits 150ms for firmware to fully boot */
> +	msleep(GOODIX_NORMAL_RESET_DELAY_MS);
> +
> +	error = devm_request_threaded_irq(&ts->spi->dev, ts->spi->irq,
> +					  NULL, goodix_hid_irq,
> +					  IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
> +					  "goodix_spi_hid", ts);
> +	if (error < 0) {
> +		dev_err(ts->dev, "could not register interrupt, irq = %d, %d",
> +			ts->spi->irq, error);
> +		return error;
> +	}

I do not think it is safe. Your interrupt is hot here, but you are
allocating and registering HID device instance in goodix_hid_init(). If
interrupt arrives right away you will likely crash.

> +
> +	error = goodix_hid_init(ts);
> +	if (error) {
> +		dev_err(dev, "failed init hid device");
> +		return error;
> +	}
> +
> +	return 0;
> +}
> +
> +static void goodix_spi_remove(struct spi_device *spi)
> +{
> +	struct goodix_ts_data *ts = spi_get_drvdata(spi);
> +
> +	hid_destroy_device(ts->hid);

This is not safe either, you destroy the device, but interrupts are
enabled and nothing stops them from coming...

> +}
> +
> +static void goodix_spi_shutdown(struct spi_device *spi)
> +{
> +	struct goodix_ts_data *ts = spi_get_drvdata(spi);
> +
> +	disable_irq_nosync(spi->irq);

Why nosync? Seems dangerous. Please add a comment why nosync is needed
and why it is safe.

> +	hid_destroy_device(ts->hid);
> +}
> +
> +#ifdef CONFIG_ACPI
> +static const struct acpi_device_id goodix_spi_acpi_match[] = {
> +	{ "GXTS7986" },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(acpi, goodix_spi_acpi_match);
> +#endif
> +
> +static struct spi_driver goodix_spi_driver = {
> +	.driver = {
> +		.name = "goodix-spi-hid",
> +		.acpi_match_table = ACPI_PTR(goodix_spi_acpi_match),
> +	},
> +	.probe =	goodix_spi_probe,
> +	.remove =	goodix_spi_remove,
> +	.shutdown =	goodix_spi_shutdown,
> +};
> +module_spi_driver(goodix_spi_driver);
> +
> +MODULE_DESCRIPTION("Goodix SPI driver for HID touchscreen");
> +MODULE_AUTHOR("Goodix, Inc.");
> +MODULE_LICENSE("GPL");
> -- 
> 2.43.0
> 
> 

Thanks.

-- 
Dmitry

^ permalink raw reply

* [PATCH 2/2] ARM: dts: cros-ec-keyboard: Add keyboard matrix v3.0
From: Daisuke Nojiri @ 2024-06-04  0:55 UTC (permalink / raw)
  Cc: Daisuke Nojiri, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Benson Leung, Guenter Roeck, Tzung-Bi Shih, Dmitry Torokhov,
	devicetree, chrome-platform, linux-kernel, linux-input

This CL adds support for keyboard matrix version 3.0. To enable it,
define CONFIG_CROS_KBD_V30.

BUG=b:331761304
TEST=cros build-packages --board corsola sys-kernel/chromeos-kernel-5_15

Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
---
 arch/arm/boot/dts/cros-ec-keyboard.dtsi      |  16 ++-
 drivers/platform/chrome/Kconfig              |   6 ++
 include/dt-bindings/input/cros-ec-keyboard.h | 104 +++++++++++++++++++
 3 files changed, 123 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/cros-ec-keyboard.dtsi b/arch/arm/boot/dts/cros-ec-keyboard.dtsi
index 55c4744fa7e7..0499e254596a 100644
--- a/arch/arm/boot/dts/cros-ec-keyboard.dtsi
+++ b/arch/arm/boot/dts/cros-ec-keyboard.dtsi
@@ -8,16 +8,26 @@
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/input/cros-ec-keyboard.h>
 
+#ifdef CONFIG_CROS_KBD_V30
+#define CROS_EC_KEYBOARD_COLUMN_SIZE 18
+#define CROS_TOP_ROW_KEYMAP CROS_TOP_ROW_KEYMAP_V30
+#define CROS_MAIN_KEYMAP CROS_MAIN_KEYMAP_V30
+#else
+#define CROS_EC_KEYBOARD_COLUMN_SIZE 13
+#define CROS_TOP_ROW_KEYMAP CROS_STD_TOP_ROW_KEYMAP
+#define CROS_MAIN_KEYMAP CROS_STD_MAIN_KEYMAP
+#endif
+
 &cros_ec {
 	keyboard_controller: keyboard-controller {
 		compatible = "google,cros-ec-keyb";
 		keypad,num-rows = <8>;
-		keypad,num-columns = <13>;
+		keypad,num-columns = <CROS_EC_KEYBOARD_COLUMN_SIZE>;
 		google,needs-ghost-filter;
 
 		linux,keymap = <
-			CROS_STD_TOP_ROW_KEYMAP
-			CROS_STD_MAIN_KEYMAP
+			CROS_TOP_ROW_KEYMAP
+			CROS_MAIN_KEYMAP
 		>;
 	};
 };
diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig
index d48f7f43f9e5..8f66beaa48ec 100644
--- a/drivers/platform/chrome/Kconfig
+++ b/drivers/platform/chrome/Kconfig
@@ -157,6 +157,12 @@ config CROS_KBD_LED_BACKLIGHT
 	  To compile this driver as a module, choose M here: the
 	  module will be called cros_kbd_led_backlight.
 
+config CROS_KBD_V30
+	bool "ChromeOS built-in keyboard version 3.0"
+	default n
+	help
+	  If you say Y here, you get support for built-in keyboard ver 3.0.
+
 config CROS_EC_CHARDEV
 	tristate "ChromeOS EC miscdevice"
 	depends on MFD_CROS_EC_DEV
diff --git a/include/dt-bindings/input/cros-ec-keyboard.h b/include/dt-bindings/input/cros-ec-keyboard.h
index f0ae03634a96..afc12f6aa642 100644
--- a/include/dt-bindings/input/cros-ec-keyboard.h
+++ b/include/dt-bindings/input/cros-ec-keyboard.h
@@ -100,4 +100,108 @@
 	MATRIX_KEY(0x07, 0x0b, KEY_UP)		\
 	MATRIX_KEY(0x07, 0x0c, KEY_LEFT)
 
+/* No numpad */
+#define CROS_TOP_ROW_KEYMAP_V30 \
+	MATRIX_KEY(0x00, 0x01, KEY_F11)		/* T11 */	\
+	MATRIX_KEY(0x00, 0x02, KEY_F1)		/* T1 */	\
+	MATRIX_KEY(0x00, 0x04, KEY_F10)		/* T10 */	\
+	MATRIX_KEY(0x00, 0x0b, KEY_F14)		/* T14 */	\
+	MATRIX_KEY(0x00, 0x0c, KEY_F15)		/* T15 */	\
+	MATRIX_KEY(0x01, 0x02, KEY_F4)		/* T4 */	\
+	MATRIX_KEY(0x01, 0x04, KEY_F7)		/* T7 */	\
+	MATRIX_KEY(0x01, 0x05, KEY_F12)		/* T12 */	\
+	MATRIX_KEY(0x01, 0x09, KEY_F9)		/* T9 */	\
+	MATRIX_KEY(0x02, 0x02, KEY_F3)		/* T3 */	\
+	MATRIX_KEY(0x02, 0x04, KEY_F6)		/* T6 */	\
+	MATRIX_KEY(0x02, 0x0b, KEY_F8)		/* T8 */	\
+	MATRIX_KEY(0x03, 0x02, KEY_F2)		/* T2 */	\
+	MATRIX_KEY(0x03, 0x05, KEY_F13)		/* T13 */	\
+	MATRIX_KEY(0x04, 0x04, KEY_F5)		/* T5 */
+
+#define CROS_MAIN_KEYMAP_V30			/* Keycode */	\
+	MATRIX_KEY(0x00, 0x03, KEY_B)		/* 50 */	\
+	MATRIX_KEY(0x00, 0x05, KEY_N)		/* 51 */	\
+	MATRIX_KEY(0x00, 0x06, KEY_RO)		/* 56 (JIS) */	\
+	MATRIX_KEY(0x00, 0x08, KEY_EQUAL)	/* 13 */	\
+	MATRIX_KEY(0x00, 0x09, KEY_HOME)	/* 80 (Numpad) */	\
+	MATRIX_KEY(0x00, 0x0a, KEY_RIGHTALT)	/* 62 */	\
+	MATRIX_KEY(0x00, 0x10, KEY_FN)		/* 127 */	\
+								\
+	MATRIX_KEY(0x01, 0x01, KEY_ESC)		/* 110 */	\
+	MATRIX_KEY(0x01, 0x03, KEY_G)		/* 35 */	\
+	MATRIX_KEY(0x01, 0x06, KEY_H)		/* 36 */	\
+	MATRIX_KEY(0x01, 0x08, KEY_APOSTROPHE)	/* 41 */	\
+	MATRIX_KEY(0x01, 0x0b, KEY_BACKSPACE)	/* 15 */	\
+	MATRIX_KEY(0x01, 0x0c, KEY_HENKAN)	/* 65 (JIS) */	\
+	MATRIX_KEY(0x01, 0x0e, KEY_LEFTCTRL)	/* 58 */	\
+								\
+	MATRIX_KEY(0x02, 0x01, KEY_TAB)		/* 16 */	\
+	MATRIX_KEY(0x02, 0x03, KEY_T)		/* 21 */	\
+	MATRIX_KEY(0x02, 0x05, KEY_RIGHTBRACE)	/* 28 */	\
+	MATRIX_KEY(0x02, 0x06, KEY_Y)		/* 22 */	\
+	MATRIX_KEY(0x02, 0x08, KEY_LEFTBRACE)	/* 27 */	\
+	MATRIX_KEY(0x02, 0x09, KEY_DELETE)	/* 76 (Numpad) */	\
+	MATRIX_KEY(0x02, 0x0c, KEY_PAGEUP)	/* 85 (Numpad) */	\
+	MATRIX_KEY(0x02, 0x011, KEY_YEN)	/* 14 (JIS) */	\
+								\
+	MATRIX_KEY(0x03, 0x00, KEY_LEFTMETA)	/* Launcher */	\
+	MATRIX_KEY(0x03, 0x01, KEY_GRAVE)	/* 1 */	\
+	MATRIX_KEY(0x03, 0x03, KEY_5)		/* 6 */	\
+	MATRIX_KEY(0x03, 0x04, KEY_S)		/* 32 */	\
+	MATRIX_KEY(0x03, 0x06, KEY_MINUS)	/* 12 */	\
+	MATRIX_KEY(0x03, 0x08, KEY_6)		/* 7 */		\
+	MATRIX_KEY(0x03, 0x09, KEY_SLEEP)	/* Lock */	\
+	MATRIX_KEY(0x03, 0x0b, KEY_BACKSLASH)	/* 29 */	\
+	MATRIX_KEY(0x03, 0x0c, KEY_MUHENKAN)	/* 63 (JIS) */	\
+	MATRIX_KEY(0x03, 0x0e, KEY_RIGHTCTRL)	/* 64 */	\
+								\
+	MATRIX_KEY(0x04, 0x01, KEY_A)		/* 31 */	\
+	MATRIX_KEY(0x04, 0x02, KEY_D)		/* 33 */	\
+	MATRIX_KEY(0x04, 0x03, KEY_F)		/* 34 */	\
+	MATRIX_KEY(0x04, 0x05, KEY_K)		/* 38 */	\
+	MATRIX_KEY(0x04, 0x06, KEY_J)		/* 37 */	\
+	MATRIX_KEY(0x04, 0x08, KEY_SEMICOLON)	/* 40 */	\
+	MATRIX_KEY(0x04, 0x09, KEY_L)		/* 39 */	\
+	MATRIX_KEY(0x04, 0x0b, KEY_ENTER)	/* 43 */	\
+	MATRIX_KEY(0x04, 0x0c, KEY_END)		/* 81 (Numpad) */	\
+								\
+	MATRIX_KEY(0x05, 0x01, KEY_1)		/* 2 */	\
+	MATRIX_KEY(0x05, 0x02, KEY_COMMA)	/* 53 */	\
+	MATRIX_KEY(0x05, 0x03, KEY_DOT)		/* 54 */	\
+	MATRIX_KEY(0x05, 0x04, KEY_SLASH)	/* 55 */	\
+	MATRIX_KEY(0x05, 0x05, KEY_C)		/* 48 */	\
+	MATRIX_KEY(0x05, 0x06, KEY_SPACE)	/* 61 */	\
+	MATRIX_KEY(0x05, 0x07, KEY_LEFTSHIFT)	/* 44 */	\
+	MATRIX_KEY(0x05, 0x08, KEY_X)		/* 47 */	\
+	MATRIX_KEY(0x05, 0x09, KEY_V)		/* 49 */	\
+	MATRIX_KEY(0x05, 0x0b, KEY_M)		/* 52 */	\
+	MATRIX_KEY(0x05, 0x0c, KEY_PAGEDOWN)	/* 86 (Numpad) */	\
+								\
+	MATRIX_KEY(0x06, 0x01, KEY_Z)		/* 46 */	\
+	MATRIX_KEY(0x06, 0x02, KEY_3)		/* 4 */		\
+	MATRIX_KEY(0x06, 0x03, KEY_4)		/* 5 */		\
+	MATRIX_KEY(0x06, 0x04, KEY_2)		/* 3 */		\
+	MATRIX_KEY(0x06, 0x05, KEY_8)		/* 9 */		\
+	MATRIX_KEY(0x06, 0x06, KEY_0)		/* 11 */	\
+	MATRIX_KEY(0x06, 0x08, KEY_7)		/* 8 */		\
+	MATRIX_KEY(0x06, 0x09, KEY_9)		/* 10 */	\
+	MATRIX_KEY(0x06, 0x0b, KEY_DOWN)	/* 84 */	\
+	MATRIX_KEY(0x06, 0x0c, KEY_RIGHT)	/* 89 */	\
+	MATRIX_KEY(0x06, 0x0d, KEY_LEFTALT)	/* 60 */	\
+	MATRIX_KEY(0x06, 0x0f, KEY_ASSISTANT)	/* 128 */	\
+	MATRIX_KEY(0x06, 0x11, KEY_BACKSLASH)	/* 42 (JIS, ISO) */	\
+								\
+	MATRIX_KEY(0x07, 0x01, KEY_U)		/* 23 */	\
+	MATRIX_KEY(0x07, 0x02, KEY_I)		/* 24 */	\
+	MATRIX_KEY(0x07, 0x03, KEY_O)		/* 25 */	\
+	MATRIX_KEY(0x07, 0x04, KEY_P)		/* 26 */	\
+	MATRIX_KEY(0x07, 0x05, KEY_Q)		/* 17 */	\
+	MATRIX_KEY(0x07, 0x06, KEY_W)		/* 18 */	\
+	MATRIX_KEY(0x07, 0x07, KEY_RIGHTSHIFT)	/* 57 */	\
+	MATRIX_KEY(0x07, 0x08, KEY_E)		/* 19 */	\
+	MATRIX_KEY(0x07, 0x09, KEY_R)		/* 20 */	\
+	MATRIX_KEY(0x07, 0x0b, KEY_UP)		/* 83 */	\
+	MATRIX_KEY(0x07, 0x0c, KEY_LEFT)	/* 79 */	\
+	MATRIX_KEY(0x07, 0x11, KEY_102ND)	/* 45 (ISO) */
+
 #endif /* _CROS_EC_KEYBOARD_H */
-- 
2.45.1.288.g0e0cd299f1-goog


^ permalink raw reply related

* [dtor-input:for-linus] BUILD SUCCESS 955af6355ddfe35140f9706a635838212a32513b
From: kernel test robot @ 2024-06-04  2:06 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git for-linus
branch HEAD: 955af6355ddfe35140f9706a635838212a32513b  Input: i8042 - add Ayaneo Kun to i8042 quirk table

elapsed time: 1280m

configs tested: 194
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha                             allnoconfig   gcc  
alpha                            allyesconfig   gcc  
alpha                               defconfig   gcc  
arc                              allmodconfig   gcc  
arc                               allnoconfig   gcc  
arc                              allyesconfig   gcc  
arc                                 defconfig   gcc  
arc                   randconfig-001-20240603   gcc  
arc                   randconfig-002-20240603   gcc  
arm                              allmodconfig   gcc  
arm                               allnoconfig   clang
arm                              allyesconfig   gcc  
arm                                 defconfig   clang
arm                            dove_defconfig   gcc  
arm                   milbeaut_m10v_defconfig   clang
arm                   randconfig-001-20240603   gcc  
arm                   randconfig-002-20240603   gcc  
arm                   randconfig-003-20240603   gcc  
arm                   randconfig-004-20240603   gcc  
arm64                            allmodconfig   clang
arm64                             allnoconfig   gcc  
arm64                               defconfig   gcc  
arm64                 randconfig-001-20240603   gcc  
arm64                 randconfig-002-20240603   gcc  
arm64                 randconfig-003-20240603   clang
arm64                 randconfig-004-20240603   gcc  
csky                             allmodconfig   gcc  
csky                              allnoconfig   gcc  
csky                             allyesconfig   gcc  
csky                                defconfig   gcc  
csky                  randconfig-001-20240603   gcc  
csky                  randconfig-002-20240603   gcc  
hexagon                          allmodconfig   clang
hexagon                           allnoconfig   clang
hexagon                          allyesconfig   clang
hexagon                             defconfig   clang
hexagon               randconfig-001-20240603   clang
hexagon               randconfig-002-20240603   clang
i386                             allmodconfig   gcc  
i386                              allnoconfig   gcc  
i386                             allyesconfig   gcc  
i386         buildonly-randconfig-001-20240603   clang
i386         buildonly-randconfig-002-20240603   clang
i386         buildonly-randconfig-003-20240603   gcc  
i386         buildonly-randconfig-004-20240603   gcc  
i386         buildonly-randconfig-005-20240603   gcc  
i386         buildonly-randconfig-006-20240603   clang
i386                                defconfig   clang
i386                  randconfig-001-20240603   clang
i386                  randconfig-002-20240603   gcc  
i386                  randconfig-003-20240603   gcc  
i386                  randconfig-004-20240603   clang
i386                  randconfig-005-20240603   clang
i386                  randconfig-006-20240603   gcc  
i386                  randconfig-011-20240603   clang
i386                  randconfig-012-20240603   clang
i386                  randconfig-013-20240603   clang
i386                  randconfig-014-20240603   clang
i386                  randconfig-015-20240603   clang
i386                  randconfig-016-20240603   gcc  
loongarch                        allmodconfig   gcc  
loongarch                         allnoconfig   gcc  
loongarch                           defconfig   gcc  
loongarch             randconfig-001-20240603   gcc  
loongarch             randconfig-002-20240603   gcc  
m68k                             allmodconfig   gcc  
m68k                              allnoconfig   gcc  
m68k                             allyesconfig   gcc  
m68k                                defconfig   gcc  
microblaze                       allmodconfig   gcc  
microblaze                        allnoconfig   gcc  
microblaze                       allyesconfig   gcc  
microblaze                          defconfig   gcc  
mips                              allnoconfig   gcc  
mips                             allyesconfig   gcc  
mips                          ath79_defconfig   gcc  
mips                         bigsur_defconfig   gcc  
mips                          malta_defconfig   gcc  
mips                        omega2p_defconfig   clang
nios2                            allmodconfig   gcc  
nios2                             allnoconfig   gcc  
nios2                            allyesconfig   gcc  
nios2                               defconfig   gcc  
nios2                 randconfig-001-20240603   gcc  
nios2                 randconfig-002-20240603   gcc  
openrisc                          allnoconfig   gcc  
openrisc                         allyesconfig   gcc  
openrisc                            defconfig   gcc  
parisc                           allmodconfig   gcc  
parisc                            allnoconfig   gcc  
parisc                           allyesconfig   gcc  
parisc                              defconfig   gcc  
parisc                randconfig-001-20240603   gcc  
parisc                randconfig-002-20240603   gcc  
parisc64                            defconfig   gcc  
powerpc                          allmodconfig   gcc  
powerpc                           allnoconfig   gcc  
powerpc                          allyesconfig   clang
powerpc                 canyonlands_defconfig   clang
powerpc                      obs600_defconfig   clang
powerpc                     powernv_defconfig   gcc  
powerpc               randconfig-001-20240603   gcc  
powerpc               randconfig-002-20240603   gcc  
powerpc               randconfig-003-20240603   gcc  
powerpc64             randconfig-001-20240603   gcc  
powerpc64             randconfig-002-20240603   gcc  
powerpc64             randconfig-003-20240603   clang
riscv                            allmodconfig   clang
riscv                             allnoconfig   gcc  
riscv                            allyesconfig   clang
riscv                               defconfig   clang
riscv                 randconfig-001-20240603   clang
riscv                 randconfig-002-20240603   clang
riscv                          rv32_defconfig   clang
s390                             alldefconfig   gcc  
s390                             allmodconfig   clang
s390                              allnoconfig   clang
s390                             allyesconfig   gcc  
s390                                defconfig   clang
s390                  randconfig-001-20240603   clang
s390                  randconfig-002-20240603   clang
sh                               allmodconfig   gcc  
sh                                allnoconfig   gcc  
sh                               allyesconfig   gcc  
sh                                  defconfig   gcc  
sh                            hp6xx_defconfig   gcc  
sh                          landisk_defconfig   gcc  
sh                    randconfig-001-20240603   gcc  
sh                    randconfig-002-20240603   gcc  
sh                          rsk7201_defconfig   gcc  
sh                              ul2_defconfig   gcc  
sparc                            allmodconfig   gcc  
sparc                             allnoconfig   gcc  
sparc                               defconfig   gcc  
sparc64                          allmodconfig   gcc  
sparc64                          allyesconfig   gcc  
sparc64                             defconfig   gcc  
sparc64               randconfig-001-20240603   gcc  
sparc64               randconfig-002-20240603   gcc  
um                               allmodconfig   clang
um                                allnoconfig   clang
um                               allyesconfig   gcc  
um                                  defconfig   clang
um                             i386_defconfig   gcc  
um                    randconfig-001-20240603   clang
um                    randconfig-002-20240603   gcc  
um                           x86_64_defconfig   clang
x86_64                            allnoconfig   clang
x86_64                           allyesconfig   clang
x86_64       buildonly-randconfig-001-20240603   gcc  
x86_64       buildonly-randconfig-001-20240604   clang
x86_64       buildonly-randconfig-002-20240603   gcc  
x86_64       buildonly-randconfig-002-20240604   clang
x86_64       buildonly-randconfig-003-20240603   gcc  
x86_64       buildonly-randconfig-004-20240603   clang
x86_64       buildonly-randconfig-004-20240604   clang
x86_64       buildonly-randconfig-005-20240603   clang
x86_64       buildonly-randconfig-006-20240603   gcc  
x86_64       buildonly-randconfig-006-20240604   clang
x86_64                              defconfig   gcc  
x86_64                randconfig-001-20240603   gcc  
x86_64                randconfig-001-20240604   clang
x86_64                randconfig-002-20240603   clang
x86_64                randconfig-003-20240603   clang
x86_64                randconfig-004-20240603   gcc  
x86_64                randconfig-005-20240603   gcc  
x86_64                randconfig-006-20240603   gcc  
x86_64                randconfig-011-20240603   gcc  
x86_64                randconfig-011-20240604   clang
x86_64                randconfig-012-20240603   gcc  
x86_64                randconfig-012-20240604   clang
x86_64                randconfig-013-20240603   clang
x86_64                randconfig-013-20240604   clang
x86_64                randconfig-014-20240603   gcc  
x86_64                randconfig-014-20240604   clang
x86_64                randconfig-015-20240603   gcc  
x86_64                randconfig-015-20240604   clang
x86_64                randconfig-016-20240603   clang
x86_64                randconfig-016-20240604   clang
x86_64                randconfig-071-20240603   clang
x86_64                randconfig-071-20240604   clang
x86_64                randconfig-072-20240603   clang
x86_64                randconfig-073-20240603   clang
x86_64                randconfig-074-20240603   clang
x86_64                randconfig-074-20240604   clang
x86_64                randconfig-075-20240603   gcc  
x86_64                randconfig-075-20240604   clang
x86_64                randconfig-076-20240603   gcc  
x86_64                randconfig-076-20240604   clang
x86_64                          rhel-8.3-rust   clang
xtensa                            allnoconfig   gcc  
xtensa                  cadence_csp_defconfig   gcc  
xtensa                randconfig-001-20240603   gcc  
xtensa                randconfig-002-20240603   gcc  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* [PATCH] HID: logitech-hidpp: add missing MODULE_DESCRIPTION() macro
From: Jeff Johnson @ 2024-06-04  6:00 UTC (permalink / raw)
  To: Filipe Laíns, Bastien Nocera, Jiri Kosina,
	Benjamin Tissoires
  Cc: linux-input, linux-kernel, kernel-janitors, Jeff Johnson

make allmodconfig && make W=1 C=1 reports:
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-logitech-hidpp.o

Add the missing invocation of the MODULE_DESCRIPTION() macro.

Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
---
 drivers/hid/hid-logitech-hidpp.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index b81d5bcc76a7..400d70e6dbe2 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -27,6 +27,7 @@
 #include "usbhid/usbhid.h"
 #include "hid-ids.h"
 
+MODULE_DESCRIPTION("Support for Logitech devices relying on the HID++ specification");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
 MODULE_AUTHOR("Nestor Lopez Casado <nlopezcasad@logitech.com>");

---
base-commit: a693b9c95abd4947c2d06e05733de5d470ab6586
change-id: 20240603-md-hid-logitech-hidpp-209ce6cac203


^ permalink raw reply related

* Re: [PATCH] HID: core: remove unnecessary WARN_ON() in implement()
From: Jiri Kosina @ 2024-06-04  7:50 UTC (permalink / raw)
  To: Nikita Zhandarovich
  Cc: Benjamin Tissoires, Dmitry Torokhov, Douglas Anderson,
	linux-input, linux-kernel, Alan Stern,
	syzbot+5186630949e3c55f0799
In-Reply-To: <20240517141914.8604-1-n.zhandarovich@fintech.ru>

On Fri, 17 May 2024, Nikita Zhandarovich wrote:

> Syzkaller hit a warning [1] in a call to implement() when trying
> to write a value into a field of smaller size in an output report.
> 
> Since implement() already has a warn message printed out with the
> help of hid_warn() and value in question gets trimmed with:
> 	...
> 	value &= m;
> 	...
> WARN_ON may be considered superfluous. Remove it to suppress future
> syzkaller triggers.
> 
> [1]
> WARNING: CPU: 0 PID: 5084 at drivers/hid/hid-core.c:1451 implement drivers/hid/hid-core.c:1451 [inline]
> WARNING: CPU: 0 PID: 5084 at drivers/hid/hid-core.c:1451 hid_output_report+0x548/0x760 drivers/hid/hid-core.c:1863
> Modules linked in:
> CPU: 0 PID: 5084 Comm: syz-executor424 Not tainted 6.9.0-rc7-syzkaller-00183-gcf87f46fd34d #0
> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/02/2024
> RIP: 0010:implement drivers/hid/hid-core.c:1451 [inline]
> RIP: 0010:hid_output_report+0x548/0x760 drivers/hid/hid-core.c:1863
> ...
> Call Trace:
>  <TASK>
>  __usbhid_submit_report drivers/hid/usbhid/hid-core.c:591 [inline]
>  usbhid_submit_report+0x43d/0x9e0 drivers/hid/usbhid/hid-core.c:636
>  hiddev_ioctl+0x138b/0x1f00 drivers/hid/usbhid/hiddev.c:726
>  vfs_ioctl fs/ioctl.c:51 [inline]
>  __do_sys_ioctl fs/ioctl.c:904 [inline]
>  __se_sys_ioctl+0xfc/0x170 fs/ioctl.c:890
>  do_syscall_x64 arch/x86/entry/common.c:52 [inline]
>  do_syscall_64+0xf5/0x240 arch/x86/entry/common.c:83
>  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> ...
> 
> Fixes: 95d1c8951e5b ("HID: simplify implement() a bit")
> Reported-by: syzbot+5186630949e3c55f0799@syzkaller.appspotmail.com
> Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru>

I've added

	Suggested-by: Alan Stern <stern@rowland.harvard.edu>

and applied. Thanks,

-- 
Jiri Kosina
SUSE Labs


^ permalink raw reply

* Re: [PATCH] HID: Use kvzalloc instead of kzalloc in hid_register_field()
From: Jiri Kosina @ 2024-06-04  7:58 UTC (permalink / raw)
  To: Hailong.Liu; +Cc: benjamin.tissoires, linux-input, linux-kernel, 21cnbao
In-Reply-To: <20240522080328.12317-1-hailong.liu@oppo.com>

On Wed, 22 May 2024, hailong.liu@oppo.com wrote:

> From: "Hailong.Liu" <hailong.liu@oppo.com>
> 
> The function hid_register_field() might allocate more than 32k, which
> would use order-4 contiguous memory if the parameter usage exceeds
> 1024. However, after the system runs for a while, the memory can
> become heavily fragmented. This increases the likelihood of order-4 page
> allocation failure. Here’s the relevant log.
> 
> [71553.093623]kworker/1: 0: page allocation failure: order:4, mode:0x40dc0(GFP_KERNEL|__GFP_COMP|__GFP_ZERO), nodemask=(null),cpuset=/,mems_allowed=0
> [71553.093669]Workqueue: events uhid_device_add_worker
> [71553.093683]Call trace:
> [71553.093687]: dump_backtrace+0xf4/0x118
> [71553.093696]: show_stack+0x18/0x24
> [71553.093702]: dump_stack_lvl+0x60/0x7c
> [71553.093710]: dump_stack+0x18/0x3c
> [71553.093717]: warn_alloc+0xf4/0x174
> [71553.093725]: __alloc_pages_slowpath+0x1ba0/0x1cac
> [71553.093732]: __alloc_pages+0x460/0x560
> [71553.093738]: __kmalloc_large_node+0xbc/0x1f8
> [71553.093746]: __kmalloc+0x144/0x254
> [71553.093752]: hid_add_field+0x13c/0x308
> [71553.093758]: hid_parser_main+0x250/0x298
> [71553.093765]: hid_open_report+0x214/0x30c
> [71553.093771]: mt_probe+0x130/0x258
> [71553.093778]: hid_device_probe+0x11c/0x1e4
> [71553.093784]: really_probe+0xe4/0x388
> [71553.093791]: __driver_probe_device+0xa0/0x12c
> [71553.093798]: driver_probe_device+0x44/0x214
> [71553.093804]: __device_attach_driver+0xdc/0x124
> [71553.093812]: bus_for_each_drv+0x88/0xec
> [71553.093818]: __device_attach+0x84/0x170
> [71553.093824]: device_initial_probe+0x14/0x20
> [71553.093831]: bus_probe_device+0x48/0xd0
> [71553.093836]: device_add+0x248/0x928
> [71553.093844]: hid_add_device+0xf8/0x1a4
> [71553.093850]: uhid_device_add_worker+0x24/0x144
> [71553.093857]: process_one_work+0x158/0x804
> [71553.093865]: worker_thread+0x15c/0x494
> [71553.093872]: kthread+0xf4/0x1e4
> [71553.093880]: ret_from_fork+0x10/0x20
> 
> To fix the allocation failure, use kvzalloc() instead of kzalloc().
> 
> Signed-off-by: Hailong.Liu <hailong.liu@oppo.com>

Applied, thanks.

-- 
Jiri Kosina
SUSE Labs


^ permalink raw reply

* Re: [PATCH v3 2/2] input: Add support for "Do Not Disturb"
From: Jiri Kosina @ 2024-06-04  8:03 UTC (permalink / raw)
  To: Aseda Aboagye; +Cc: Dmitry Torokhov, Benjamin Tissoires, linux-input
In-Reply-To: <Zl4BBz4Doo8krta_@google.com>

On Mon, 3 Jun 2024, Aseda Aboagye wrote:

> 
> > >  #define KEY_ACCESSIBILITY              0x24e   /* Toggles the system bound accessibility UI/command (HUTRR116) */
> > > +#define KEY_DO_NOT_DISTURB             0x24f   /* Toggles the system-wide "Do Not Disturb" control (HUTRR94)*/
> > 
> > Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> > 
> > Feel free to merge through HID tree.
> 
> Thank you for the review!

Thanks. The patches are whitespace damaged though, and can't be applied. 
Could you please fix your patch sending workflow and resend?

Thanks!

-- 
Jiri Kosina
SUSE Labs


^ permalink raw reply

* Re: [PATCH 0/2] Improve HUION Kamvas Pro 24 support
From: Jiri Kosina @ 2024-06-04  8:13 UTC (permalink / raw)
  To: José Expósito; +Cc: benjamin.tissoires, linux-input, linux-kernel
In-Reply-To: <20240524112554.166746-1-jose.exposito89@gmail.com>

On Fri, 24 May 2024, José Expósito wrote:

> This series includes 2 patches to improve support for the HUION Kamvas
> Pro 24. See [1] and [2] for additional context.
> 
> [1] https://gitlab.freedesktop.org/libinput/libinput/-/issues/989
> [2] https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/989
> 
> José Expósito (2):
>   HID: uclogic: Support HUION devices with up to 20 buttons
>   HID: uclogic: Use Rx and Ry for touch strips

Applied, thanks José.

-- 
Jiri Kosina
SUSE Labs


^ permalink raw reply

* Re: [PATCH] HID: usbhid: fix recurrent out-of-bounds bug in usbhid_parse()
From: Jiri Kosina @ 2024-06-04  8:15 UTC (permalink / raw)
  To: Nikita Zhandarovich
  Cc: Benjamin Tissoires, Kees Cook, linux-usb, linux-input,
	syzkaller-bugs, linux-kernel, syzbot+c52569baf0c843f35495
In-Reply-To: <20240524120112.28076-1-n.zhandarovich@fintech.ru>

On Fri, 24 May 2024, Nikita Zhandarovich wrote:

> Syzbot reports [1] a reemerging out-of-bounds bug regarding hid
> descriptors possibly having incorrect bNumDescriptors values in
> usbhid_parse().
> 
> Build on the previous fix in "HID: usbhid: fix out-of-bounds bug"
> and run a sanity-check ensuring that number of descriptors doesn't
> exceed the size of desc[] in struct hid_descriptor.
> 
> [1] Syzbot report:
> Link: https://syzkaller.appspot.com/bug?extid=c52569baf0c843f35495
> 
> UBSAN: array-index-out-of-bounds in drivers/hid/usbhid/hid-core.c:1024:7
> index 1 is out of range for type 'struct hid_class_descriptor[1]'
> CPU: 0 PID: 8 Comm: kworker/0:1 Not tainted 6.9.0-rc6-syzkaller-00290-gb9158815de52 #0
> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/27/2024
> Workqueue: usb_hub_wq hub_event
> Call Trace:
>  <TASK>
>  __dump_stack lib/dump_stack.c:88 [inline]
>  dump_stack_lvl+0x241/0x360 lib/dump_stack.c:114
>  ubsan_epilogue lib/ubsan.c:231 [inline]
>  __ubsan_handle_out_of_bounds+0x121/0x150 lib/ubsan.c:429
>  usbhid_parse+0x5a7/0xc80 drivers/hid/usbhid/hid-core.c:1024
>  hid_add_device+0x132/0x520 drivers/hid/hid-core.c:2790
>  usbhid_probe+0xb38/0xea0 drivers/hid/usbhid/hid-core.c:1429
>  usb_probe_interface+0x645/0xbb0 drivers/usb/core/driver.c:399
>  really_probe+0x2b8/0xad0 drivers/base/dd.c:656
>  __driver_probe_device+0x1a2/0x390 drivers/base/dd.c:798
>  driver_probe_device+0x50/0x430 drivers/base/dd.c:828
>  __device_attach_driver+0x2d6/0x530 drivers/base/dd.c:956
>  bus_for_each_drv+0x24e/0x2e0 drivers/base/bus.c:457
>  __device_attach+0x333/0x520 drivers/base/dd.c:1028
>  bus_probe_device+0x189/0x260 drivers/base/bus.c:532
>  device_add+0x8ff/0xca0 drivers/base/core.c:3720
>  usb_set_configuration+0x1976/0x1fb0 drivers/usb/core/message.c:2210
>  usb_generic_driver_probe+0x88/0x140 drivers/usb/core/generic.c:254
>  usb_probe_device+0x1b8/0x380 drivers/usb/core/driver.c:294
> 
> Reported-and-tested-by: syzbot+c52569baf0c843f35495@syzkaller.appspotmail.com
> Fixes: f043bfc98c19 ("HID: usbhid: fix out-of-bounds bug")
> Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru>

Applied, thanks.

-- 
Jiri Kosina
SUSE Labs


^ permalink raw reply

* Re: [PATCH] HID: logitech-dj: Fix memory leak in logi_dj_recv_switch_to_dj_mode()
From: Jiri Kosina @ 2024-06-04  8:16 UTC (permalink / raw)
  To: José Expósito; +Cc: bentiss, lains, linux-input, linux-kernel
In-Reply-To: <20240524130600.275577-1-jose.exposito89@gmail.com>

On Fri, 24 May 2024, José Expósito wrote:

> Fix a memory leak on logi_dj_recv_send_report() error path.
> 
> Fixes: 6f20d3261265 ("HID: logitech-dj: Fix error handling in logi_dj_recv_switch_to_dj_mode()")
> Signed-off-by: José Expósito <jose.exposito89@gmail.com>
> ---
>  drivers/hid/hid-logitech-dj.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
> index 3c3c497b6b91..37958edec55f 100644
> --- a/drivers/hid/hid-logitech-dj.c
> +++ b/drivers/hid/hid-logitech-dj.c
> @@ -1284,8 +1284,10 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
>  		 */
>  		msleep(50);
>  
> -		if (retval)
> +		if (retval) {
> +			kfree(dj_report);
>  			return retval;
> +		}
>  	}

Applied, thanks.

-- 
Jiri Kosina
SUSE Labs


^ permalink raw reply

* Re: [PATCH 0/2] HID: intel-ish-hid: fix some 'make W=1' warnings
From: Jiri Kosina @ 2024-06-04  8:19 UTC (permalink / raw)
  To: Jeff Johnson
  Cc: Srinivas Pandruvada, Benjamin Tissoires, linux-input,
	linux-kernel, kernel-janitors, kernel test robot
In-Reply-To: <20240525-kd-ishtp_wait_resume-v1-0-fec87a6f7916@quicinc.com>

On Sat, 25 May 2024, Jeff Johnson wrote:

> Clean up some 'make W=1' warnings
> 
> ---
> Jeff Johnson (2):
>       HID: intel-ish-hid: fix ishtp_wait_resume() kernel-doc
>       HID: intel-ish-hid: add MODULE_DESCRIPTION()
> 
>  drivers/hid/intel-ish-hid/ishtp/bus.c | 2 ++
>  1 file changed, 2 insertions(+)
> ---

Applied, thank you.

-- 
Jiri Kosina
SUSE Labs


^ permalink raw reply

* Re: [PATCH] HID: nintendo: Fix an error handling path in nintendo_hid_probe()
From: Jiri Kosina @ 2024-06-04  8:21 UTC (permalink / raw)
  To: Christophe JAILLET
  Cc: Daniel J. Ogorchock, Benjamin Tissoires, Martino Fontana,
	Ryan McClelland, linux-kernel, kernel-janitors, linux-input
In-Reply-To: <9e599978852f9a2f30f9523edfd220dd1e25aa63.1716735907.git.christophe.jaillet@wanadoo.fr>

On Sun, 26 May 2024, Christophe JAILLET wrote:

> joycon_leds_create() has a ida_alloc() call. So if an error occurs after
> it, a corresponding ida_free() call is needed, as already done in the
> .remove function.
> 
> This is not 100% perfect, because if ida_alloc() fails, then
> 'ctlr->player_id' will forced to be U32_MAX, and an error will be logged
> when ida_free() is called.
> 
> Considering that this can't happen in real life, no special handling is
> done to handle it.
> 
> Fixes: 5307de63d71d ("HID: nintendo: use ida for LED player id")
> Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>

Applied, thanks.

-- 
Jiri Kosina
SUSE Labs


^ permalink raw reply

* Re: [PATCH] HID: Ignore battery for ELAN touchscreens 2F2C and 4116 on ASUS Zenbook 14 OLED (2023) and ASUS Zenbook Pro 14 OLED (2023)
From: Jiri Kosina @ 2024-06-04  8:39 UTC (permalink / raw)
  To: Louis Dalibard; +Cc: linux-input, bentiss
In-Reply-To: <04cff4e6-4c6b-424b-8f27-32e439eabf06@ontake.dev>

On Sun, 2 Jun 2024, Louis Dalibard wrote:

> The touchscreen reports a battery status of 0% and jumps to 1% when a stylus
> is used.
> The device ID was added and the battery ignore quirk was enabled for it.
> 
> Signed-off-by: Louis Dalibard <ontake@ontake.dev>

Thanks for the patch. It has however been whitespace damaged by your mail 
client / service provider, so it can't be applied.

Could you please fix that up, and resend?

Thanks,

-- 
Jiri Kosina
SUSE Labs


^ permalink raw reply

* Re: [PATCH] HID: logitech-hidpp: add missing MODULE_DESCRIPTION() macro
From: Jiri Kosina @ 2024-06-04  8:40 UTC (permalink / raw)
  To: Jeff Johnson
  Cc: Filipe Laíns, Bastien Nocera, Benjamin Tissoires,
	linux-input, linux-kernel, kernel-janitors
In-Reply-To: <20240603-md-hid-logitech-hidpp-v1-1-060f06e4529f@quicinc.com>

On Mon, 3 Jun 2024, Jeff Johnson wrote:

> make allmodconfig && make W=1 C=1 reports:
> WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-logitech-hidpp.o
> 
> Add the missing invocation of the MODULE_DESCRIPTION() macro.
> 
> Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>

Applied, thanks.

-- 
Jiri Kosina
SUSE Labs


^ permalink raw reply

* Re: [PATCH] HID: nintendo: Remove some unused functions
From: Jiri Kosina @ 2024-06-04  9:05 UTC (permalink / raw)
  To: Jiapeng Chong
  Cc: djogorchock, bentiss, linux-input, linux-kernel, Abaci Robot
In-Reply-To: <20240531085559.129085-1-jiapeng.chong@linux.alibaba.com>

On Fri, 31 May 2024, Jiapeng Chong wrote:

> These functions are defined in the hid-nintendo.c file, but not
> called elsewhere, so delete these unused functions.
> 
> drivers/hid/hid-nintendo.c:672:20: warning: unused function 'joycon_device_is_procon'.
> drivers/hid/hid-nintendo.c:682:20: warning: unused function 'joycon_device_is_snescon'.
> drivers/hid/hid-nintendo.c:687:20: warning: unused function 'joycon_device_is_gencon'.
> drivers/hid/hid-nintendo.c:692:20: warning: unused function 'joycon_device_is_n64con'.
> 
> Reported-by: Abaci Robot <abaci@linux.alibaba.com>
> Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=9265
> Signed-off-by: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>

Applied, thanks.

-- 
Jiri Kosina
SUSE Labs


^ permalink raw reply

* [PATCH] HID: Ignore battery for ELAN touchscreens 2F2C and 4116 on ASUS Zenbook 14 OLED (2023) and ASUS Zenbook Pro 14 OLED (2023)
From: Louis Dalibard @ 2024-06-04  9:21 UTC (permalink / raw)
  To: linux-input; +Cc: jikos, bentiss

The touchscreen reports a battery status of 0% and jumps to 1% when a
stylus is used.
The device ID was added and the battery ignore quirk was enabled for it.

Signed-off-by: Louis Dalibard <ontake@ontake.dev>
---
  drivers/hid/hid-ids.h   | 2 ++
  drivers/hid/hid-input.c | 4 ++++
  2 files changed, 6 insertions(+)

diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 61d2a21affa2..72d56ee7ce1b 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -423,6 +423,8 @@
  #define I2C_DEVICE_ID_HP_SPECTRE_X360_13_AW0020NG  0x29DF
  #define I2C_DEVICE_ID_ASUS_TP420IA_TOUCHSCREEN 0x2BC8
  #define I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN 0x2C82
+#define I2C_DEVICE_ID_ASUS_UX3402_TOUCHSCREEN 0x2F2C
+#define I2C_DEVICE_ID_ASUS_UX6404_TOUCHSCREEN 0x4116
  #define USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN 0x2544
  #define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706
  #define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN 0x261A
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index e03d300d2bac..0d21590e2d2c 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -377,6 +377,10 @@ static const struct hid_device_id
hid_battery_quirks[] = {
    HID_BATTERY_QUIRK_IGNORE },
   { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN,
I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN),
    HID_BATTERY_QUIRK_IGNORE },
+ { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_UX3402_TOUCHSCREEN),
+  HID_BATTERY_QUIRK_IGNORE },
+ { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_UX6404_TOUCHSCREEN),
+  HID_BATTERY_QUIRK_IGNORE },
   { HID_USB_DEVICE(USB_VENDOR_ID_ELAN,
USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN),
    HID_BATTERY_QUIRK_IGNORE },
   { HID_USB_DEVICE(USB_VENDOR_ID_ELAN,
USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN),
-- 
2.45.1


^ permalink raw reply related

* Re: [PATCH] HID: Ignore battery for ELAN touchscreens 2F2C and 4116 on ASUS Zenbook 14 OLED (2023) and ASUS Zenbook Pro 14 OLED (2023)
From: Jiri Kosina @ 2024-06-04  9:23 UTC (permalink / raw)
  To: Louis Dalibard; +Cc: linux-input, bentiss
In-Reply-To: <75245e3b-72ca-4a62-a88d-36b7c9976181@gmail.com>

On Tue, 4 Jun 2024, Louis Dalibard wrote:

> The touchscreen reports a battery status of 0% and jumps to 1% when a
> stylus is used.
> The device ID was added and the battery ignore quirk was enabled for it.
> 
> Signed-off-by: Louis Dalibard <ontake@ontake.dev>

Unfortunately, it's still whitespace-damaged. See

	Documentation/process/email-clients.rst

for some hints on how to fix that up, please.

Thanks,

-- 
Jiri Kosina
SUSE Labs


^ permalink raw reply

* [PATCH] HID: Ignore battery for ELAN touchscreens 2F2C and 4116 on ASUS Zenbook 14 OLED (2023) and ASUS Zenbook Pro 14 OLED (2023)
From: Louis Dalibard @ 2024-06-04  9:35 UTC (permalink / raw)
  To: linux-input; +Cc: jikos, bentiss

The touchscreen reports a battery status of 0% and jumps to 1% when a stylus is used. The device ID was added and the battery ignore quirk was enabled for it. Signed-off-by: Louis Dalibard --- drivers/hid/hid-ids.h | 2 ++ drivers/hid/hid-input.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 61d2a21affa2..72d56ee7ce1b 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -423,6 +423,8 @@ #define I2C_DEVICE_ID_HP_SPECTRE_X360_13_AW0020NG 0x29DF #define I2C_DEVICE_ID_ASUS_TP420IA_TOUCHSCREEN 0x2BC8 #define I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN 0x2C82 +#define I2C_DEVICE_ID_ASUS_UX3402_TOUCHSCREEN 0x2F2C +#define I2C_DEVICE_ID_ASUS_UX6404_TOUCHSCREEN 0x4116 #define USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN 0x2544 #define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706 #define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN 0x261A diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index e03d300d2bac..0d21590e2d2c
100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -377,6 +377,10 @@ static const struct hid_device_id hid_battery_quirks[] = { HID_BATTERY_QUIRK_IGNORE }, { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN), HID_BATTERY_QUIRK_IGNORE }, + { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_UX3402_TOUCHSCREEN), + HID_BATTERY_QUIRK_IGNORE }, + { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_UX6404_TOUCHSCREEN), + HID_BATTERY_QUIRK_IGNORE }, { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN), HID_BATTERY_QUIRK_IGNORE }, { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN), -- 2.45.1

^ permalink raw reply

* [PATCH] HID: Ignore battery for ELAN touchscreens 2F2C and 4116 on ASUS Zenbook 14 OLED (2023) and ASUS Zenbook Pro 14 OLED (2023)
From: Louis Dalibard @ 2024-06-04  9:38 UTC (permalink / raw)
  To: linux-input; +Cc: jikos, bentiss

The touchscreen reports a battery status of 0% and jumps to 1% when a stylus is used. The device ID was added and the battery ignore quirk was enabled for it. Signed-off-by: Louis Dalibard --- drivers/hid/hid-ids.h | 2 ++ drivers/hid/hid-input.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 61d2a21affa2..72d56ee7ce1b 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -423,6 +423,8 @@ #define I2C_DEVICE_ID_HP_SPECTRE_X360_13_AW0020NG 0x29DF #define I2C_DEVICE_ID_ASUS_TP420IA_TOUCHSCREEN 0x2BC8 #define I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN 0x2C82 +#define I2C_DEVICE_ID_ASUS_UX3402_TOUCHSCREEN 0x2F2C +#define I2C_DEVICE_ID_ASUS_UX6404_TOUCHSCREEN 0x4116 #define USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN 0x2544 #define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706 #define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN 0x261A diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index e03d300d2bac..0d21590e2d2c
100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -377,6 +377,10 @@ static const struct hid_device_id hid_battery_quirks[] = { HID_BATTERY_QUIRK_IGNORE }, { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN), HID_BATTERY_QUIRK_IGNORE }, + { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_UX3402_TOUCHSCREEN), + HID_BATTERY_QUIRK_IGNORE }, + { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_UX6404_TOUCHSCREEN), + HID_BATTERY_QUIRK_IGNORE }, { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN), HID_BATTERY_QUIRK_IGNORE }, { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN), -- 2.45.1

^ permalink raw reply

* [PATCH] HID: Ignore battery for ELAN touchscreens 2F2C and 4116 on ASUS Zenbook 14 OLED (2023) and ASUS Zenbook Pro 14 OLED (2023)
From: Louis Dalibard @ 2024-06-04  9:57 UTC (permalink / raw)
  To: linux-input; +Cc: jikos, bentiss

The touchscreen reports a battery status of 0% and jumps to 1% when a 
stylus is used.
The device ID was added and the battery ignore quirk was enabled for it.

Signed-off-by: Louis Dalibard <ontake@ontake.dev>
---
  drivers/hid/hid-ids.h   | 2 ++
  drivers/hid/hid-input.c | 4 ++++
  2 files changed, 6 insertions(+)

diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 61d2a21affa2..72d56ee7ce1b 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -423,6 +423,8 @@
  #define I2C_DEVICE_ID_HP_SPECTRE_X360_13_AW0020NG  0x29DF
  #define I2C_DEVICE_ID_ASUS_TP420IA_TOUCHSCREEN 0x2BC8
  #define I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN 0x2C82
+#define I2C_DEVICE_ID_ASUS_UX3402_TOUCHSCREEN 0x2F2C
+#define I2C_DEVICE_ID_ASUS_UX6404_TOUCHSCREEN 0x4116
  #define USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN 0x2544
  #define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706
  #define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN 0x261A
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index e03d300d2bac..0d21590e2d2c 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -377,6 +377,10 @@ static const struct hid_device_id 
hid_battery_quirks[] = {
    HID_BATTERY_QUIRK_IGNORE },
   { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, 
I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN),
    HID_BATTERY_QUIRK_IGNORE },
+ { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_UX3402_TOUCHSCREEN),
+  HID_BATTERY_QUIRK_IGNORE },
+ { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_UX6404_TOUCHSCREEN),
+  HID_BATTERY_QUIRK_IGNORE },
   { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, 
USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN),
    HID_BATTERY_QUIRK_IGNORE },
   { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, 
USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN),
-- 
2.45.1




^ permalink raw reply related

* Re: [PATCH] [v3] HID: intel-ish-hid: fix endian-conversion
From: srinivas pandruvada @ 2024-06-04 11:23 UTC (permalink / raw)
  To: Zhang, Lixu, Arnd Bergmann, Jiri Kosina
  Cc: Arnd Bergmann, Benjamin Tissoires, linux-input@vger.kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <DM4PR11MB599501461E04F76B9F32374093FF2@DM4PR11MB5995.namprd11.prod.outlook.com>

On Mon, 2024-06-03 at 08:38 +0000, Zhang, Lixu wrote:
> > -----Original Message-----
> > From: Arnd Bergmann <arnd@kernel.org>
> > Sent: Monday, June 3, 2024 3:41 PM
> > To: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>; Jiri
> > Kosina
> > <jikos@kernel.org>; Zhang, Lixu <lixu.zhang@intel.com>
> > Cc: Arnd Bergmann <arnd@arndb.de>; Benjamin Tissoires
> > <bentiss@kernel.org>; linux-input@vger.kernel.org; linux-
> > kernel@vger.kernel.org
> > Subject: [PATCH] [v3] HID: intel-ish-hid: fix endian-conversion
> > 
> > From: Arnd Bergmann <arnd@arndb.de>
> > 
> > The newly added file causes a ton of sparse warnings about the
> > incorrect use of
> > __le32 and similar types:
> > 
> > Add the necessary conversions and use temporary variables where
> > appropriate
> > to avoid converting back.
> > 
> > Fixes: 579a267e4617 ("HID: intel-ish-hid: Implement loading
> > firmware from
> > host feature")
> > Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> Reviewed-by: Zhang Lixu <lixu.zhang@intel.com>
> Tested-by: Zhang Lixu <lixu.zhang@intel.com>

Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>

> 
> Thanks,
> Lixu
> > ---


^ permalink raw reply


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