Linux Input/HID development
 help / color / mirror / Atom feed
* Re: [PATCH v5 4/4] Input: Add TouchNetix aXiom I2C Touchscreen support
From: Marco Felsch @ 2026-02-25 20:50 UTC (permalink / raw)
  To: Andrew Thomas
  Cc: Luis Chamberlain, Russ Weight, Greg Kroah-Hartman,
	Rafael J. Wysocki, Andrew Morton, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Dmitry Torokhov, Kamel Bouhara,
	Marco Felsch, Henrik Rydberg, Danilo Krummrich, linux-kernel,
	devicetree, linux-input
In-Reply-To: <qoelgb5k77a4c4jodn622a6wauotzkeygy5fj54cjjnobb5g6c@ysxkou6nhkop>

Hi Andrew,

thanks for the your reply, please see below.

On 26-02-25, Andrew Thomas wrote:
> On Sun, Jan 11, 2026 at 04:05:47PM +0100, Marco Felsch wrote:

...

> > +struct axiom_u33_rev3 {
> > +	__le32 runtime_crc;
> > +	__le32 runtime_nvm_crc;
> > +	__le32 bootloader_crc;
> > +	__le32 nvltlusageconfig_crc;
> > +	__le32 vltusageconfig_crc;
> > +	__le32 u22_sequencedata_crc;
> > +	__le32 u43_hotspots_crc;
> > +	__le32 u77_dod_data_crc;
> > +	__le32 u93_profiles_crc;
> > +	__le32 u94_deltascalemap_crc;
> > +	__le32 runtimehash_crc;
> > +};
> > +
> 
> I think revision handling should be kept in unpacking where possible.
> Currently there are 10 revisions of u33, so adding support for many
> revisions and usages would add alot of code.

This isn't very complex nor very large code. Each u33 rev will add
44-byte of code, so in the end there will be 440-byte. I've also seen
that some revisions reduce the size because some fields aren't required.
E.g. u93_crc is at offset-5.

Furthermore describing the complete layout of u33 allows us using it to
query the u33 in one i2c-bulk-transfer.

> > +#define AXIOM_U34				0x34
> > +#define   AXIOM_U34_REV1_OVERFLOW_MASK		BIT(7)
> > +#define   AXIOM_U34_REV1_REPORTLENGTH_MASK	GENMASK(6, 0)
> > +#define   AXIOM_U34_REV1_PREAMBLE_BYTES		2
> > +#define   AXIOM_U34_REV1_POSTAMBLE_BYTES	4

...

> > +enum axiom_runmode {
> > +	AXIOM_DISCOVERY_MODE,
> > +	AXIOM_TCP_MODE,
> > +	AXIOM_TCP_CFG_UPDATE_MODE,
> > +	AXIOM_BLP_PRE_MODE,
> > +	AXIOM_BLP_MODE,
> > +};
> 
> There are only two actual axiom states, bootloader and runtime (TCP).
> This is more of a driver state rather than an axiom state.
> Could you label it as such?

Yes I know and the AXIOM_BLP_PRE_MODE will be dropped with the next
version, which I'm going to send this week!. Not sure why this would be
required.

> > +struct axiom_data {
> > +	struct input_dev *input;
> > +	struct device *dev;
> > +
> > +	struct gpio_desc *reset_gpio;
> > +	struct regulator_bulk_data supplies[2];
> > +	unsigned int num_supplies;
> > +
> > +	struct regmap *regmap;
> > +	struct touchscreen_properties prop;
> > +	bool irq_setup_done;
> > +	u32 poll_interval;
> > +
> > +	struct drm_panel_follower panel_follower;
> > +	bool is_panel_follower;
> > +
> > +	enum axiom_runmode mode;
> > +	/*
> > +	 * Two completion types to support firmware updates
> > +	 * in irq and poll mode.
> > +	 */
> > +	struct axiom_completion {
> > +		struct completion completion;
> > +		bool poll_done;
> > +	} nvm_write, boot_complete;
> > +
> > +	/* Lock to protect both firmware interfaces */
> > +	struct mutex fwupdate_lock;
> > +	struct axiom_firmware {
> > +		/* Lock to protect cancel */
> > +		struct mutex lock;
> > +		bool cancel;
> > +		struct fw_upload *fwl;
> > +	} fw[AXIOM_FW_NUM];
> > +
> > +	unsigned int fw_major;
> > +	unsigned int fw_minor;
> > +	unsigned int fw_rc;
> > +	unsigned int fw_status;
> > +	unsigned int fw_variant;
> > +	u16 device_id;
> > +	u16 jedec_id;
> > +	u8 silicon_rev;
> > +
> > +	/* CRCs we need to check during a config update */
> > +	struct axiom_crc {
> > +		u32 runtime;
> > +		u32 vltusageconfig;
> > +		u32 nvltlusageconfig;
> > +		u32 u22_sequencedata;
> > +		u32 u43_hotspots;
> > +		u32 u77_dod_data;
> > +		u32 u93_profiles;
> > +		u32 u94_deltascalemap;
> > +	} crc[AXIOM_CRC_NUM];
> 
> I think this structure should hold all possible u33 CRCs and then
> invalid ones can be ignored for the given u33 revision.

Why should be the bootloader CRC interessting? The bootloader can't be
updated/flashed, at least not according my documentation. Therefore I
didn't listed the bootloader CRC here.

> > +	bool cds_enabled;
> > +	unsigned long enabled_slots;
> > +	unsigned int num_slots;
> > +
> > +	unsigned int max_report_byte_len;
> > +	struct axiom_usage_table_entry {
> > +		bool populated;
> > +		unsigned int baseaddr;
> > +		unsigned int size_bytes;
> > +		const struct axiom_usage_info *info;
> > +	} usage_table[AXIOM_MAX_USAGES];
> > +};

....

> > +static int axiom_u02_swreset(struct axiom_data *ts)
> > +{
> > +	struct axiom_u02_rev1_system_manager_msg msg = { };
> > +	int ret;
> > +
> > +	if (!axiom_driver_supports_usage(ts, AXIOM_U02))
> > +		return -EINVAL;
> > +
> > +	msg.command = cpu_to_le16(AXIOM_U02_REV1_CMD_SOFTRESET);
> > +	ret = axiom_u02_send_msg(ts, &msg, false);
> > +	if (ret)
> > +		return ret;
> > +
> > +	/*
> > +	 * Downstream http://axcfg.py waits for 1sec without checking U01 hello. Tests
> > +	 * showed that waiting for the hello message isn't enough therefore we
> > +	 * need both to make it robuster.
> > +	 */
> > +	ret = axiom_wait_for_completion_timeout(ts, &ts->boot_complete,
> > +					msecs_to_jiffies(1 * MSEC_PER_SEC));
> 
> Boot can take up to 2s with all selftests enabled.

Thanks for this information :) I will add it.

> > +	if (!ret)
> > +		dev_err(ts->dev, "Error swreset timedout\n");
> > +
> > +	fsleep(USEC_PER_SEC);
> > +
> > +	return ret ? 0 : -ETIMEDOUT;
> > +}

...

> > +static int axiom_u02_enter_bootloader(struct axiom_data *ts)
> > +{
> > +	struct axiom_u02_rev1_system_manager_msg msg = { };
> > +	struct device *dev = ts->dev;
> > +	unsigned int val;
> > +	int ret;
> > +
> > +	if (!axiom_driver_supports_usage(ts, AXIOM_U02))
> > +		return -EINVAL;
> > +
> > +	/*
> > +	 * Enter the bootloader mode requires 3 consecutive messages so we can't
> > +	 * check for the response.
> > +	 */
> > +	msg.command = cpu_to_le16(AXIOM_U02_REV1_CMD_ENTERBOOTLOADER);
> > +	msg.parameters[0] = cpu_to_le16(AXIOM_U02_REV1_PARAM0_ENTERBOOLOADER_KEY1);
> > +	ret = axiom_u02_send_msg(ts, &msg, false);
> > +	if (ret) {
> > +		dev_err(dev, "Failed to send bootloader-key1: %d\n", ret);
> > +		return ret;
> > +	}
> 
> A delay is required between commands. 10ms is fine.

Can I make use of the axiom_u02_wait_idle() logic which checks the
AXIOM_U02_REV1_RESP_SUCCESS? Arbitrary delays are always a source of
trouble.

> > +	msg.parameters[0] = cpu_to_le16(AXIOM_U02_REV1_PARAM0_ENTERBOOLOADER_KEY2);
> > +	ret = axiom_u02_send_msg(ts, &msg, false);
> > +	if (ret) {
> > +		dev_err(dev, "Failed to send bootloader-key2: %d\n", ret);
> > +		return ret;
> > +	}
> 
> And here.
> 
> > +
> > +	msg.parameters[0] = cpu_to_le16(AXIOM_U02_REV1_PARAM0_ENTERBOOLOADER_KEY3);
> > +	ret = axiom_u02_send_msg(ts, &msg, false);
> > +	if (ret) {
> > +		dev_err(dev, "Failed to send bootloader-key3: %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	/* Sleep before the first read to give the device time */
> > +	fsleep(250 * USEC_PER_MSEC);
> > +
> > +	/* Wait till the device reports it is in bootloader mode */
> > +	return regmap_read_poll_timeout(ts->regmap,
> > +			AXIOM_U31_REV1_DEVICE_ID_HIGH_REG, val,
> > +			FIELD_GET(AXIOM_U31_REV1_MODE_MASK, val) ==
> > +			AXIOM_U31_REV1_MODE_BLP, 250 * USEC_PER_MSEC,
> > +			USEC_PER_SEC);
> > +}
> 
> Just to note if we cannot enter bootloader with u02 due to a corrupted firmware,
> you can enter bootloader if the nRESET line is toggled 5 times without comms.

This could be added later on by $dev (maybe you :)) since I can't test
this. Our system has the reset line not connected :/

...

> > +static int axiom_u33_read(struct axiom_data *ts, struct axiom_crc *crc)
> > +{
> > +	struct device *dev = ts->dev;
> > +	unsigned int reg;
> > +	int ret;
> > +
> > +	if (!axiom_driver_supports_usage(ts, AXIOM_U33))
> > +		return -EINVAL;
> > +
> > +	if (axiom_usage_rev(ts, AXIOM_U33) == 2) {
> > +		struct axiom_u33_rev2 val;
> > +
> > +		reg = axiom_usage_baseaddr(ts, AXIOM_U33);
> > +		ret = regmap_raw_read(ts->regmap, reg, &val, sizeof(val));
> 
> Could we read into a raw buffer to save having to define a little endian
> version of the CRCs?

I don't see the benefit.

...

> > +/* Custom regmap read/write handling is required due to the aXiom protocol */
> > +static int axiom_regmap_read(void *context, const void *reg_buf, size_t reg_size,
> > +			     void *val_buf, size_t val_size)
> > +{
> > +	struct device *dev = context;
> > +	struct i2c_client *i2c = to_i2c_client(dev);
> > +	struct axiom_data *ts = i2c_get_clientdata(i2c);
> > +	struct axiom_cmd_header hdr;
> > +	u16 xferlen, addr, baseaddr;
> > +	struct i2c_msg xfer[2];
> > +	int ret;
> > +
> > +	if (val_size > AXIOM_MAX_XFERLEN) {
> > +		dev_err(ts->dev, "Exceed max xferlen: %zu > %u\n",
> > +			val_size, AXIOM_MAX_XFERLEN);
> > +		return -EINVAL;
> > +	}
> > +
> > +	addr = *((u16 *)reg_buf);
> > +	hdr.target_address = cpu_to_le16(addr);
> > +	xferlen = FIELD_PREP(AXIOM_CMD_HDR_DIR_MASK, AXIOM_CMD_HDR_READ) |
> > +		  FIELD_PREP(AXIOM_CMD_HDR_LEN_MASK, val_size);
> > +	hdr.xferlen = cpu_to_le16(xferlen);
> > +
> > +	/* Verify that usage including the usage rev is supported */
> > +	baseaddr = addr & AXIOM_USAGE_BASEADDR_MASK;
> > +	if (!axiom_usage_supported(ts, baseaddr))
> > +		return -EINVAL;
> > +
> > +	xfer[0].addr = i2c->addr;
> > +	xfer[0].flags = 0;
> > +	xfer[0].len = sizeof(hdr);
> > +	xfer[0].buf = (u8 *)&hdr;
> > +
> > +	xfer[1].addr = i2c->addr;
> > +	xfer[1].flags = I2C_M_RD;
> > +	xfer[1].len = val_size;
> > +	xfer[1].buf = val_buf;
> > +
> > +	ret = i2c_transfer(i2c->adapter, xfer, 2);
> > +	if (ret == 2)
> > +		return 0;
> > +	else if (ret < 0)
> > +		return ret;
> > +	else
> > +		return -EIO;
> > +}
> 
> There needs to be atleast 40us holdoff between axiom bus transfers.
> I am not sure that has been considered here.

Is this written somewhere within the datasheet/programming-guide?

...

> > +static enum fw_upload_err
> > +axiom_cfg_fw_prepare(struct fw_upload *fw_upload, const u8 *data, u32 size)
> > +{

...

> > +	cur_runtime_crc = ts->crc[AXIOM_CRC_CUR].runtime;
> > +	fw_runtime_crc = ts->crc[AXIOM_CRC_NEW].runtime;
> > +	if (cur_runtime_crc != fw_runtime_crc) {
> > +		dev_err(dev, "TH2CFG and device runtime CRC doesn't match: %#x != %#x\n",
> > +			fw_runtime_crc, cur_runtime_crc);
> > +		ret = FW_UPLOAD_ERR_FW_INVALID;
> > +		goto out;
> > +	}
> 
> The firmware CRCs dont need to match for a config load, only the usage revision/length.

What difference does it make? The firmware CRC implicit includes the
usage revision and the length (register layout). So we can ensure that
the configuration was made for the correct register layout without
checking each register and revision.

...

> > +static enum fw_upload_err
> > +axiom_cfg_fw_write(struct fw_upload *fw_upload, const u8 *data, u32 offset,
> > +		   u32 size, u32 *written)
> > +{

....

> > +	/* Ensure that the chunks are written correctly */
> > +	ret = axiom_verify_volatile_mem(ts);
> > +	if (ret) {
> > +		dev_err(dev, "Failed to verify written config, abort\n");
> > +		goto err_swreset;
> > +	}
> > +
> > +	ret = axiom_u02_save_config(ts);
> > +	if (ret)
> > +		goto err_swreset;
> > +
> > +	/*
> > +	 * TODO: Check if u02 start would be sufficient to load the new config
> > +	 * values
> > +	 */
> 
> It is not necessarily needed.

What do you mean by this? Do we need the axiom_u02_swreset() or can we
just start the system via u02 (without swreset)?

> 
> > +	ret = axiom_u02_swreset(ts);
> > +	if (ret) {
> > +		dev_err(dev, "Soft reset failed\n");
> > +		goto err_unlock;
> > +	}

....

> > +static ssize_t fw_variant_show(struct device *dev,
> > +			       struct device_attribute *attr, char *buf)
> > +{
> > +	struct i2c_client *i2c = to_i2c_client(dev);
> > +	struct axiom_data *ts = i2c_get_clientdata(i2c);
> > +	const char *val;
> > +
> > +	switch (ts->fw_variant) {
> > +	case 0:
> > +		val = "3d";
> > +		break;
> > +	case 1:
> > +		val = "2d";
> > +		break;
> > +	case 3:
> > +		val = "force";
> > +		break;
> > +	default:
> > +		val = "unknown";
> > +		break;
> > +	}
> 
> The following are all the variants we currently support in order:
> FW_VARIANTS = ["3D", "2D", "FORCE", "0D", "XL"]

Means:

0 == 3d
1 == 2d
3 == force
4 == 0d
5 == xl

?

This is also something I can test on my site. Patches are welcome once
this is mainline of course :)

Regards,
  Marco

-- 
#gernperDu 
#CallMeByMyFirstName

Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | https://www.pengutronix.de/ |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-9    |

^ permalink raw reply

* Re: [PATCH v3 4/4] Input: charlieplex_keypad: add GPIO charlieplex keypad
From: Hugo Villeneuve @ 2026-02-25 17:36 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Dmitry Torokhov, robin, andy, geert, robh, krzk+dt, conor+dt,
	hvilleneuve, mkorpershoek, matthias.bgg,
	angelogioacchino.delregno, lee, alexander.sverdlin, marek.vasut,
	akurz, devicetree, linux-kernel, linux-input, linux-arm-kernel,
	linux-mediatek
In-Reply-To: <aZ8voAddPvMLCvc4@smile.fi.intel.com>

On Wed, 25 Feb 2026 19:21:36 +0200
Andy Shevchenko <andriy.shevchenko@intel.com> wrote:

> On Wed, Feb 25, 2026 at 09:14:16AM -0800, Dmitry Torokhov wrote:
> > On Wed, Feb 25, 2026 at 11:56:52AM -0500, Hugo Villeneuve wrote:
> > > On Wed, 25 Feb 2026 11:41:55 -0500
> > > Hugo Villeneuve <hugo@hugovil.com> wrote:
> > > > On Wed, 25 Feb 2026 18:12:13 +0200
> > > > Andy Shevchenko <andriy.shevchenko@intel.com> wrote:
> > > > > On Wed, Feb 25, 2026 at 10:54:01AM -0500, Hugo Villeneuve wrote:
> 
> ...
> 
> > > > > > +#include <linux/of.h>
> > > > > 
> > > > > Is this in use? Or you wanted mod_devicetable.h for OF ID table?
> > > > 
> > > > I need only OF ID table, so will replace with mod_devicetable.h.
> > > 
> > > Hi Andy,
> > > finally I need <linux/of.h> for of_match_ptr()...
> > > 
> > > But I will keep <mod_devicetable.h> ...
> > 
> > Do we need the dependency on OF? We may include of match pointer
> > unconditionally and the driver could be used on ACPI systems with
> > PRP0001 HID.
> 
> Not only that. of_match_ptr() or ACPI_PTR() shouldn't be used in a new code
> (there are, of course, _rare_ corner cases, which this one is not one of).

Ok, will remove of_match_ptr() and also include <linux/of.h>

Hugo Villeneuve

^ permalink raw reply

* Re: [PATCH v3 4/4] Input: charlieplex_keypad: add GPIO charlieplex keypad
From: Hugo Villeneuve @ 2026-02-25 17:27 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Andy Shevchenko, robin, andy, geert, robh, krzk+dt, conor+dt,
	hvilleneuve, mkorpershoek, matthias.bgg,
	angelogioacchino.delregno, lee, alexander.sverdlin, marek.vasut,
	akurz, devicetree, linux-kernel, linux-input, linux-arm-kernel,
	linux-mediatek
In-Reply-To: <aZ8sjwaKk5MCSDlg@google.com>

Hi Dmitry,

On Wed, 25 Feb 2026 09:12:57 -0800
Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:

> Hi Hugo,
> 
> On Wed, Feb 25, 2026 at 11:41:55AM -0500, Hugo Villeneuve wrote:
> > Hi Andy,
> > thank you for the review.
> > 
> > On Wed, 25 Feb 2026 18:12:13 +0200
> > Andy Shevchenko <andriy.shevchenko@intel.com> wrote:
> > 
> > > On Wed, Feb 25, 2026 at 10:54:01AM -0500, Hugo Villeneuve wrote:
> > > 
> > > > Add support for GPIO-based charlieplex keypad, allowing to control
> > > > N^2-N keys using N GPIO lines.
> > > > 
> > > > Reuse matrix keypad keymap to simplify, even if there is no concept
> > > > of rows and columns in this type of keyboard.
> > > 
> > > ...
> > > 
> > > > +/*
> > > > + *  GPIO driven charlieplex keypad driver
> > > > + *
> > > > + *  Copyright (c) 2025 Hugo Villeneuve <hvilleneuve@dimonoff.com>
> > > > + *
> > > > + *  Based on matrix_keyboard.c
> > > 
> > > A single space after asterisk is enough.
> > 
> > Ok, leftover from copy/paste from matrix_keyboard.c :)
> > 
> > > 
> > > > + */
> > > 
> > > ...
> > > 
> > > + bitops.h
> > > 
> > > > +#include <linux/delay.h>
> > > 
> > > + dev_printk.h
> > > + device/devres.h
> > > + err.h
> > > 
> > > > +#include <linux/gpio/consumer.h>
> > > > +#include <linux/input.h>
> > > > +#include <linux/input/matrix_keypad.h>
> > > 
> > > + math.h
> > 
> > Ok.
> > 
> > 
> > > 
> > > > +#include <linux/module.h>
> > > 
> > > > +#include <linux/of.h>
> > > 
> > > Is this in use? Or you wanted mod_devicetable.h for OF ID table?
> > 
> > I need only OF ID table, so will replace with mod_devicetable.h.
> > 
> > 
> > > 
> > > > +#include <linux/platform_device.h>
> > > > +#include <linux/property.h>
> > > > +#include <linux/types.h>
> > > 
> > > ...
> > > 
> > > > +	for (code = 0, oline = 0; oline < keypad->nlines; oline++) {
> > > > +		DECLARE_BITMAP(values, MATRIX_MAX_ROWS);
> > > > +		int iline;
> > > 
> > > > +		int rc;
> > > 
> > > I think Dmitry prefers 'error' name for this kind of variables.
> > 
> > I hate using "error", can be so misleading :)
> > 
> > I would prefer to use "rc" everywhere, but if Dmitry chimes in and
> > specifies "error" or "err", then so it will be.
> 
> Yes, I prefer err or error for variables that carry error code or 0.
> This allows to write
> 
> 	error = action(...);
> 	if (error) {
> 		// handle it
> 	}
> 
> which is very clear IMO.

Ok, will fix it globally to "err" everywhere in V4.


> 
> 
> > > > +
> > > > +	err = input_register_device(keypad->input_dev);
> > > > +	if (err)
> > > > +		return err;
> > > 
> > > > +	platform_set_drvdata(pdev, keypad);
> > > 
> > > Is this needed?
> > 
> > No, will remove it, and replace last lines with:
> > 
> >    return input_register_device(keypad->input_dev);
> 
> Please use
> 
> 	err = input_register_device(...);
> 	if (err)
> 		return err;
> 
> 	return 0;
> 
> It clearly differentiates error an normal paths, shows that function
> returns 0 and not anything else on success, and allows to reorder
> or add additional actions easily.

Ok.

Thank you,
Hugo


^ permalink raw reply

* Re: [PATCH v3 4/4] Input: charlieplex_keypad: add GPIO charlieplex keypad
From: Andy Shevchenko @ 2026-02-25 17:21 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Hugo Villeneuve, robin, andy, geert, robh, krzk+dt, conor+dt,
	hvilleneuve, mkorpershoek, matthias.bgg,
	angelogioacchino.delregno, lee, alexander.sverdlin, marek.vasut,
	akurz, devicetree, linux-kernel, linux-input, linux-arm-kernel,
	linux-mediatek
In-Reply-To: <aZ8tocPCKqTXqbC0@google.com>

On Wed, Feb 25, 2026 at 09:14:16AM -0800, Dmitry Torokhov wrote:
> On Wed, Feb 25, 2026 at 11:56:52AM -0500, Hugo Villeneuve wrote:
> > On Wed, 25 Feb 2026 11:41:55 -0500
> > Hugo Villeneuve <hugo@hugovil.com> wrote:
> > > On Wed, 25 Feb 2026 18:12:13 +0200
> > > Andy Shevchenko <andriy.shevchenko@intel.com> wrote:
> > > > On Wed, Feb 25, 2026 at 10:54:01AM -0500, Hugo Villeneuve wrote:

...

> > > > > +#include <linux/of.h>
> > > > 
> > > > Is this in use? Or you wanted mod_devicetable.h for OF ID table?
> > > 
> > > I need only OF ID table, so will replace with mod_devicetable.h.
> > 
> > Hi Andy,
> > finally I need <linux/of.h> for of_match_ptr()...
> > 
> > But I will keep <mod_devicetable.h> ...
> 
> Do we need the dependency on OF? We may include of match pointer
> unconditionally and the driver could be used on ACPI systems with
> PRP0001 HID.

Not only that. of_match_ptr() or ACPI_PTR() shouldn't be used in a new code
(there are, of course, _rare_ corner cases, which this one is not one of).

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply

* Re: [PATCH v5 4/4] Input: Add TouchNetix aXiom I2C Touchscreen support
From: Andrew Thomas @ 2026-02-25 17:11 UTC (permalink / raw)
  To: Marco Felsch
  Cc: Luis Chamberlain, Russ Weight, Greg Kroah-Hartman,
	Rafael J. Wysocki, Andrew Morton, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Dmitry Torokhov, Kamel Bouhara,
	Marco Felsch, Henrik Rydberg, Danilo Krummrich, linux-kernel,
	devicetree, linux-input
In-Reply-To: <20260111-v6-10-topic-touchscreen-axiom-v5-4-f94e0ae266cb@pengutronix.de>

On Sun, Jan 11, 2026 at 04:05:47PM +0100, Marco Felsch wrote:
>This adds the initial support for the TouchNetix AX54A touchcontroller
>which is part of TouchNetix's aXiom touchscreen controller family.
>
>The TouchNetix aXiom family provides two physical interfaces: SPI and
>I2C. This patch covers only the I2C interface.
>
>Apart the input event handling the driver supports firmware updates too.
>One firmware interface handles the touchcontroller firmware (AXFW and
>ALC) update the other handles the touchcontroller configuration
>(TH2CFGBIN) update.
>
>Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
>---
> .../testing/sysfs-driver-input-touchnetix-axiom    |   81 +
> drivers/input/touchscreen/Kconfig                  |   17 +
> drivers/input/touchscreen/Makefile                 |    1 +
> drivers/input/touchscreen/touchnetix_axiom.c       | 2974 ++++++++++++++++++++
> 4 files changed, 3073 insertions(+)
>
>diff --git a/Documentation/ABI/testing/sysfs-driver-input-touchnetix-axiom b/Documentation/ABI/testing/sysfs-driver-input-touchnetix-axiom
>new file mode 100644
>index 0000000000000000000000000000000000000000..31c1c6510c55da80659ddf7bea2d0ce681fde323
>--- /dev/null
>+++ b/Documentation/ABI/testing/sysfs-driver-input-touchnetix-axiom
>@@ -0,0 +1,81 @@
>+What:		/sys/bus/i2c/devices/xxx/fw_major
>+Date:		Jan 2026
>+Contact:	linux-input@vger.kernel.org
>+Description:
>+		Reports the firmware major version provided by the touchscreen.
>+
>+		Access: Read
>+
>+		Valid values: Represented as string
>+
>+What:		/sys/bus/i2c/devices/xxx/fw_minor
>+Date:		Jan 2026
>+Contact:	linux-input@vger.kernel.org
>+Description:
>+		Reports the firmware minor version provided by the touchscreen.
>+
>+		Access: Read
>+
>+		Valid values: Represented as string
>+
>+What:		/sys/bus/i2c/devices/xxx/fw_rc
>+Date:		Jan 2026
>+Contact:	linux-input@vger.kernel.org
>+Description:
>+		Reports the firmware release canidate version provided by the touchscreen.
>+
>+		Access: Read
>+
>+		Valid values: Represented as string
>+
>+What:		/sys/bus/i2c/devices/xxx/fw_status
>+Date:		Jan 2026
>+Contact:	linux-input@vger.kernel.org
>+Description:
>+		Reports the firmware status provided by the touchscreen. It may
>+		be either "release" or "engineering".
>+
>+		Access: Read
>+
>+		Valid values: Represented as string
>+
>+What:		/sys/bus/i2c/devices/xxx/fw_variant
>+Date:		Jan 2026
>+Contact:	linux-input@vger.kernel.org
>+Description:
>+		Reports the firmware variant provided by the touchscreen. It may
>+		be either: "3d", "2d", "force" or "unknown".
>+
>+		Access: Read
>+
>+		Valid values: Represented as string
>+
>+What:		/sys/bus/i2c/devices/xxx/device_id
>+Date:		Jan 2026
>+Contact:	linux-input@vger.kernel.org
>+Description:
>+		Reports the touchscreen device id, for example: "54" for the AX54A.
>+
>+		Access: Read
>+
>+		Valid values: Represented as string
>+
>+What:		/sys/bus/i2c/devices/xxx/device_state
>+Date:		Jan 2026
>+Contact:	linux-input@vger.kernel.org
>+Description:
>+		Reports the touchscreen device current runtime state. The
>+		following values are reported:
>+
>+		discovery: Device is in discovery mode.
>+		tcp:  Device is in touch-control-protocol (tcp) mode. This is
>+		      the normal working mode.
>+		th2cfg-update: Device is in configuration update mode.
>+		bootloader-pre: Device bootloader mode enter was triggered
>+		bootloader: Device is in bootloader mode, used for firmware
>+			    updates.
>+		unknown: Device mode is unknown.
>+
>+		Access: Read
>+
>+		Valid values: Represented as string
>diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
>index 7d5b72ee07fa1313da39a625b5129a0459720865..449ae5e29cb4bb1f5335afdee82e91f0aa30a209 100644
>--- a/drivers/input/touchscreen/Kconfig
>+++ b/drivers/input/touchscreen/Kconfig
>@@ -828,6 +828,23 @@ 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"
>+	# We need to call into panel code so if DRM=m, this can't be 'y'
>+	depends on DRM || !DRM
>+	depends on I2C
>+	select CRC16
>+	select CRC32
>+	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 touchnetix_axiom.
>+
> config TOUCHSCREEN_TOUCHRIGHT
> 	tristate "Touchright serial touchscreen"
> 	select SERIO
>diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
>index ab9abd151078831a4b22d6998e00ef74fe01c356..540df3ada4b2b6ad05ffeba67f44ff262f93c11f 100644
>--- a/drivers/input/touchscreen/Makefile
>+++ b/drivers/input/touchscreen/Makefile
>@@ -90,6 +90,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 0000000000000000000000000000000000000000..e8f56a8f7e8a83361b04bb858caadf9658fb7e05
>--- /dev/null
>+++ b/drivers/input/touchscreen/touchnetix_axiom.c
>@@ -0,0 +1,2974 @@
>+// SPDX-License-Identifier: GPL-2.0-only
>+/*
>+ * TouchNetix aXiom Touchscreen Driver
>+ *
>+ * Copyright (C) 2024 Pengutronix
>+ *
>+ * Marco Felsch <kernel@pengutronix.de>
>+ */
>+
>+#include <drm/drm_panel.h>
>+#include <linux/bitfield.h>
>+#include <linux/bits.h>
>+#include <linux/completion.h>
>+#include <linux/crc16.h>
>+#include <linux/crc32.h>
>+#include <linux/delay.h>
>+#include <linux/device.h>
>+#include <linux/firmware.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/pm_runtime.h>
>+#include <linux/property.h>
>+#include <linux/regmap.h>
>+#include <linux/regulator/consumer.h>
>+#include <linux/time.h>
>+#include <linux/unaligned.h>
>+
>+/*
>+ * Short introduction for developers:
>+ *  The programming manual is written based on u(sages):
>+ *   - Max. 0xff usages possible
>+ *   - A usage is a group of registers (0x00 ... 0xff)
>+ *   - The usage base address must be discovered (FW dependent)
>+ *   - Partial RW usage access is allowed
>+ *   - Each usage has a revision (FW dependent)
>+ *   - Only u31 is always at address 0x0 (used for discovery)
>+ *
>+ *  E.x. Reading register 0x01 for usage u03 with baseaddr 0x20 results in the
>+ *  following physical 16bit I2C address: 0x2001.
>+ *
>+ * Note the datasheet specifies the usage numbers in hex and the internal
>+ * offsets in decimal. Keep it that way to make it more developer friendly.
>+ */
>+#define AXIOM_U01				0x01
>+#define AXIOM_U01_REV1_REPORTTYPE_REG		0
>+#define   AXIOM_U01_REV1_REPORTTYPE_HELLO	0
>+#define   AXIOM_U01_REV1_REPORTTYPE_HEARTBEAT	1
>+#define   AXIOM_U01_REV1_REPORTTYPE_OPCOMPLETE	3
>+
>+#define AXIOM_U02					0x02
>+#define AXIOM_U02_REV1_COMMAND_REG			0
>+#define   AXIOM_U02_REV1_CMD_HARDRESET			0x0001
>+#define   AXIOM_U02_REV1_CMD_SOFTRESET			0x0002
>+#define   AXIOM_U02_REV1_CMD_STOP			0x0005
>+#define   AXIOM_U02_REV1_CMD_SAVEVLTLCFG2NVM		0x0007
>+#define   AXIOM_U02_REV1_PARAM1_SAVEVLTLCFG2NVM		0xb10c
>+#define   AXIOM_U02_REV1_PARAM2_SAVEVLTLCFG2NVM		0xc0de
>+#define   AXIOM_U02_REV1_CMD_HANDSHAKENVM		0x0008
>+#define   AXIOM_U02_REV1_CMD_COMPUTECRCS		0x0009
>+#define   AXIOM_U02_REV1_CMD_FILLCONFIG			0x000a
>+#define   AXIOM_U02_REV1_PARAM0_FILLCONFIG		0x5555
>+#define   AXIOM_U02_REV1_PARAM1_FILLCONFIG		0xaaaa
>+#define   AXIOM_U02_REV1_PARAM2_FILLCONFIG_ZERO		0xa55a
>+#define   AXIOM_U02_REV1_CMD_ENTERBOOTLOADER		0x000b
>+#define   AXIOM_U02_REV1_PARAM0_ENTERBOOLOADER_KEY1	0x5555
>+#define   AXIOM_U02_REV1_PARAM0_ENTERBOOLOADER_KEY2	0xaaaa
>+#define   AXIOM_U02_REV1_PARAM0_ENTERBOOLOADER_KEY3	0xa55a
>+#define   AXIOM_U02_REV1_RESP_SUCCESS			0x0000
>+
>+struct axiom_u02_rev1_system_manager_msg {
>+	union {
>+		__le16 command;
>+		__le16 response;
>+	};
>+	__le16 parameters[3];
>+};
>+
>+#define AXIOM_U04				0x04
>+#define   AXIOM_U04_REV1_SIZE_BYTES		128
>+
>+#define AXIOM_U05				0x05	/* CDU */
>+
>+#define AXIOM_U22				0x22	/* CDU */
>+
>+#define AXIOM_U31				0x31
>+#define AXIOM_U31_REV1_PAGE0			0x0000
>+#define AXIOM_U31_REV1_DEVICE_ID_LOW_REG	(AXIOM_U31_REV1_PAGE0 + 0)
>+#define AXIOM_U31_REV1_DEVICE_ID_HIGH_REG	(AXIOM_U31_REV1_PAGE0 + 1)
>+#define   AXIOM_U31_REV1_MODE_MASK		BIT(7)
>+#define   AXIOM_U31_REV1_MODE_BLP		1
>+#define   AXIOM_U31_REV1_DEVICE_ID_HIGH_MASK	GENMASK(6, 0)
>+#define AXIOM_U31_REV1_RUNTIME_FW_MIN_REG	(AXIOM_U31_REV1_PAGE0 + 2)
>+#define AXIOM_U31_REV1_RUNTIME_FW_MAJ_REG	(AXIOM_U31_REV1_PAGE0 + 3)
>+#define AXIOM_U31_REV1_RUNTIME_FW_STATUS_REG	(AXIOM_U31_REV1_PAGE0 + 4)
>+#define   AXIOM_U31_REV1_RUNTIME_FW_STATUS	BIT(7)
>+#define   AXIOM_U31_REV1_RUNTIME_FW_VARIANT	GENMASK(6, 0)
>+#define AXIOM_U31_REV1_JEDEC_ID_LOW_REG		(AXIOM_U31_REV1_PAGE0 + 8)
>+#define AXIOM_U31_REV1_JEDEC_ID_HIGH_REG	(AXIOM_U31_REV1_PAGE0 + 9)
>+#define AXIOM_U31_REV1_NUM_USAGES_REG		(AXIOM_U31_REV1_PAGE0 + 10)
>+#define AXIOM_U31_REV1_RUNTIME_FW_RC_REG	(AXIOM_U31_REV1_PAGE0 + 11)
>+#define   AXIOM_U31_REV1_RUNTIME_FW_RC_MASK	GENMASK(7, 4)
>+#define   AXIOM_U31_REV1_SILICON_REV_MASK	GENMASK(3, 0)
>+
>+#define AXIOM_U31_REV1_PAGE1			0x0100
>+#define   AXIOM_U31_REV1_OFFSET_TYPE_MASK	BIT(7)
>+#define   AXIOM_U31_REV1_MAX_OFFSET_MASK	GENMASK(6, 0)
>+
>+#define AXIOM_U32				0x32
>+
>+struct axiom_u31_usage_table_entry {
>+	u8 usage_num;
>+	u8 start_page;
>+	u8 num_pages;
>+	u8 max_offset;
>+	u8 uifrevision;
>+	u8 reserved;
>+} __packed;
>+
>+#define AXIOM_U33				0x33
>+
>+struct axiom_u33_rev2 {
>+	__le32 runtime_crc;
>+	__le32 runtime_nvm_crc;
>+	__le32 bootloader_crc;
>+	__le32 nvltlusageconfig_crc;
>+	__le32 vltusageconfig_crc;
>+	__le32 u22_sequencedata_crc;
>+	__le32 u43_hotspots_crc;
>+	__le32 u93_profiles_crc;
>+	__le32 u94_deltascalemap_crc;
>+	__le32 runtimehash_crc;
>+};
>+
>+struct axiom_u33_rev3 {
>+	__le32 runtime_crc;
>+	__le32 runtime_nvm_crc;
>+	__le32 bootloader_crc;
>+	__le32 nvltlusageconfig_crc;
>+	__le32 vltusageconfig_crc;
>+	__le32 u22_sequencedata_crc;
>+	__le32 u43_hotspots_crc;
>+	__le32 u77_dod_data_crc;
>+	__le32 u93_profiles_crc;
>+	__le32 u94_deltascalemap_crc;
>+	__le32 runtimehash_crc;
>+};
>+

I think revision handling should be kept in unpacking where possible.
Currently there are 10 revisions of u33, so adding support for many
revisions and usages would add alot of code.

>+#define AXIOM_U34				0x34
>+#define   AXIOM_U34_REV1_OVERFLOW_MASK		BIT(7)
>+#define   AXIOM_U34_REV1_REPORTLENGTH_MASK	GENMASK(6, 0)
>+#define   AXIOM_U34_REV1_PREAMBLE_BYTES		2
>+#define   AXIOM_U34_REV1_POSTAMBLE_BYTES	4
>+
>+#define AXIOM_U36				0x36
>+
>+#define AXIOM_U41				0x41
>+#define AXIOM_U41_REV2_TARGETSTATUS_REG		0
>+#define AXIOM_U41_REV2_X_REG(id)		((4 * (id)) + 2)
>+#define AXIOM_U41_REV2_Y_REG(id)		((4 * (id)) + 4)
>+#define AXIOM_U41_REV2_Z_REG(id)		((id) + 42)
>+
>+#define AXIOM_U42				0x42
>+#define AXIOM_U42_REV1_REPORT_ID_CONTAINS(id)	((id) + 2)
>+#define   AXIOM_U42_REV1_REPORT_ID_TOUCH	1	/* Touch, Proximity, Hover */
>+
>+#define AXIOM_U42_REV4_REPORT_ID_CONTAINS(id)   ((id) + 8)
>+#define   AXIOM_U42_REV4_REPORT_ID_TOUCH	1	/* Touch, Proximity, Hover */
>+
>+#define AXIOM_U43				0x43	/* CDU */
>+
>+#define AXIOM_U64					0x64
>+#define   AXIOM_U64_REV2_ENABLECDSPROCESSING_REG	0
>+#define   AXIOM_U64_REV2_ENABLECDSPROCESSING_MASK	BIT(0)
>+
>+#define AXIOM_U77				0x77	/* CDU */
>+#define AXIOM_U82				0x82
>+#define AXIOM_U93				0x93	/* CDU */
>+#define AXIOM_U94				0x94	/* CDU */
>+
>+/*
>+ * Axiom CDU usage structure copied from downstream CDU_Common.py. Downstream
>+ * doesn't mention any revision. According downstream all CDU register windows
>+ * are 56 byte wide (8 byte header + 48 byte data).
>+ */
>+#define AXIOM_CDU_CMD_STORE			0x0002
>+#define AXIOM_CDU_CMD_COMMIT			0x0003
>+#define AXIOM_CDU_PARAM0_COMMIT			0xb10c
>+#define AXIOM_CDU_PARAM1_COMMIT			0xc0de
>+
>+#define AXIOM_CDU_RESP_SUCCESS			0x0000
>+#define AXIOM_CDU_MAX_DATA_BYTES		48
>+
>+struct axiom_cdu_usage {
>+	union {
>+		__le16 command;
>+		__le16 response;
>+	};
>+	__le16 parameters[3];
>+	u8 data[AXIOM_CDU_MAX_DATA_BYTES];
>+};
>+
>+/*
>+ * u01 for the bootloader protocol (BLP)
>+ *
>+ * Values taken from http://Bootloader.py [1] which had a comment that documentation
>+ * values are out dated. The BLP does not have different versions according the
>+ * documentation python helper.
>+ *
>+ * [1] https://github.com/TouchNetix/axiom_pylib
>+ */
>+#define AXIOM_U01_BLP_COMMAND_REG		0x0100
>+#define   AXIOM_U01_BLP_COMMAND_RESET		BIT(1)
>+#define AXIOM_U01_BLP_SATUS_REG			0x0100
>+#define   AXIOM_U01_BLP_STATUS_BUSY		BIT(0)
>+#define AXIOM_U01_BLP_FIFO_REG			0x0102
>+#define   AXIOM_U01_BLP_FIFO_CHK_SIZE_BYTES	255
>+
>+#define AXIOM_PROX_LEVEL			-128
>+#define AXIOM_STARTUP_TIME_MS			110
>+
>+#define AXIOM_USAGE_BASEADDR_MASK		GENMASK(15, 8)
>+#define AXIOM_MAX_USAGES			256	/* u00 - uFF */
>+/*
>+ * The devices have a 16bit ADC but Touchnetix used the lower two bits for other
>+ * information.
>+ */
>+#define AXIOM_MAX_XY				(65535 - 3)
>+#define AXIOM_DEFAULT_POLL_INTERVAL_MS		10
>+#define AXIOM_PAGE_BYTE_LEN			256
>+#define AXIOM_MAX_XFERLEN			0x7fff
>+#define AXIOM_MAX_TOUCHSLOTS			10
>+#define AXIOM_MAX_TOUCHSLOTS_MASK		GENMASK(9, 0)
>+
>+/* aXiom firmware (.axfw) */
>+#define AXIOM_FW_AXFW_SIGNATURE			"AXFW"
>+#define AXIOM_FW_AXFW_FILE_FMT_VER		0x0200
>+
>+struct axiom_fw_axfw_hdr {
>+	u8 signature[4];
>+	__le32 file_crc32;
>+	__le16 file_format_ver;
>+	__le16 device_id;
>+	u8 variant;
>+	u8 minor_ver;
>+	u8 major_ver;
>+	u8 rc_ver;
>+	u8 status;
>+	__le16 silicon_ver;
>+	u8 silicon_rev;
>+	__le32 fw_crc32;
>+} __packed;
>+
>+struct axiom_fw_axfw_chunk_hdr {
>+	u8 internal[6]; /* no description */
>+	__be16 payload_length;
>+};
>+
>+/* aXiom config (.th2cfgbin) */
>+#define AXIOM_FW_CFG_SIGNATURE			0x20071969
>+
>+struct axiom_fw_cfg_hdr {
>+	__be32 signature;
>+	__le16 file_format_ver;
>+	__le16 tcp_file_rev_major;
>+	__le16 tcp_file_rev_minor;
>+	__le16 tcp_file_rev_patch;
>+	u8 tcp_version;
>+} __packed;
>+
>+struct axiom_fw_cfg_chunk_hdr {
>+	u8 usage_num;
>+	u8 usage_rev;
>+	u8 reserved;
>+	__le16 usage_length;
>+} __packed;
>+
>+struct axiom_fw_cfg_chunk {
>+	u8 usage_num;
>+	u8 usage_rev;
>+	u16 usage_length;
>+	const u8 *usage_content;
>+};
>+
>+enum axiom_fw_type {
>+	AXIOM_FW_AXFW,
>+	AXIOM_FW_CFG,
>+	AXIOM_FW_NUM
>+};
>+
>+enum axiom_crc_type {
>+	AXIOM_CRC_CUR,
>+	AXIOM_CRC_NEW,
>+	AXIOM_CRC_NUM
>+};
>+
>+struct axiom_data;
>+
>+struct axiom_usage_info {
>+	unsigned char usage_num;	/* uXX number (XX in hex) */
>+	unsigned int rev_num;		/* rev.X (X in dec) */
>+	bool is_cdu;
>+	bool is_ro;
>+
>+	/* Optional hooks */
>+	int (*process_report)(struct axiom_data *ts, const u8 *buf, size_t bufsize);
>+};
>+
>+enum axiom_runmode {
>+	AXIOM_DISCOVERY_MODE,
>+	AXIOM_TCP_MODE,
>+	AXIOM_TCP_CFG_UPDATE_MODE,
>+	AXIOM_BLP_PRE_MODE,
>+	AXIOM_BLP_MODE,
>+};

There are only two actual axiom states, bootloader and runtime (TCP).
This is more of a driver state rather than an axiom state.
Could you label it as such? 

>+
>+struct axiom_data {
>+	struct input_dev *input;
>+	struct device *dev;
>+
>+	struct gpio_desc *reset_gpio;
>+	struct regulator_bulk_data supplies[2];
>+	unsigned int num_supplies;
>+
>+	struct regmap *regmap;
>+	struct touchscreen_properties prop;
>+	bool irq_setup_done;
>+	u32 poll_interval;
>+
>+	struct drm_panel_follower panel_follower;
>+	bool is_panel_follower;
>+
>+	enum axiom_runmode mode;
>+	/*
>+	 * Two completion types to support firmware updates
>+	 * in irq and poll mode.
>+	 */
>+	struct axiom_completion {
>+		struct completion completion;
>+		bool poll_done;
>+	} nvm_write, boot_complete;
>+
>+	/* Lock to protect both firmware interfaces */
>+	struct mutex fwupdate_lock;
>+	struct axiom_firmware {
>+		/* Lock to protect cancel */
>+		struct mutex lock;
>+		bool cancel;
>+		struct fw_upload *fwl;
>+	} fw[AXIOM_FW_NUM];
>+
>+	unsigned int fw_major;
>+	unsigned int fw_minor;
>+	unsigned int fw_rc;
>+	unsigned int fw_status;
>+	unsigned int fw_variant;
>+	u16 device_id;
>+	u16 jedec_id;
>+	u8 silicon_rev;
>+
>+	/* CRCs we need to check during a config update */
>+	struct axiom_crc {
>+		u32 runtime;
>+		u32 vltusageconfig;
>+		u32 nvltlusageconfig;
>+		u32 u22_sequencedata;
>+		u32 u43_hotspots;
>+		u32 u77_dod_data;
>+		u32 u93_profiles;
>+		u32 u94_deltascalemap;
>+	} crc[AXIOM_CRC_NUM];

I think this structure should hold all possible u33 CRCs and then invalid ones
can be ignored for the given u33 revision.

>+
>+	bool cds_enabled;
>+	unsigned long enabled_slots;
>+	unsigned int num_slots;
>+
>+	unsigned int max_report_byte_len;
>+	struct axiom_usage_table_entry {
>+		bool populated;
>+		unsigned int baseaddr;
>+		unsigned int size_bytes;
>+		const struct axiom_usage_info *info;
>+	} usage_table[AXIOM_MAX_USAGES];
>+};
>+
>+static int axiom_u01_rev1_process_report(struct axiom_data *ts, const u8 *buf,
>+					 size_t bufsize);
>+static int axiom_u34_rev1_process_report(struct axiom_data *ts, const u8 *_buf,
>+					 size_t bufsize);
>+static int axiom_u41_rev2_process_report(struct axiom_data *ts, const u8 *buf,
>+					 size_t bufsize);
>+
>+#define AXIOM_USAGE(num, rev)		\
>+	{				\
>+		.usage_num = num,	\
>+		.rev_num = rev,		\
>+	}
>+
>+#define AXIOM_RO_USAGE(num, rev)	\
>+	{				\
>+		.usage_num = num,	\
>+		.rev_num = rev,		\
>+		.is_ro = true,		\
>+	}
>+
>+#define AXIOM_CDU_USAGE(num, rev)	\
>+	{				\
>+		.usage_num = num,	\
>+		.rev_num = rev,		\
>+		.is_cdu = true,		\
>+	}
>+
>+#define AXIOM_REPORT_USAGE(num, rev, func)	\
>+	{					\
>+		.usage_num = num,		\
>+		.rev_num = rev,			\
>+		.process_report = func,		\
>+	}
>+
>+#define AXIOM_USAGE_REV_UNUSED	(-1)
>+
>+/*
>+ * All usages used by driver must be added to this list to ensure the correct
>+ * communictation with the devices. The list can contain multiple entries of the
>+ * same usage to handle different usage revisions.
>+ *
>+ * Note:
>+ * During a th2cfgbin update the driver may use usages not listed here.
>+ * Therefore the th2cfgbin update compares the current running FW again the
>+ * th2cfgbin targets FW.
>+ */
>+static const struct axiom_usage_info driver_required_usages[] = {
>+	AXIOM_REPORT_USAGE(AXIOM_U01, 1, axiom_u01_rev1_process_report),
>+	AXIOM_REPORT_USAGE(AXIOM_U01, 3, axiom_u01_rev1_process_report),
>+	AXIOM_USAGE(AXIOM_U02, 1),
>+	AXIOM_USAGE(AXIOM_U02, 2),
>+	AXIOM_USAGE(AXIOM_U04, 1),
>+	AXIOM_RO_USAGE(AXIOM_U33, 2),
>+	AXIOM_RO_USAGE(AXIOM_U33, 3),
>+	AXIOM_REPORT_USAGE(AXIOM_U34, 1, axiom_u34_rev1_process_report),
>+	AXIOM_REPORT_USAGE(AXIOM_U41, 2, axiom_u41_rev2_process_report),
>+	AXIOM_REPORT_USAGE(AXIOM_U41, 4, axiom_u41_rev2_process_report),
>+	AXIOM_USAGE(AXIOM_U42, 1),
>+	AXIOM_USAGE(AXIOM_U42, 4),
>+	AXIOM_USAGE(AXIOM_U64, 2),
>+	AXIOM_USAGE(AXIOM_U64, 4),
>+	{ /* sentinel */ }
>+};
>+
>+/*
>+ * All usages below are unused but the driver needs to know the type (ro, cdu)
>+ * to handle them correctly. Unfortunately the type is not discoverable. Once
>+ * a usage is actually used, it must be shifted to driver_required_usages and
>+ * the revision must be set accordingly.
>+ */
>+static const struct axiom_usage_info driver_additional_usages[] = {
>+	AXIOM_CDU_USAGE(AXIOM_U05, AXIOM_USAGE_REV_UNUSED),
>+	AXIOM_CDU_USAGE(AXIOM_U22, AXIOM_USAGE_REV_UNUSED),
>+	AXIOM_RO_USAGE(AXIOM_U31, AXIOM_USAGE_REV_UNUSED),
>+	AXIOM_RO_USAGE(AXIOM_U32, AXIOM_USAGE_REV_UNUSED),
>+	AXIOM_RO_USAGE(AXIOM_U36, AXIOM_USAGE_REV_UNUSED),
>+	AXIOM_CDU_USAGE(AXIOM_U43, AXIOM_USAGE_REV_UNUSED),
>+	AXIOM_CDU_USAGE(AXIOM_U77, AXIOM_USAGE_REV_UNUSED),
>+	AXIOM_RO_USAGE(AXIOM_U82, AXIOM_USAGE_REV_UNUSED),
>+	AXIOM_CDU_USAGE(AXIOM_U93, AXIOM_USAGE_REV_UNUSED),
>+	AXIOM_CDU_USAGE(AXIOM_U94, AXIOM_USAGE_REV_UNUSED),
>+	{ /* sentinel */ }
>+};
>+
>+/************************ Common helpers **************************************/
>+
>+static void axiom_set_runmode(struct axiom_data *ts, enum axiom_runmode mode)
>+{
>+	ts->mode = mode;
>+}
>+
>+static enum axiom_runmode axiom_get_runmode(struct axiom_data *ts)
>+{
>+	return ts->mode;
>+}
>+
>+static const char *axiom_runmode_to_string(struct axiom_data *ts)
>+{
>+	switch (ts->mode) {
>+	case AXIOM_DISCOVERY_MODE:	return "discovery";
>+	case AXIOM_TCP_MODE:		return "tcp";
>+	case AXIOM_TCP_CFG_UPDATE_MODE:	return "th2cfg-update";
>+	case AXIOM_BLP_PRE_MODE:	return "bootloader-pre";
>+	case AXIOM_BLP_MODE:		return "bootlaoder";
>+	default:			return "unknown";
>+	}
>+}
>+
>+static bool axiom_skip_usage_check(struct axiom_data *ts)
>+{
>+	switch (ts->mode) {
>+	case AXIOM_TCP_CFG_UPDATE_MODE:
>+	case AXIOM_DISCOVERY_MODE:
>+	case AXIOM_BLP_MODE:
>+		return true;
>+	case AXIOM_BLP_PRE_MODE:
>+	case AXIOM_TCP_MODE:
>+	default:
>+		return false;
>+	}
>+}
>+
>+static unsigned int
>+axiom_usage_baseaddr(struct axiom_data *ts, unsigned char usage_num)
>+{
>+	return ts->usage_table[usage_num].baseaddr;
>+}
>+
>+static unsigned int
>+axiom_usage_size(struct axiom_data *ts, unsigned char usage_num)
>+{
>+	return ts->usage_table[usage_num].size_bytes;
>+}
>+
>+static int
>+axiom_usage_rev(struct axiom_data *ts, unsigned char usage_num)
>+{
>+	struct axiom_usage_table_entry *entry = &ts->usage_table[usage_num];
>+
>+	if (!entry->info)
>+		return -EINVAL;
>+
>+	return entry->info->rev_num;
>+}
>+
>+static bool
>+axiom_driver_supports_usage(struct axiom_data *ts, unsigned char usage_num)
>+{
>+	const struct axiom_usage_info *iter = driver_required_usages;
>+	struct device *dev = ts->dev;
>+	int rev;
>+
>+	/*
>+	 * Some features depend on the current running firmware. Don't print an
>+	 * error if the usage for an optional feature is missing.
>+	 */
>+	if (!ts->usage_table[usage_num].populated) {
>+		dev_dbg(dev, "u%02X is not supported by the current firmware\n",
>+			usage_num);
>+		return false;
>+	}
>+
>+	rev = axiom_usage_rev(ts, usage_num);
>+	if (rev < 0) {
>+		dev_warn(dev, "Driver doesn't support u%02X yet\n", usage_num);
>+		return false;
>+	}
>+
>+	for (; iter; iter++) {
>+		if (iter->usage_num != usage_num)
>+			continue;
>+
>+		if (iter->rev_num == rev)
>+			return true;
>+	}
>+
>+	dev_warn(dev, "Driver doesn't support u%02X rev.%d yet\n",
>+		 usage_num, rev);
>+
>+	return false;
>+}
>+
>+static bool
>+axiom_usage_entry_is_report(struct axiom_u31_usage_table_entry *entry)
>+{
>+	return entry->num_pages == 0;
>+}
>+
>+static unsigned int
>+axiom_get_usage_size_bytes(struct axiom_u31_usage_table_entry *entry)
>+{
>+	unsigned char max_offset;
>+
>+	max_offset = FIELD_GET(AXIOM_U31_REV1_MAX_OFFSET_MASK,
>+			       entry->max_offset) + 1;
>+	max_offset *= 2;
>+
>+	if (axiom_usage_entry_is_report(entry))
>+		return max_offset;
>+
>+	if (FIELD_GET(AXIOM_U31_REV1_OFFSET_TYPE_MASK, entry->max_offset))
>+		return (entry->num_pages - 1) * AXIOM_PAGE_BYTE_LEN + max_offset;
>+
>+	return max_offset;
>+}
>+
>+static void axiom_dump_usage_entry(struct device *dev,
>+				   struct axiom_u31_usage_table_entry *entry)
>+{
>+	unsigned int page_len, total_len;
>+
>+	total_len = axiom_get_usage_size_bytes(entry);
>+
>+	if (total_len > AXIOM_PAGE_BYTE_LEN)
>+		page_len = AXIOM_PAGE_BYTE_LEN;
>+	else
>+		page_len = total_len;
>+
>+	if (axiom_usage_entry_is_report(entry))
>+		dev_dbg(dev,
>+			"u%02X rev.%d total-len:%u [REPORT]\n",
>+			entry->usage_num, entry->uifrevision, total_len);
>+	else
>+		dev_dbg(dev,
>+			"u%02X rev.%d first-page:%#02x page-len:%u num-pages:%u total-len:%u\n",
>+			entry->usage_num, entry->uifrevision, entry->start_page, page_len,
>+			entry->num_pages, total_len);
>+}
>+
>+static const struct axiom_usage_info *
>+axiom_get_usage_info(struct axiom_u31_usage_table_entry *query)
>+{
>+	const struct axiom_usage_info *info = driver_required_usages;
>+	bool required = false;
>+	bool found = false;
>+
>+	for (; info->usage_num; info++) {
>+		/* Skip all usages not used by the driver */
>+		if (query->usage_num != info->usage_num)
>+			continue;
>+
>+		/* The usage is used so we need to mark it as required */
>+		required = true;
>+
>+		/* Continue with the next usage if the revision doesn't match */
>+		if (query->uifrevision != info->rev_num)
>+			continue;
>+
>+		found = true;
>+		break;
>+	}
>+
>+	if (found)
>+		return info;
>+
>+	/* Return an error if not found but required */
>+	if (required)
>+		return ERR_PTR(-EINVAL);
>+
>+	info = driver_additional_usages;
>+	for (; info->usage_num; info++) {
>+		if (query->usage_num != info->usage_num)
>+			continue;
>+
>+		/*
>+		 * No need to check the revision since these usages are not
>+		 * used actually but the driver needs the type information.
>+		 */
>+		return info;
>+	}
>+
>+	/* No info found */
>+	return NULL;
>+}
>+
>+static bool axiom_usage_supported(struct axiom_data *ts, unsigned int baseaddr)
>+{
>+	struct axiom_usage_table_entry *entry;
>+	unsigned int i;
>+
>+	if (axiom_skip_usage_check(ts))
>+		return true;
>+
>+	dev_dbg(ts->dev, "Checking support for baseaddr: %#x\n", baseaddr);
>+
>+	for (i = 0; i < ARRAY_SIZE(ts->usage_table); i++) {
>+		entry = &ts->usage_table[i];
>+
>+		if (!entry->populated)
>+			continue;
>+
>+		if (entry->baseaddr != baseaddr)
>+			continue;
>+
>+		break;
>+	}
>+
>+	if (i == ARRAY_SIZE(ts->usage_table)) {
>+		dev_warn(ts->dev, "Usage not found\n");
>+		return false;
>+	}
>+
>+	if (!entry->info)
>+		dev_warn(ts->dev, "Unsupported usage u%02X used, driver bug!", i);
>+
>+	return !!entry->info;
>+}
>+
>+static void axiom_poll(struct input_dev *input);
>+
>+static unsigned long
>+axiom_wait_for_completion_timeout(struct axiom_data *ts, struct axiom_completion *x,
>+				  long timeout)
>+{
>+	struct i2c_client *client = to_i2c_client(ts->dev);
>+	unsigned long poll_timeout;
>+
>+	if (client->irq)
>+		return wait_for_completion_timeout(&x->completion, timeout);
>+
>+	/*
>+	 * Only firmware update cases do wait for completion. Since they require
>+	 * the input device to be closed, the poller is not running. So we need
>+	 * to do the polling manually.
>+	 */
>+	poll_timeout = timeout / 10;
>+
>+	/*
>+	 * Very basic and not very accurate but it does the job because there
>+	 * are no known timeout constraints.
>+	 */
>+	do {
>+		axiom_poll(ts->input);
>+		fsleep(jiffies_to_usecs(poll_timeout));
>+		if (x->poll_done)
>+			break;
>+		timeout -= poll_timeout;
>+	} while (timeout > 0);
>+
>+	x->poll_done = false;
>+
>+	return timeout > 0 ? timeout : 0;
>+}
>+
>+static void axiom_complete(struct axiom_data *ts, struct axiom_completion *x)
>+{
>+	struct i2c_client *client = to_i2c_client(ts->dev);
>+
>+	if (client->irq)
>+		complete(&x->completion);
>+	else
>+		x->poll_done = true;
>+}
>+
>+/*************************** Usage handling ***********************************/
>+/*
>+ * Wrapper functions to handle the usage access. Wrappers are used to add
>+ * different revision handling later on more easily.
>+ */
>+static int axiom_u02_wait_idle(struct axiom_data *ts)
>+{
>+	unsigned int reg;
>+	int ret, _ret;
>+	u16 cmd;
>+
>+	if (!axiom_driver_supports_usage(ts, AXIOM_U02))
>+		return -EINVAL;
>+
>+	reg = axiom_usage_baseaddr(ts, AXIOM_U02);
>+	reg += AXIOM_U02_REV1_COMMAND_REG;
>+
>+	/*
>+	 * Missing regmap_raw_read_poll_timeout for now. RESP_SUCCESS means that
>+	 * the last command successfully completed and the device is idle.
>+	 */
>+	ret = read_poll_timeout(regmap_raw_read, _ret,
>+				_ret || cmd == AXIOM_U02_REV1_RESP_SUCCESS,
>+				10 * USEC_PER_MSEC, 1 * USEC_PER_SEC, false,
>+				ts->regmap, reg, &cmd, 2);
>+	if (ret)
>+		dev_err(ts->dev, "Poll u02 timedout with: %#x\n", cmd);
>+
>+	return ret;
>+}
>+
>+static int
>+axiom_u02_send_msg(struct axiom_data *ts,
>+		   const struct axiom_u02_rev1_system_manager_msg *msg,
>+		   bool validate_response)
>+{
>+	unsigned int reg;
>+	int ret;
>+
>+	if (!axiom_driver_supports_usage(ts, AXIOM_U02))
>+		return -EINVAL;
>+
>+	reg = axiom_usage_baseaddr(ts, AXIOM_U02);
>+	reg += AXIOM_U02_REV1_COMMAND_REG;
>+
>+	ret = regmap_raw_write(ts->regmap, reg, msg, sizeof(*msg));
>+	if (ret)
>+		return ret;
>+
>+	if (!validate_response)
>+		return 0;
>+
>+	return axiom_u02_wait_idle(ts);
>+}
>+
>+static int
>+axiom_u02_rev1_send_single_cmd(struct axiom_data *ts, u16 cmd)
>+{
>+	struct axiom_u02_rev1_system_manager_msg msg = {
>+		.command = cpu_to_le16(cmd)
>+	};
>+
>+	return axiom_u02_send_msg(ts, &msg, true);
>+}
>+
>+static int axiom_u02_handshakenvm(struct axiom_data *ts)
>+{
>+	return axiom_u02_rev1_send_single_cmd(ts, AXIOM_U02_REV1_CMD_HANDSHAKENVM);
>+}
>+
>+static int axiom_u02_computecrc(struct axiom_data *ts)
>+{
>+	return axiom_u02_rev1_send_single_cmd(ts, AXIOM_U02_REV1_CMD_COMPUTECRCS);
>+}
>+
>+static int axiom_u02_stop(struct axiom_data *ts)
>+{
>+	return axiom_u02_rev1_send_single_cmd(ts, AXIOM_U02_REV1_CMD_STOP);
>+}
>+
>+static int axiom_u02_save_config(struct axiom_data *ts)
>+{
>+	struct axiom_u02_rev1_system_manager_msg msg;
>+	int ret;
>+
>+	if (!axiom_driver_supports_usage(ts, AXIOM_U02))
>+		return -EINVAL;
>+
>+	msg.command = cpu_to_le16(AXIOM_U02_REV1_CMD_SAVEVLTLCFG2NVM);
>+	msg.parameters[0] = 0; /* Don't care */
>+	msg.parameters[1] = cpu_to_le16(AXIOM_U02_REV1_PARAM1_SAVEVLTLCFG2NVM);
>+	msg.parameters[2] = cpu_to_le16(AXIOM_U02_REV1_PARAM2_SAVEVLTLCFG2NVM);
>+
>+	ret = axiom_u02_send_msg(ts, &msg, false);
>+	if (ret)
>+		return ret;
>+
>+	/* Downstream http://axcfg.py waits for 2sec without checking U01 response */
>+	ret = axiom_wait_for_completion_timeout(ts, &ts->nvm_write,
>+					msecs_to_jiffies(2 * MSEC_PER_SEC));
>+	if (!ret)
>+		dev_err(ts->dev, "Error save volatile config timedout\n");
>+
>+	return ret ? 0 : -ETIMEDOUT;
>+}
>+
>+static int axiom_u02_swreset(struct axiom_data *ts)
>+{
>+	struct axiom_u02_rev1_system_manager_msg msg = { };
>+	int ret;
>+
>+	if (!axiom_driver_supports_usage(ts, AXIOM_U02))
>+		return -EINVAL;
>+
>+	msg.command = cpu_to_le16(AXIOM_U02_REV1_CMD_SOFTRESET);
>+	ret = axiom_u02_send_msg(ts, &msg, false);
>+	if (ret)
>+		return ret;
>+
>+	/*
>+	 * Downstream http://axcfg.py waits for 1sec without checking U01 hello. Tests
>+	 * showed that waiting for the hello message isn't enough therefore we
>+	 * need both to make it robuster.
>+	 */
>+	ret = axiom_wait_for_completion_timeout(ts, &ts->boot_complete,
>+					msecs_to_jiffies(1 * MSEC_PER_SEC));

Boot can take up to 2s with all selftests enabled.

>+	if (!ret)
>+		dev_err(ts->dev, "Error swreset timedout\n");
>+
>+	fsleep(USEC_PER_SEC);
>+
>+	return ret ? 0 : -ETIMEDOUT;
>+}
>+
>+static int axiom_u02_fillconfig(struct axiom_data *ts)
>+{
>+	struct axiom_u02_rev1_system_manager_msg msg;
>+
>+	if (!axiom_driver_supports_usage(ts, AXIOM_U02))
>+		return -EINVAL;
>+
>+	msg.command = cpu_to_le16(AXIOM_U02_REV1_CMD_FILLCONFIG);
>+	msg.parameters[0] = cpu_to_le16(AXIOM_U02_REV1_PARAM0_FILLCONFIG);
>+	msg.parameters[1] = cpu_to_le16(AXIOM_U02_REV1_PARAM1_FILLCONFIG);
>+	msg.parameters[2] = cpu_to_le16(AXIOM_U02_REV1_PARAM2_FILLCONFIG_ZERO);
>+
>+	return axiom_u02_send_msg(ts, &msg, true);
>+}
>+
>+static int axiom_u02_enter_bootloader(struct axiom_data *ts)
>+{
>+	struct axiom_u02_rev1_system_manager_msg msg = { };
>+	struct device *dev = ts->dev;
>+	unsigned int val;
>+	int ret;
>+
>+	if (!axiom_driver_supports_usage(ts, AXIOM_U02))
>+		return -EINVAL;
>+
>+	/*
>+	 * Enter the bootloader mode requires 3 consecutive messages so we can't
>+	 * check for the response.
>+	 */
>+	msg.command = cpu_to_le16(AXIOM_U02_REV1_CMD_ENTERBOOTLOADER);
>+	msg.parameters[0] = cpu_to_le16(AXIOM_U02_REV1_PARAM0_ENTERBOOLOADER_KEY1);
>+	ret = axiom_u02_send_msg(ts, &msg, false);
>+	if (ret) {
>+		dev_err(dev, "Failed to send bootloader-key1: %d\n", ret);
>+		return ret;
>+	}

A delay is required between commands. 10ms is fine.

>+
>+	msg.parameters[0] = cpu_to_le16(AXIOM_U02_REV1_PARAM0_ENTERBOOLOADER_KEY2);
>+	ret = axiom_u02_send_msg(ts, &msg, false);
>+	if (ret) {
>+		dev_err(dev, "Failed to send bootloader-key2: %d\n", ret);
>+		return ret;
>+	}

And here.

>+
>+	msg.parameters[0] = cpu_to_le16(AXIOM_U02_REV1_PARAM0_ENTERBOOLOADER_KEY3);
>+	ret = axiom_u02_send_msg(ts, &msg, false);
>+	if (ret) {
>+		dev_err(dev, "Failed to send bootloader-key3: %d\n", ret);
>+		return ret;
>+	}
>+
>+	/* Sleep before the first read to give the device time */
>+	fsleep(250 * USEC_PER_MSEC);
>+
>+	/* Wait till the device reports it is in bootloader mode */
>+	return regmap_read_poll_timeout(ts->regmap,
>+			AXIOM_U31_REV1_DEVICE_ID_HIGH_REG, val,
>+			FIELD_GET(AXIOM_U31_REV1_MODE_MASK, val) ==
>+			AXIOM_U31_REV1_MODE_BLP, 250 * USEC_PER_MSEC,
>+			USEC_PER_SEC);
>+}

Just to note if we cannot enter bootloader with u02 due to a corrupted firmware,
you can enter bootloader if the nRESET line is toggled 5 times without comms.

>+
>+static int axiom_u04_get(struct axiom_data *ts, u8 **_buf)
>+{
>+	u8 buf[AXIOM_U04_REV1_SIZE_BYTES];
>+	unsigned int reg;
>+	int ret;
>+
>+	if (!axiom_driver_supports_usage(ts, AXIOM_U04))
>+		return -EINVAL;
>+
>+	reg = axiom_usage_baseaddr(ts, AXIOM_U04);
>+	ret = regmap_raw_read(ts->regmap, reg, buf, sizeof(buf));
>+	if (ret)
>+		return ret;
>+
>+	*_buf = kmemdup(buf, sizeof(buf), GFP_KERNEL);
>+
>+	return sizeof(buf);
>+}
>+
>+static int axiom_u04_set(struct axiom_data *ts, u8 *buf, unsigned int bufsize)
>+{
>+	unsigned int reg;
>+
>+	if (!axiom_driver_supports_usage(ts, AXIOM_U04))
>+		return -EINVAL;
>+
>+	reg = axiom_usage_baseaddr(ts, AXIOM_U04);
>+	return regmap_raw_write(ts->regmap, reg, buf, bufsize);
>+}
>+
>+/*
>+ * U31 revision must be always rev.1 else the whole self discovery mechanism
>+ * fall apart.
>+ */
>+static int axiom_u31_parse_device_info(struct axiom_data *ts)
>+{
>+	struct regmap *regmap = ts->regmap;
>+	unsigned int id_low, id_high, val;
>+	int ret;
>+
>+	ret = regmap_read(regmap, AXIOM_U31_REV1_DEVICE_ID_HIGH_REG, &id_high);
>+	if (ret)
>+		return ret;
>+	id_high = FIELD_GET(AXIOM_U31_REV1_DEVICE_ID_HIGH_MASK, id_high);
>+
>+	ret = regmap_read(regmap, AXIOM_U31_REV1_DEVICE_ID_LOW_REG, &id_low);
>+	if (ret)
>+		return ret;
>+	ts->device_id = id_high << 8 | id_low;
>+
>+	ret = regmap_read(regmap, AXIOM_U31_REV1_RUNTIME_FW_MAJ_REG, &val);
>+	if (ret)
>+		return ret;
>+	ts->fw_major = val;
>+
>+	ret = regmap_read(regmap, AXIOM_U31_REV1_RUNTIME_FW_MIN_REG, &val);
>+	if (ret)
>+		return ret;
>+	ts->fw_minor = val;
>+
>+	/* All other fields are not allowed to be read in BLP mode */
>+	if (axiom_get_runmode(ts) == AXIOM_BLP_MODE)
>+		return 0;
>+
>+	ret = regmap_read(regmap, AXIOM_U31_REV1_RUNTIME_FW_RC_REG, &val);
>+	if (ret)
>+		return ret;
>+	ts->fw_rc = FIELD_GET(AXIOM_U31_REV1_RUNTIME_FW_RC_MASK, val);
>+	ts->silicon_rev = FIELD_GET(AXIOM_U31_REV1_SILICON_REV_MASK, val);
>+
>+	ret = regmap_read(regmap, AXIOM_U31_REV1_RUNTIME_FW_STATUS_REG, &val);
>+	if (ret)
>+		return ret;
>+	ts->fw_status = FIELD_GET(AXIOM_U31_REV1_RUNTIME_FW_STATUS, val);
>+	ts->fw_variant = FIELD_GET(AXIOM_U31_REV1_RUNTIME_FW_VARIANT, val);
>+
>+	ret = regmap_read(regmap, AXIOM_U31_REV1_JEDEC_ID_HIGH_REG, &val);
>+	if (ret)
>+		return ret;
>+	ts->jedec_id = val << 8;
>+
>+	ret = regmap_read(regmap, AXIOM_U31_REV1_JEDEC_ID_LOW_REG, &val);
>+	if (ret)
>+		return ret;
>+	ts->jedec_id |= val;
>+
>+	return 0;
>+}
>+
>+static int axiom_u33_read(struct axiom_data *ts, struct axiom_crc *crc);
>+
>+static int axiom_u31_device_discover(struct axiom_data *ts)
>+{
>+	struct axiom_u31_usage_table_entry *u31_usage_table __free(kfree) = NULL;
>+	struct axiom_u31_usage_table_entry *entry;
>+	struct regmap *regmap = ts->regmap;
>+	unsigned int mode, num_usages;
>+	struct device *dev = ts->dev;
>+	unsigned int i;
>+	int ret;
>+
>+	axiom_set_runmode(ts, AXIOM_DISCOVERY_MODE);
>+
>+	ret = regmap_read(regmap, AXIOM_U31_REV1_DEVICE_ID_HIGH_REG, &mode);
>+	if (ret) {
>+		dev_err(dev, "Failed to read MODE\n");
>+		return ret;
>+	}
>+
>+	/* Abort if the device is in bootloader protocol mode */
>+	mode = FIELD_GET(AXIOM_U31_REV1_MODE_MASK, mode);
>+	if (mode == AXIOM_U31_REV1_MODE_BLP)
>+		axiom_set_runmode(ts, AXIOM_BLP_MODE);
>+
>+	/* Since we are not in bootloader mode we can parse the device info */
>+	ret = axiom_u31_parse_device_info(ts);
>+	if (ret) {
>+		dev_err(dev, "Failed to parse device info\n");
>+		return ret;
>+	}
>+
>+	/* All other fields are not allowed to be read in BLP mode */
>+	if (axiom_get_runmode(ts) == AXIOM_BLP_MODE) {
>+		dev_info(dev, "Device in Bootloader mode, firmware upload required\n");
>+		return -EACCES;
>+	}
>+
>+	ret = regmap_read(regmap, AXIOM_U31_REV1_NUM_USAGES_REG, &num_usages);
>+	if (ret) {
>+		dev_err(dev, "Failed to read NUM_USAGES\n");
>+		return ret;
>+	}
>+
>+	u31_usage_table = kcalloc(num_usages, sizeof(*u31_usage_table),
>+				  GFP_KERNEL);
>+	if (!u31_usage_table)
>+		return -ENOMEM;
>+
>+	ret = regmap_raw_read(regmap, AXIOM_U31_REV1_PAGE1, u31_usage_table,
>+			      array_size(num_usages, sizeof(*u31_usage_table)));
>+	if (ret) {
>+		dev_err(dev, "Failed to read NUM_USAGES\n");
>+		return ret;
>+	}
>+
>+	/*
>+	 * axiom_u31_device_discover() is call after fw update too, so ensure
>+	 * that the usage_table is cleared.
>+	 */
>+	memset(ts->usage_table, 0, sizeof(ts->usage_table));
>+
>+	for (i = 0, entry = u31_usage_table; i < num_usages; i++, entry++) {
>+		unsigned char idx = entry->usage_num;
>+		const struct axiom_usage_info *info;
>+		unsigned int size_bytes;
>+
>+		axiom_dump_usage_entry(dev, entry);
>+
>+		/*
>+		 * Verify that the driver used usages are supported. Don't abort
>+		 * yet if a usage isn't supported to allow the user to dump the
>+		 * actual usage table.
>+		 */
>+		info = axiom_get_usage_info(entry);
>+		if (IS_ERR(info)) {
>+			dev_info(dev, "Required usage u%02X isn't supported for rev.%u\n",
>+				 entry->usage_num, entry->uifrevision);
>+			ret = -EACCES;
>+		}
>+
>+		size_bytes = axiom_get_usage_size_bytes(entry);
>+
>+		ts->usage_table[idx].baseaddr = entry->start_page << 8;
>+		ts->usage_table[idx].size_bytes = size_bytes;
>+		ts->usage_table[idx].populated = true;
>+		ts->usage_table[idx].info = info;
>+
>+		if (axiom_usage_entry_is_report(entry) &&
>+		    ts->max_report_byte_len < size_bytes)
>+			ts->max_report_byte_len = size_bytes;
>+	}
>+
>+	if (ret)
>+		return ret;
>+
>+	/* From now on we are in TCP mode to include usage revision checks */
>+	axiom_set_runmode(ts, AXIOM_TCP_MODE);
>+
>+	return axiom_u33_read(ts, &ts->crc[AXIOM_CRC_CUR]);
>+}
>+
>+static int axiom_u33_read(struct axiom_data *ts, struct axiom_crc *crc)
>+{
>+	struct device *dev = ts->dev;
>+	unsigned int reg;
>+	int ret;
>+
>+	if (!axiom_driver_supports_usage(ts, AXIOM_U33))
>+		return -EINVAL;
>+
>+	if (axiom_usage_rev(ts, AXIOM_U33) == 2) {
>+		struct axiom_u33_rev2 val;
>+
>+		reg = axiom_usage_baseaddr(ts, AXIOM_U33);
>+		ret = regmap_raw_read(ts->regmap, reg, &val, sizeof(val));

Could we read into a raw buffer to save having to define a little endian 
version of the CRCs?

>+		if (ret) {
>+			dev_err(dev, "Failed to read u33\n");
>+			return ret;
>+		}
>+
>+		crc->runtime = le32_to_cpu(val.runtime_crc);
>+		crc->vltusageconfig = le32_to_cpu(val.vltusageconfig_crc);
>+		crc->nvltlusageconfig = le32_to_cpu(val.nvltlusageconfig_crc);
>+		crc->u22_sequencedata = le32_to_cpu(val.u22_sequencedata_crc);
>+		crc->u43_hotspots = le32_to_cpu(val.u43_hotspots_crc);
>+		crc->u93_profiles = le32_to_cpu(val.u93_profiles_crc);
>+		crc->u94_deltascalemap = le32_to_cpu(val.u94_deltascalemap_crc);
>+	} else if (axiom_usage_rev(ts, AXIOM_U33) == 3) {
>+		struct axiom_u33_rev3 val;
>+
>+		reg = axiom_usage_baseaddr(ts, AXIOM_U33);
>+		ret = regmap_raw_read(ts->regmap, reg, &val, sizeof(val));
>+		if (ret) {
>+			dev_err(dev, "Failed to read u33\n");
>+			return ret;
>+		}
>+
>+		crc->runtime = le32_to_cpu(val.runtime_crc);
>+		crc->vltusageconfig = le32_to_cpu(val.vltusageconfig_crc);
>+		crc->nvltlusageconfig = le32_to_cpu(val.nvltlusageconfig_crc);
>+		crc->u22_sequencedata = le32_to_cpu(val.u22_sequencedata_crc);
>+		crc->u43_hotspots = le32_to_cpu(val.u43_hotspots_crc);
>+		crc->u77_dod_data = le32_to_cpu(val.u77_dod_data_crc);
>+		crc->u93_profiles = le32_to_cpu(val.u93_profiles_crc);
>+		crc->u94_deltascalemap = le32_to_cpu(val.u94_deltascalemap_crc);
>+	}
>+
>+	return 0;
>+}
>+
>+static bool axiom_u42_touch_enabled(struct axiom_data *ts, const u8 *buf,
>+				    unsigned int touch_num)
>+{
>+	switch (axiom_usage_rev(ts, AXIOM_U42)) {
>+	case 1:
>+		return buf[AXIOM_U42_REV1_REPORT_ID_CONTAINS(touch_num)] ==
>+		       AXIOM_U42_REV1_REPORT_ID_TOUCH;
>+	case 4:
>+		return buf[AXIOM_U42_REV4_REPORT_ID_CONTAINS(touch_num)] ==
>+		       AXIOM_U42_REV4_REPORT_ID_TOUCH;
>+	default:
>+		/* Should never happen */
>+		return false;
>+	}
>+}
>+
>+static void axiom_u42_get_touchslots(struct axiom_data *ts)
>+{
>+	u8 *buf __free(kfree) = NULL;
>+	struct device *dev = ts->dev;
>+	unsigned int bufsize;
>+	unsigned int reg;
>+	int ret, i;
>+
>+	if (!axiom_driver_supports_usage(ts, AXIOM_U42)) {
>+		dev_warn(dev, "Use default touchslots num\n");
>+		goto fallback;
>+	}
>+
>+	bufsize = axiom_usage_size(ts, AXIOM_U42);
>+	buf = kzalloc(bufsize, GFP_KERNEL);
>+	if (!buf) {
>+		dev_warn(dev, "Failed to alloc u42 read buffer, use default value\n");
>+		goto fallback;
>+	}
>+
>+	reg = axiom_usage_baseaddr(ts, AXIOM_U42);
>+	ret = regmap_raw_read(ts->regmap, reg, buf, bufsize);
>+	if (ret) {
>+		dev_warn(dev, "Failed to read u42, use default value\n");
>+		goto fallback;
>+	}
>+
>+	ts->enabled_slots = 0;
>+	ts->num_slots = 0;
>+
>+	for (i = 0; i < AXIOM_MAX_TOUCHSLOTS; i++) {
>+		if (axiom_u42_touch_enabled(ts, buf, i)) {
>+			ts->enabled_slots |= BIT(i);
>+			ts->num_slots++;
>+		}
>+	}
>+
>+	return;
>+
>+fallback:
>+	ts->enabled_slots = AXIOM_MAX_TOUCHSLOTS_MASK;
>+	ts->num_slots = AXIOM_MAX_TOUCHSLOTS;
>+}
>+
>+static void axiom_u64_cds_enabled(struct axiom_data *ts)
>+{
>+	unsigned int reg, val;
>+	int ret;
>+
>+	if (!axiom_driver_supports_usage(ts, AXIOM_U64))
>+		goto fallback_out;
>+
>+	reg = axiom_usage_baseaddr(ts, AXIOM_U64);
>+	reg += AXIOM_U64_REV2_ENABLECDSPROCESSING_REG;
>+
>+	ret = regmap_read(ts->regmap, reg, &val);
>+	if (ret)
>+		goto fallback_out;
>+
>+	val = FIELD_GET(AXIOM_U64_REV2_ENABLECDSPROCESSING_MASK, val);
>+	ts->cds_enabled = val ? true : false;
>+
>+	return;
>+
>+fallback_out:
>+	ts->cds_enabled = false;
>+}
>+
>+static int axiom_cdu_wait_idle(struct axiom_data *ts, u8 cdu_usage_num)
>+{
>+	unsigned int reg;
>+	int ret, _ret;
>+	u16 cmd;
>+
>+	reg = axiom_usage_baseaddr(ts, cdu_usage_num);
>+
>+	/*
>+	 * Missing regmap_raw_read_poll_timeout for now. RESP_SUCCESS means that
>+	 * the last command successfully completed and the device is idle.
>+	 */
>+	ret = read_poll_timeout(regmap_raw_read, _ret,
>+				_ret || cmd == AXIOM_CDU_RESP_SUCCESS,
>+				10 * USEC_PER_MSEC, 1 * USEC_PER_SEC, false,
>+				ts->regmap, reg, &cmd, 2);
>+	if (ret)
>+		dev_err(ts->dev, "Poll CDU u%02X timedout with: %#x\n",
>+			cdu_usage_num, cmd);
>+
>+	return ret;
>+}
>+
>+/*********************** Report usage handling ********************************/
>+
>+static int axiom_process_report(struct axiom_data *ts, unsigned char usage_num,
>+				const u8 *buf, size_t buflen)
>+{
>+	struct axiom_usage_table_entry *entry = &ts->usage_table[usage_num];
>+
>+	/* Skip processing if not in TCP mode */
>+	if ((axiom_get_runmode(ts) != AXIOM_TCP_MODE) &&
>+	    (axiom_get_runmode(ts) != AXIOM_TCP_CFG_UPDATE_MODE))
>+		return 0;
>+
>+	/* May happen if an unsupported usage was requested */
>+	if (!entry) {
>+		dev_info(ts->dev, "Unsupported usage U%x request\n", usage_num);
>+		return 0;
>+	}
>+
>+	/* Supported report usages need to have a process_report hook */
>+	if (!entry->info || !entry->info->process_report)
>+		return -EINVAL;
>+
>+	return entry->info->process_report(ts, buf, buflen);
>+}
>+
>+/* Make use of datasheet method 1 - single transfer read */
>+static int
>+axiom_u34_rev1_process_report(struct axiom_data *ts, const u8 *_buf, size_t bufsize)
>+{
>+	unsigned int reg = axiom_usage_baseaddr(ts, AXIOM_U34);
>+	struct regmap *regmap = ts->regmap;
>+	u8 buf[AXIOM_PAGE_BYTE_LEN] = { };
>+	struct device *dev = ts->dev;
>+	unsigned char report_usage;
>+	u16 crc_report, crc_calc;
>+	unsigned int len;
>+	u8 *payload;
>+	int ret;
>+
>+	ret = regmap_raw_read(regmap, reg, buf, ts->max_report_byte_len);
>+	if (ret)
>+		return ret;
>+
>+	/* TODO: Add overflow statistics */
>+
>+	/* REPORTLENGTH is in uint16 */
>+	len = FIELD_GET(AXIOM_U34_REV1_REPORTLENGTH_MASK, buf[0]);
>+	len *= 2;
>+
>+	/*
>+	 * Downstream ignores zero length reports, extend the check to validate
>+	 * the upper bound too.
>+	 */
>+	if (len == 0 || len > AXIOM_PAGE_BYTE_LEN) {
>+		dev_dbg_ratelimited(dev, "Invalid report length: %u\n", len);
>+		return -EINVAL;
>+	}
>+
>+	/*
>+	 * The CRC16 value can be queried at the last two bytes of the report.
>+	 * The value itself is covering the complete report excluding the CRC16
>+	 * value at the end.
>+	 */
>+	crc_report = get_unaligned_le16(&buf[len - 2]);
>+	crc_calc = crc16(0, buf, (len - 2));
>+
>+	if (crc_calc != crc_report) {
>+		dev_err_ratelimited(dev, "CRC16 mismatch!\n");
>+		return -EINVAL;
>+	}
>+
>+	report_usage = buf[1];
>+	payload = &buf[AXIOM_U34_REV1_PREAMBLE_BYTES];
>+	len -= AXIOM_U34_REV1_PREAMBLE_BYTES - AXIOM_U34_REV1_POSTAMBLE_BYTES;
>+
>+	switch (report_usage) {
>+	case AXIOM_U01:
>+	case AXIOM_U41:
>+		return axiom_process_report(ts, report_usage, payload, len);
>+	default:
>+		dev_dbg(dev, "Unsupported report u%02X received\n",
>+			report_usage);
>+	}
>+
>+	return 0;
>+}
>+
>+static void
>+axiom_u41_rev2_decode_target(const u8 *buf, u8 id, u16 *x, u16 *y, s8 *z)
>+{
>+	u16 val;
>+
>+	val = get_unaligned_le16(&buf[AXIOM_U41_REV2_X_REG(id)]);
>+	val &= AXIOM_MAX_XY;
>+	*x = val;
>+
>+	val = get_unaligned_le16(&buf[AXIOM_U41_REV2_Y_REG(id)]);
>+	val &= AXIOM_MAX_XY;
>+	*y = val;
>+
>+	*z = buf[AXIOM_U41_REV2_Z_REG(id)];
>+}
>+
>+static int
>+axiom_u41_rev2_process_report(struct axiom_data *ts, const u8 *buf, size_t bufsize)
>+{
>+	struct input_dev *input = ts->input;
>+	unsigned char id;
>+	u16 targets;
>+
>+	/*
>+	 * The input registration can be postponed but the touchscreen FW is
>+	 * sending u41 reports regardless.
>+	 */
>+	if (!input)
>+		return 0;
>+
>+	targets = get_unaligned_le16(&buf[AXIOM_U41_REV2_TARGETSTATUS_REG]);
>+
>+	for_each_set_bit(id, &ts->enabled_slots, AXIOM_MAX_TOUCHSLOTS) {
>+		bool present;
>+		u16 x, y;
>+		s8 z;
>+
>+		axiom_u41_rev2_decode_target(buf, id, &x, &y, &z);
>+
>+		present = targets & BIT(id);
>+		/* Ignore possible jitters */
>+		if (z == AXIOM_PROX_LEVEL)
>+			present = false;
>+
>+		dev_dbg(ts->dev, "id:%u x:%u y:%u z:%d present:%u",
>+			id, x, y, z, present);
>+
>+		input_mt_slot(input, id);
>+		if (input_mt_report_slot_state(input, MT_TOOL_FINGER, present))
>+			touchscreen_report_pos(input, &ts->prop, x, y, true);
>+
>+		if (!present)
>+			continue;
>+
>+		input_report_abs(input, ABS_MT_DISTANCE, z < 0 ? -z : 0);
>+		if (ts->cds_enabled)
>+			input_report_abs(input, ABS_MT_PRESSURE, z >= 0 ? z : 0);
>+	}
>+
>+	input_sync(input);
>+
>+	return 0;
>+}
>+
>+static int
>+axiom_u01_rev1_process_report(struct axiom_data *ts, const u8 *buf, size_t bufsize)
>+{
>+	switch (buf[AXIOM_U01_REV1_REPORTTYPE_REG]) {
>+	case AXIOM_U01_REV1_REPORTTYPE_HELLO:
>+		dev_dbg(ts->dev, "u01 HELLO received\n");
>+		axiom_complete(ts, &ts->boot_complete);
>+		return 0;
>+	case AXIOM_U01_REV1_REPORTTYPE_HEARTBEAT:
>+		dev_dbg_ratelimited(ts->dev, "u01 HEARTBEAT received\n");
>+		return 0;
>+	case AXIOM_U01_REV1_REPORTTYPE_OPCOMPLETE:
>+		dev_dbg(ts->dev, "u01 OPCOMPLETE received\n");
>+		axiom_u02_handshakenvm(ts);
>+		axiom_complete(ts, &ts->nvm_write);
>+		return 0;
>+	default:
>+		return -EINVAL;
>+	}
>+}
>+
>+/**************************** Regmap handling *********************************/
>+
>+#define AXIOM_CMD_HDR_DIR_MASK	BIT(15)
>+#define   AXIOM_CMD_HDR_READ	1
>+#define	  AXIOM_CMD_HDR_WRITE	0
>+#define AXIOM_CMD_HDR_LEN_MASK	GENMASK(14, 0)
>+
>+struct axiom_cmd_header {
>+	__le16 target_address;
>+	__le16 xferlen;
>+};
>+
>+/* Custom regmap read/write handling is required due to the aXiom protocol */
>+static int axiom_regmap_read(void *context, const void *reg_buf, size_t reg_size,
>+			     void *val_buf, size_t val_size)
>+{
>+	struct device *dev = context;
>+	struct i2c_client *i2c = to_i2c_client(dev);
>+	struct axiom_data *ts = i2c_get_clientdata(i2c);
>+	struct axiom_cmd_header hdr;
>+	u16 xferlen, addr, baseaddr;
>+	struct i2c_msg xfer[2];
>+	int ret;
>+
>+	if (val_size > AXIOM_MAX_XFERLEN) {
>+		dev_err(ts->dev, "Exceed max xferlen: %zu > %u\n",
>+			val_size, AXIOM_MAX_XFERLEN);
>+		return -EINVAL;
>+	}
>+
>+	addr = *((u16 *)reg_buf);
>+	hdr.target_address = cpu_to_le16(addr);
>+	xferlen = FIELD_PREP(AXIOM_CMD_HDR_DIR_MASK, AXIOM_CMD_HDR_READ) |
>+		  FIELD_PREP(AXIOM_CMD_HDR_LEN_MASK, val_size);
>+	hdr.xferlen = cpu_to_le16(xferlen);
>+
>+	/* Verify that usage including the usage rev is supported */
>+	baseaddr = addr & AXIOM_USAGE_BASEADDR_MASK;
>+	if (!axiom_usage_supported(ts, baseaddr))
>+		return -EINVAL;
>+
>+	xfer[0].addr = i2c->addr;
>+	xfer[0].flags = 0;
>+	xfer[0].len = sizeof(hdr);
>+	xfer[0].buf = (u8 *)&hdr;
>+
>+	xfer[1].addr = i2c->addr;
>+	xfer[1].flags = I2C_M_RD;
>+	xfer[1].len = val_size;
>+	xfer[1].buf = val_buf;
>+
>+	ret = i2c_transfer(i2c->adapter, xfer, 2);
>+	if (ret == 2)
>+		return 0;
>+	else if (ret < 0)
>+		return ret;
>+	else
>+		return -EIO;
>+}

There needs to be atleast 40us holdoff between axiom bus transfers.
I am not sure that has been considered here.

>+
>+static int axiom_regmap_write(void *context, const void *data, size_t count)
>+{
>+	struct device *dev = context;
>+	struct i2c_client *i2c = to_i2c_client(dev);
>+	struct axiom_data *ts = i2c_get_clientdata(i2c);
>+	char *buf __free(kfree) = NULL;
>+	struct axiom_cmd_header hdr;
>+	u16 xferlen, addr, baseaddr;
>+	size_t val_size, msg_size;
>+	int ret;
>+
>+	val_size = count - sizeof(addr);
>+	if (val_size > AXIOM_MAX_XFERLEN) {
>+		dev_err(ts->dev, "Exceed max xferlen: %zu > %u\n",
>+			val_size, AXIOM_MAX_XFERLEN);
>+		return -EINVAL;
>+	}
>+
>+	addr = *((u16 *)data);
>+	hdr.target_address = cpu_to_le16(addr);
>+	xferlen = FIELD_PREP(AXIOM_CMD_HDR_DIR_MASK, AXIOM_CMD_HDR_WRITE) |
>+		  FIELD_PREP(AXIOM_CMD_HDR_LEN_MASK, val_size);
>+	hdr.xferlen = cpu_to_le16(xferlen);
>+
>+	/* Verify that usage including the usage rev is supported */
>+	baseaddr = addr & AXIOM_USAGE_BASEADDR_MASK;
>+	if (!axiom_usage_supported(ts, baseaddr))
>+		return -EINVAL;
>+
>+	msg_size = sizeof(hdr) + val_size;
>+	buf = kzalloc(msg_size, GFP_KERNEL);
>+	if (!buf)
>+		return -ENOMEM;
>+
>+	memcpy(buf, &hdr, sizeof(hdr));
>+	memcpy(&buf[sizeof(hdr)], &((char *)data)[2], val_size);
>+
>+	ret = i2c_master_send(i2c, buf, msg_size);
>+
>+	return ret == msg_size ? 0 : ret;
>+}
>+
>+static const struct regmap_config axiom_i2c_regmap_config = {
>+	.reg_bits = 16,
>+	.val_bits = 8,
>+	.read = axiom_regmap_read,
>+	.write = axiom_regmap_write,
>+};
>+
>+/************************ FW update handling **********************************/
>+
>+static int axiom_update_input_dev(struct axiom_data *ts);
>+
>+static enum fw_upload_err
>+axiom_axfw_fw_prepare(struct fw_upload *fw_upload, const u8 *data, u32 size)
>+{
>+	struct axiom_data *ts = fw_upload->dd_handle;
>+	struct axiom_firmware *afw = &ts->fw[AXIOM_FW_AXFW];
>+	u8 major_ver, minor_ver, rc_ver, status, variant;
>+	u32 fw_file_crc32, crc32_calc;
>+	struct device *dev = ts->dev;
>+	unsigned int signature_len;
>+	enum fw_upload_err ret;
>+	u16 fw_file_format_ver;
>+	u16 fw_file_device_id;
>+
>+	mutex_lock(&afw->lock);
>+	afw->cancel = false;
>+	mutex_unlock(&afw->lock);
>+
>+	mutex_lock(&ts->fwupdate_lock);
>+
>+	if (size < sizeof(struct axiom_fw_axfw_hdr)) {
>+		dev_err(dev, "Invalid AXFW file size\n");
>+		ret = FW_UPLOAD_ERR_INVALID_SIZE;
>+		goto out;
>+	}
>+
>+	signature_len = strlen(AXIOM_FW_AXFW_SIGNATURE);
>+	if (strncmp(data, AXIOM_FW_AXFW_SIGNATURE, signature_len)) {
>+		/*
>+		 * AXFW has a header which can be used to perform validations,
>+		 * ALC don't. Therefore the AXFW format is preferred.
>+		 */
>+		dev_warn(dev, "No AXFW signature, assume ALC firmware\n");
>+		ret = FW_UPLOAD_ERR_NONE;
>+		goto out;
>+	}
>+
>+	fw_file_crc32 = get_unaligned_le32(&data[signature_len]);
>+	crc32_calc = crc32(~0, &data[8], size - 8) ^ 0xffffffff;
>+	if (fw_file_crc32 != crc32_calc) {
>+		dev_err(dev, "AXFW CRC32 doesn't match (fw:%#x calc:%#x)\n",
>+			fw_file_crc32, crc32_calc);
>+		ret = FW_UPLOAD_ERR_FW_INVALID;
>+		goto out;
>+	}
>+
>+	data += signature_len + sizeof(fw_file_crc32);
>+	fw_file_format_ver = get_unaligned_le16(data);
>+	if (fw_file_format_ver != AXIOM_FW_AXFW_FILE_FMT_VER) {
>+		dev_err(dev, "Invalid AXFW file format version: %04x",
>+			fw_file_format_ver);
>+		ret = FW_UPLOAD_ERR_FW_INVALID;
>+		goto out;
>+	}
>+
>+	data += sizeof(fw_file_format_ver);
>+	fw_file_device_id = get_unaligned_le16(data);
>+	if (fw_file_device_id != ts->device_id) {
>+		dev_err(dev, "Invalid AXFW target device (fw:%#04x dev:%#04x)\n",
>+			fw_file_device_id, ts->device_id);
>+		ret = FW_UPLOAD_ERR_FW_INVALID;
>+		goto out;
>+	}
>+
>+	/*
>+	 * This can happen if:
>+	 *  * the device came up in bootloader mode, or
>+	 *  * downloading the firmware failed in between, or
>+	 *  * the following usage discovery failed.
>+	 *
>+	 *  All cases are crcitical and we need to use any firmware to
>+	 *  bring the device back into a working state which is supported by the
>+	 *  host.
>+	 */
>+	if (axiom_get_runmode(ts) != AXIOM_TCP_MODE)
>+		return FW_UPLOAD_ERR_NONE;
>+
>+	data += sizeof(fw_file_device_id);
>+	variant = *data++;
>+	minor_ver = *data++;
>+	major_ver = *data++;
>+	rc_ver = *data++;
>+	status = *data++;
>+
>+	if (major_ver == ts->fw_major && minor_ver == ts->fw_minor &&
>+	    rc_ver == ts->fw_rc && status == ts->fw_status &&
>+	    variant == ts->fw_variant) {
>+		ret = FW_UPLOAD_ERR_DUPLICATE;
>+		goto out;
>+	}
>+
>+	dev_info(dev, "Detected AXFW %02u.%02u.%02u (%s)\n",
>+		 major_ver, minor_ver, rc_ver,
>+		 status ? "production" : "engineering");
>+
>+	mutex_lock(&afw->lock);
>+	ret = afw->cancel ? FW_UPLOAD_ERR_CANCELED : FW_UPLOAD_ERR_NONE;
>+	mutex_unlock(&afw->lock);
>+
>+out:
>+	/*
>+	 * In FW_UPLOAD_ERR_NONE case the complete handler will release the
>+	 * lock.
>+	 */
>+	if (ret != FW_UPLOAD_ERR_NONE)
>+		mutex_unlock(&ts->fwupdate_lock);
>+
>+	return ret;
>+}
>+
>+static int axiom_enter_bootloader_mode(struct axiom_data *ts)
>+{
>+	struct device *dev = ts->dev;
>+	int ret;
>+
>+	axiom_set_runmode(ts, AXIOM_BLP_PRE_MODE);
>+
>+	ret = axiom_u02_wait_idle(ts);
>+	if (ret)
>+		goto err_out;
>+
>+	ret = axiom_u02_enter_bootloader(ts);
>+	if (ret) {
>+		dev_err(dev, "Failed to enter bootloader mode\n");
>+		goto err_out;
>+	}
>+
>+	axiom_set_runmode(ts, AXIOM_BLP_MODE);
>+
>+	return 0;
>+
>+err_out:
>+	axiom_set_runmode(ts, AXIOM_TCP_MODE);
>+
>+	return ret;
>+}
>+
>+static int axoim_blp_wait_ready(struct axiom_data *ts)
>+{
>+	struct device *dev = ts->dev;
>+	unsigned int reg;
>+	int tmp, ret;
>+	u8 buf[4];
>+
>+	reg = AXIOM_U01_BLP_SATUS_REG;
>+
>+	/* BLP busy poll requires to read 4 bytes! */
>+	ret = read_poll_timeout(regmap_raw_read, tmp,
>+				tmp || !(buf[2] & AXIOM_U01_BLP_STATUS_BUSY),
>+				10 * USEC_PER_MSEC, 5 * USEC_PER_SEC, false,
>+				ts->regmap, reg, &buf, 4);
>+	if (ret)
>+		dev_err(dev, "Bootloader wait processing packets failed %d\n", ret);
>+
>+	return ret;
>+}
>+
>+static int
>+axiom_blp_write_chunk(struct axiom_data *ts, const u8 *data, u16 length)
>+{
>+	unsigned int chunk_size = AXIOM_U01_BLP_FIFO_CHK_SIZE_BYTES;
>+	unsigned int reg = AXIOM_U01_BLP_FIFO_REG;
>+	struct device *dev = ts->dev;
>+	unsigned int pos = 0;
>+	int ret;
>+
>+	ret = axoim_blp_wait_ready(ts);
>+	if (ret)
>+		return ret;
>+
>+	/*
>+	 * TODO: Downstream does this chunk transfers. Verify if this is
>+	 * required if one fw-chunk <= AXIOM_MAX_XFERLEN
>+	 */
>+	while (pos < length) {
>+		u16 len;
>+
>+		len = chunk_size;
>+		if ((pos + chunk_size) > length)
>+			len = length - pos;
>+
>+		ret = regmap_raw_write(ts->regmap, reg, &data[pos], len);
>+		if (ret) {
>+			dev_err(dev, "Bootloader download AXFW chunk failed %d\n", ret);
>+			return ret;
>+		}
>+
>+		pos += len;
>+		ret = axoim_blp_wait_ready(ts);
>+		if (ret)
>+			return ret;
>+	}
>+
>+	return 0;
>+}
>+
>+static int axiom_blp_reset(struct axiom_data *ts)
>+{
>+	__le16 reset_cmd = cpu_to_le16(AXIOM_U01_BLP_COMMAND_RESET);
>+	unsigned int reg = AXIOM_U01_BLP_COMMAND_REG;
>+	struct device *dev = ts->dev;
>+	unsigned int attempts = 20;
>+	unsigned int mode;
>+	int ret;
>+
>+	ret = axoim_blp_wait_ready(ts);
>+	if (ret)
>+		return ret;
>+
>+	/*
>+	 * For some reason this write fail with -ENXIO. Skip checking the return
>+	 * code (which is also done by the downstream http://axfw.py tool and poll u31
>+	 * instead.
>+	 */
>+	regmap_raw_write(ts->regmap, reg, &reset_cmd, sizeof(reset_cmd));
>+
>+	do {
>+		ret = regmap_read(ts->regmap, AXIOM_U31_REV1_DEVICE_ID_HIGH_REG,
>+				  &mode);
>+		if (!ret)
>+			break;
>+
>+		fsleep(250 * USEC_PER_MSEC);
>+	} while (attempts--);
>+
>+	if (ret) {
>+		dev_err(dev, "Failed to read MODE after BLP reset: %d\n", ret);
>+		return ret;
>+	}
>+
>+	mode = FIELD_GET(AXIOM_U31_REV1_MODE_MASK, mode);
>+	if (mode == AXIOM_U31_REV1_MODE_BLP) {
>+		dev_err(dev, "Device still in BLP mode, abort\n");
>+		return -EINVAL;
>+	}
>+
>+	return 0;
>+}
>+
>+static void axiom_lock_input_device(struct axiom_data *ts)
>+{
>+	if (!ts->input)
>+		return;
>+
>+	mutex_lock(&ts->input->mutex);
>+}
>+
>+static void axiom_unlock_input_device(struct axiom_data *ts)
>+{
>+	if (!ts->input)
>+		return;
>+
>+	mutex_unlock(&ts->input->mutex);
>+}
>+
>+static void axiom_unregister_input_dev(struct axiom_data *ts)
>+{
>+	if (ts->input)
>+		input_unregister_device(ts->input);
>+
>+	ts->input = NULL;
>+}
>+
>+static enum fw_upload_err
>+axiom_axfw_fw_write(struct fw_upload *fw_upload, const u8 *data, u32 offset,
>+		    u32 size, u32 *written)
>+{
>+	struct axiom_data *ts = fw_upload->dd_handle;
>+	struct axiom_firmware *afw = &ts->fw[AXIOM_FW_AXFW];
>+	struct device *dev = ts->dev;
>+	bool cancel;
>+	int ret;
>+
>+	/* Done before cancel check due to cleanup based put */
>+	ret = pm_runtime_resume_and_get(ts->dev);
>+	if (ret)
>+		return FW_UPLOAD_ERR_HW_ERROR;
>+
>+	mutex_lock(&afw->lock);
>+	cancel = afw->cancel;
>+	mutex_unlock(&afw->lock);
>+
>+	if (cancel)
>+		return FW_UPLOAD_ERR_CANCELED;
>+
>+	axiom_lock_input_device(ts);
>+
>+	if (ts->input && input_device_enabled(ts->input)) {
>+		dev_err(dev, "Input device not idle, abort AXFW/ALC update\n");
>+		goto err;
>+	}
>+
>+	if (!strncmp(data, AXIOM_FW_AXFW_SIGNATURE,
>+		     strlen(AXIOM_FW_AXFW_SIGNATURE))) {
>+		/* Set the pointer to the first fw chunk */
>+		data += sizeof(struct axiom_fw_axfw_hdr);
>+		size -= sizeof(struct axiom_fw_axfw_hdr);
>+		*written += sizeof(struct axiom_fw_axfw_hdr);
>+	}
>+
>+	if (axiom_enter_bootloader_mode(ts))
>+		goto err;
>+
>+	while (size) {
>+		u16 chunk_len, len;
>+
>+		chunk_len = get_unaligned_be16(&data[6]);
>+		len = chunk_len + sizeof(struct axiom_fw_axfw_chunk_hdr);
>+
>+		/*
>+		 * The bootlaoder FW can handle the complete chunk incl. the
>+		 * header.
>+		 */
>+		ret = axiom_blp_write_chunk(ts, data, len);
>+		if (ret)
>+			goto err;
>+
>+		size -= len;
>+		*written += len;
>+		data += len;
>+	}
>+
>+	ret = axiom_blp_reset(ts);
>+	if (ret)
>+		dev_warn(dev, "BLP reset failed\n");
>+
>+	ret = axiom_u31_device_discover(ts);
>+	if (ret) {
>+		/*
>+		 * This is critical and we need to avoid that the user-space can
>+		 * still use the input-dev.
>+		 */
>+		axiom_unlock_input_device(ts);
>+		axiom_unregister_input_dev(ts);
>+		dev_err(dev, "Device discovery failed after AXFW/ALC firmware update\n");
>+		goto err;
>+	}
>+
>+	/* Unlock before the input device gets unregistered */
>+	axiom_unlock_input_device(ts);
>+
>+	ret = axiom_update_input_dev(ts);
>+	if (ret) {
>+		dev_err(dev, "Input device update failed after AXFW/ALC firmware update\n");
>+		return FW_UPLOAD_ERR_HW_ERROR;
>+	}
>+
>+	dev_info(dev, "AXFW update successful\n");
>+
>+	return FW_UPLOAD_ERR_NONE;
>+
>+err:
>+	axiom_unlock_input_device(ts);
>+	return FW_UPLOAD_ERR_HW_ERROR;
>+}
>+
>+static enum fw_upload_err axiom_fw_poll_complete(struct fw_upload *fw_upload)
>+{
>+	return FW_UPLOAD_ERR_NONE;
>+}
>+
>+static void axiom_axfw_fw_cancel(struct fw_upload *fw_upload)
>+{
>+	struct axiom_data *ts = fw_upload->dd_handle;
>+	struct axiom_firmware *afw = &ts->fw[AXIOM_FW_AXFW];
>+
>+	mutex_lock(&afw->lock);
>+	afw->cancel = true;
>+	mutex_unlock(&afw->lock);
>+}
>+
>+static void axiom_axfw_fw_cleanup(struct fw_upload *fw_upload)
>+{
>+	struct axiom_data *ts = fw_upload->dd_handle;
>+
>+	mutex_unlock(&ts->fwupdate_lock);
>+	pm_runtime_mark_last_busy(ts->dev);
>+	pm_runtime_put_sync_autosuspend(ts->dev);
>+}
>+
>+static const struct fw_upload_ops axiom_axfw_fw_upload_ops = {
>+	.prepare = axiom_axfw_fw_prepare,
>+	.write = axiom_axfw_fw_write,
>+	.poll_complete = axiom_fw_poll_complete,
>+	.cancel = axiom_axfw_fw_cancel,
>+	.cleanup = axiom_axfw_fw_cleanup,
>+};
>+
>+static int
>+axiom_set_new_crcs(struct axiom_data *ts, const struct axiom_fw_cfg_chunk *cfg)
>+{
>+	struct axiom_crc *crc = &ts->crc[AXIOM_CRC_NEW];
>+	const u32 *u33_data = (const u32 *)cfg->usage_content;
>+
>+	if (cfg->usage_rev != 2 && cfg->usage_rev != 3) {
>+		dev_err(ts->dev, "The driver doesn't support u33 revision %u\n",
>+			cfg->usage_rev);
>+		return -EINVAL;
>+	}
>+
>+	crc->runtime = get_unaligned_le32(u33_data);
>+	crc->nvltlusageconfig = get_unaligned_le32(&u33_data[3]);
>+	crc->vltusageconfig = get_unaligned_le32(&u33_data[4]);
>+	crc->u22_sequencedata = get_unaligned_le32(&u33_data[5]);
>+	crc->u43_hotspots = get_unaligned_le32(&u33_data[6]);
>+	if (cfg->usage_rev == 2) {
>+		crc->u93_profiles = get_unaligned_le32(&u33_data[7]);
>+		crc->u94_deltascalemap = get_unaligned_le32(&u33_data[8]);
>+	} else if (cfg->usage_rev == 3) {
>+		crc->u77_dod_data = get_unaligned_le32(&u33_data[7]);
>+		crc->u93_profiles = get_unaligned_le32(&u33_data[8]);
>+		crc->u94_deltascalemap = get_unaligned_le32(&u33_data[9]);
>+	}
>+
>+	return 0;
>+}
>+
>+static unsigned int
>+axiom_cfg_fw_prepare_chunk(struct axiom_fw_cfg_chunk *chunk, const u8 *data)
>+{
>+	chunk->usage_num = data[0];
>+	chunk->usage_rev = data[1];
>+	chunk->usage_length = get_unaligned_le16(&data[3]);
>+	chunk->usage_content = &data[5];
>+
>+	return chunk->usage_length + sizeof(struct axiom_fw_cfg_chunk_hdr);
>+}
>+
>+/*
>+ * To overcome buggy firmware we need to check if a given usage is used by the
>+ * current running firmware. Return true if the usage is unused/not populated
>+ * by the firmware since we can't perform the actual check.
>+ */
>+#define axiom_usage_crc_match(_ts, _usage_num, _cur, _new, _field) \
>+	(!_ts->usage_table[_usage_num].populated || (_cur->_field == _new->_field))
>+
>+static bool axiom_cfg_fw_update_required(struct axiom_data *ts)
>+{
>+	struct axiom_crc *cur, *new;
>+
>+	cur = &ts->crc[AXIOM_CRC_CUR];
>+	new = &ts->crc[AXIOM_CRC_NEW];
>+
>+	if (cur->nvltlusageconfig != new->nvltlusageconfig ||
>+	    !axiom_usage_crc_match(ts, AXIOM_U22, cur, new, u22_sequencedata) ||
>+	    !axiom_usage_crc_match(ts, AXIOM_U43, cur, new, u43_hotspots) ||
>+	    !axiom_usage_crc_match(ts, AXIOM_U93, cur, new, u93_profiles) ||
>+	    !axiom_usage_crc_match(ts, AXIOM_U94, cur, new, u94_deltascalemap))
>+		return true;
>+
>+	return false;
>+}
>+
>+static enum fw_upload_err
>+axiom_cfg_fw_prepare(struct fw_upload *fw_upload, const u8 *data, u32 size)
>+{
>+	struct axiom_data *ts = fw_upload->dd_handle;
>+	struct axiom_firmware *afw = &ts->fw[AXIOM_FW_CFG];
>+	u32 cur_runtime_crc, fw_runtime_crc;
>+	struct axiom_fw_cfg_chunk chunk;
>+	struct device *dev = ts->dev;
>+	enum fw_upload_err ret;
>+	u32 signature;
>+
>+	mutex_lock(&afw->lock);
>+	afw->cancel = false;
>+	mutex_unlock(&afw->lock);
>+
>+	mutex_lock(&ts->fwupdate_lock);
>+
>+	if (axiom_get_runmode(ts) != AXIOM_TCP_MODE) {
>+		dev_err(dev, "Device not in TCP mode, abort TH2CFG update\n");
>+		ret = FW_UPLOAD_ERR_HW_ERROR;
>+		goto out;
>+	}
>+
>+	if (size < sizeof(struct axiom_fw_cfg_hdr)) {
>+		dev_err(dev, "Invalid TH2CFG file size\n");
>+		ret = FW_UPLOAD_ERR_INVALID_SIZE;
>+		goto out;
>+	}
>+
>+	signature = get_unaligned_be32(data);
>+	if (signature != AXIOM_FW_CFG_SIGNATURE) {
>+		dev_err(dev, "Invalid TH2CFG signature\n");
>+		ret = FW_UPLOAD_ERR_FW_INVALID;
>+		goto out;
>+	}
>+
>+	/* Skip to the first fw chunk */
>+	data += sizeof(struct axiom_fw_cfg_hdr);
>+	size -= sizeof(struct axiom_fw_cfg_hdr);
>+
>+	/*
>+	 * Search for u33 which contains the CRC information and perform only
>+	 * the runtime-crc check.
>+	 */
>+	while (size) {
>+		unsigned int chunk_len;
>+
>+		chunk_len = axiom_cfg_fw_prepare_chunk(&chunk, data);
>+		if (chunk.usage_num == AXIOM_U33)
>+			break;
>+
>+		data += chunk_len;
>+		size -= chunk_len;
>+	}
>+
>+	if (size == 0) {
>+		dev_err(dev, "Failed to find the u33 entry in TH2CFG\n");
>+		ret = FW_UPLOAD_ERR_FW_INVALID;
>+		goto out;
>+	}
>+
>+	ret = axiom_set_new_crcs(ts, &chunk);
>+	if (ret) {
>+		ret = FW_UPLOAD_ERR_FW_INVALID;
>+		goto out;
>+	}
>+
>+	/*
>+	 * Nothing to do if the CRCs are the same. TODO: Must be extended once
>+	 * the CDU update is added.
>+	 */
>+	if (!axiom_cfg_fw_update_required(ts)) {
>+		ret = FW_UPLOAD_ERR_DUPLICATE;
>+		goto out;
>+	}
>+
>+	cur_runtime_crc = ts->crc[AXIOM_CRC_CUR].runtime;
>+	fw_runtime_crc = ts->crc[AXIOM_CRC_NEW].runtime;
>+	if (cur_runtime_crc != fw_runtime_crc) {
>+		dev_err(dev, "TH2CFG and device runtime CRC doesn't match: %#x != %#x\n",
>+			fw_runtime_crc, cur_runtime_crc);
>+		ret = FW_UPLOAD_ERR_FW_INVALID;
>+		goto out;
>+	}

The firmware CRCs dont need to match for a config load, only the usage revision/length.

>+
>+	mutex_lock(&afw->lock);
>+	ret = afw->cancel ? FW_UPLOAD_ERR_CANCELED : FW_UPLOAD_ERR_NONE;
>+	mutex_unlock(&afw->lock);
>+
>+out:
>+	/*
>+	 * In FW_UPLOAD_ERR_NONE case the complete handler will release the
>+	 * lock.
>+	 */
>+	if (ret != FW_UPLOAD_ERR_NONE)
>+		mutex_unlock(&ts->fwupdate_lock);
>+
>+	return ret;
>+}
>+
>+static int axiom_zero_volatile_mem(struct axiom_data *ts)
>+{
>+	int ret, size;
>+	u8 *buf;
>+
>+	/* Zero out the volatile memory except for the user content in u04 */
>+	ret = axiom_u04_get(ts, &buf);
>+	if (ret < 0)
>+		return ret;
>+	size = ret;
>+
>+	ret = axiom_u02_fillconfig(ts);
>+	if (ret)
>+		goto out;
>+
>+	ret = axiom_u04_set(ts, buf, size);
>+out:
>+	kfree(buf);
>+	return ret;
>+}
>+
>+static bool
>+axiom_skip_cfg_chunk(struct axiom_data *ts, const struct axiom_fw_cfg_chunk *chunk)
>+{
>+	u8 usage_num = chunk->usage_num;
>+
>+	if (!ts->usage_table[usage_num].populated) {
>+		dev_warn(ts->dev, "Unknown usage chunk for u%02X\n", usage_num);
>+		return true;
>+	}
>+
>+	/* Skip read-only usages */
>+	if (ts->usage_table[usage_num].info &&
>+	    ts->usage_table[usage_num].info->is_ro)
>+		return true;
>+
>+	return false;
>+}
>+
>+static int
>+axiom_write_cdu_usage(struct axiom_data *ts, const struct axiom_fw_cfg_chunk *chunk)
>+{
>+	struct axiom_cdu_usage cdu = { };
>+	struct device *dev = ts->dev;
>+	unsigned int remaining;
>+	unsigned int reg;
>+	unsigned int pos;
>+	int ret;
>+
>+	pos = 0;
>+	remaining = chunk->usage_length;
>+	cdu.command = cpu_to_le16(AXIOM_CDU_CMD_STORE);
>+	reg = axiom_usage_baseaddr(ts, chunk->usage_num);
>+
>+	while (remaining) {
>+		unsigned int size;
>+
>+		cdu.parameters[1] = cpu_to_le16(pos);
>+
>+		size = remaining;
>+		if (size > AXIOM_CDU_MAX_DATA_BYTES)
>+			size = AXIOM_CDU_MAX_DATA_BYTES;
>+
>+		memset(cdu.data, 0, sizeof(cdu.data));
>+		memcpy(cdu.data, &chunk->usage_content[pos], size);
>+
>+		ret = regmap_raw_write(ts->regmap, reg, &cdu, sizeof(cdu));
>+		if (ret) {
>+			dev_err(dev, "Failed to write CDU u%02X\n",
>+				chunk->usage_num);
>+			return ret;
>+		}
>+
>+		ret = axiom_cdu_wait_idle(ts, chunk->usage_num);
>+		if (ret) {
>+			dev_err(dev, "CDU write wait-idle failed\n");
>+			return ret;
>+		}
>+
>+		remaining -= size;
>+		pos += size;
>+	}
>+
>+	/*
>+	 * TODO: Check if we really need to send 48 zero bytes of data like
>+	 * downstream does.
>+	 */
>+	memset(&cdu, 0, sizeof(cdu));
>+	cdu.command = cpu_to_le16(AXIOM_CDU_CMD_COMMIT);
>+	cdu.parameters[0] = cpu_to_le16(AXIOM_CDU_PARAM0_COMMIT);
>+	cdu.parameters[1] = cpu_to_le16(AXIOM_CDU_PARAM1_COMMIT);
>+
>+	ret = regmap_raw_write(ts->regmap, reg, &cdu, sizeof(cdu));
>+	if (ret) {
>+		dev_err(dev, "Failed to commit CDU u%02X to NVM\n",
>+			chunk->usage_num);
>+		return ret;
>+	}
>+
>+	ret = axiom_wait_for_completion_timeout(ts, &ts->nvm_write,
>+					msecs_to_jiffies(5 * MSEC_PER_SEC));
>+	if (!ret) {
>+		dev_err(ts->dev, "Error CDU u%02X commit timedout\n",
>+			chunk->usage_num);
>+		return -ETIMEDOUT;
>+	}
>+
>+	return axiom_cdu_wait_idle(ts, chunk->usage_num);
>+}
>+
>+static int
>+axiom_write_cfg_chunk(struct axiom_data *ts, const struct axiom_fw_cfg_chunk *chunk)
>+{
>+	unsigned int reg;
>+	int ret;
>+
>+	if (ts->usage_table[chunk->usage_num].info &&
>+	    ts->usage_table[chunk->usage_num].info->is_cdu) {
>+		ret = axiom_write_cdu_usage(ts, chunk);
>+		if (ret)
>+			return ret;
>+		goto out;
>+	}
>+
>+	reg = axiom_usage_baseaddr(ts, chunk->usage_num);
>+	ret = regmap_raw_write(ts->regmap, reg, chunk->usage_content, chunk->usage_length);
>+	if (ret)
>+		return ret;
>+
>+out:
>+	return axiom_u02_wait_idle(ts);
>+}
>+
>+static int axiom_verify_volatile_mem(struct axiom_data *ts)
>+{
>+	int ret;
>+
>+	ret = axiom_u02_computecrc(ts);
>+	if (ret)
>+		return ret;
>+
>+	/* Query the new CRCs after they are re-computed */
>+	ret = axiom_u33_read(ts, &ts->crc[AXIOM_CRC_CUR]);
>+	if (ret)
>+		return ret;
>+
>+	return ts->crc[AXIOM_CRC_CUR].vltusageconfig ==
>+	       ts->crc[AXIOM_CRC_NEW].vltusageconfig ? 0 : -EINVAL;
>+}
>+
>+static int axiom_verify_crcs(struct axiom_data *ts)
>+{
>+	struct device *dev = ts->dev;
>+	struct axiom_crc *cur, *new;
>+
>+	cur = &ts->crc[AXIOM_CRC_CUR];
>+	new = &ts->crc[AXIOM_CRC_NEW];
>+
>+	if (new->vltusageconfig != cur->vltusageconfig) {
>+		dev_err(dev, "VLTUSAGECONFIG CRC32 mismatch (dev:%#x != fw:%#x)\n",
>+			cur->vltusageconfig, new->vltusageconfig);
>+		return -EINVAL;
>+	} else if (new->nvltlusageconfig != cur->nvltlusageconfig) {
>+		dev_err(dev, "NVLTUSAGECONFIG CRC32 mismatch (dev:%#x != fw:%#x)\n",
>+			cur->nvltlusageconfig, new->nvltlusageconfig);
>+		return -EINVAL;
>+	} else if (!axiom_usage_crc_match(ts, AXIOM_U22, cur, new, u22_sequencedata)) {
>+		dev_err(dev, "U22_SEQUENCEDATA CRC32 mismatch (dev:%#x != fw:%#x)\n",
>+			cur->u22_sequencedata, new->u22_sequencedata);
>+		return -EINVAL;
>+	} else if (!axiom_usage_crc_match(ts, AXIOM_U43, cur, new, u43_hotspots)) {
>+		dev_err(dev, "U43_HOTSPOTS CRC32 mismatch (dev:%#x != fw:%#x)\n",
>+			cur->u43_hotspots, new->u43_hotspots);
>+		return -EINVAL;
>+	} else if (!axiom_usage_crc_match(ts, AXIOM_U93, cur, new, u93_profiles)) {
>+		dev_err(dev, "U93_PROFILES CRC32 mismatch (dev:%#x != fw:%#x)\n",
>+			cur->u93_profiles, new->u93_profiles);
>+		return -EINVAL;
>+	} else if (!axiom_usage_crc_match(ts, AXIOM_U94, cur, new, u94_deltascalemap)) {
>+		dev_err(dev, "U94_DELTASCALEMAP CRC32 mismatch (dev:%#x != fw:%#x)\n",
>+			cur->u94_deltascalemap, new->u94_deltascalemap);
>+		return -EINVAL;
>+	}
>+
>+	return 0;
>+}
>+
>+static enum fw_upload_err
>+axiom_cfg_fw_write(struct fw_upload *fw_upload, const u8 *data, u32 offset,
>+		   u32 size, u32 *written)
>+{
>+	struct axiom_data *ts = fw_upload->dd_handle;
>+	struct axiom_firmware *afw = &ts->fw[AXIOM_FW_CFG];
>+	struct device *dev = ts->dev;
>+	bool cancel;
>+	int ret;
>+
>+	/* Done before cancel check due to cleanup based put */
>+	ret = pm_runtime_resume_and_get(ts->dev);
>+	if (ret)
>+		return FW_UPLOAD_ERR_HW_ERROR;
>+
>+	mutex_lock(&afw->lock);
>+	cancel = afw->cancel;
>+	mutex_unlock(&afw->lock);
>+
>+	if (cancel)
>+		return FW_UPLOAD_ERR_CANCELED;
>+
>+	axiom_lock_input_device(ts);
>+
>+	if (ts->input && input_device_enabled(ts->input)) {
>+		dev_err(dev, "Input device not idle, abort TH2CFG update\n");
>+		axiom_unlock_input_device(ts);
>+		return FW_UPLOAD_ERR_HW_ERROR;
>+	}
>+
>+	ret = axiom_u02_stop(ts);
>+	if (ret)
>+		goto err_swreset;
>+
>+	ret = axiom_zero_volatile_mem(ts);
>+	if (ret)
>+		goto err_swreset;
>+
>+	/* Skip to the first fw chunk */
>+	data += sizeof(struct axiom_fw_cfg_hdr);
>+	size -= sizeof(struct axiom_fw_cfg_hdr);
>+	*written += sizeof(struct axiom_fw_cfg_hdr);
>+
>+	axiom_set_runmode(ts, AXIOM_TCP_CFG_UPDATE_MODE);
>+
>+	while (size) {
>+		struct axiom_fw_cfg_chunk chunk;
>+		unsigned int chunk_len;
>+
>+		chunk_len = axiom_cfg_fw_prepare_chunk(&chunk, data);
>+		if (axiom_skip_cfg_chunk(ts, &chunk)) {
>+			dev_dbg(dev, "Skip TH2CFG usage u%02X\n", chunk.usage_num);
>+			goto next_chunk;
>+		}
>+
>+		ret = axiom_write_cfg_chunk(ts, &chunk);
>+		if (ret) {
>+			axiom_set_runmode(ts, AXIOM_TCP_MODE);
>+			goto err_swreset;
>+		}
>+
>+next_chunk:
>+		data += chunk_len;
>+		size -= chunk_len;
>+		*written += chunk_len;
>+	}
>+
>+	axiom_set_runmode(ts, AXIOM_TCP_MODE);
>+
>+	/* Ensure that the chunks are written correctly */
>+	ret = axiom_verify_volatile_mem(ts);
>+	if (ret) {
>+		dev_err(dev, "Failed to verify written config, abort\n");
>+		goto err_swreset;
>+	}
>+
>+	ret = axiom_u02_save_config(ts);
>+	if (ret)
>+		goto err_swreset;
>+
>+	/*
>+	 * TODO: Check if u02 start would be sufficient to load the new config
>+	 * values
>+	 */

It is not necessarily needed.

>+	ret = axiom_u02_swreset(ts);
>+	if (ret) {
>+		dev_err(dev, "Soft reset failed\n");
>+		goto err_unlock;
>+	}
>+
>+	ret = axiom_u33_read(ts, &ts->crc[AXIOM_CRC_CUR]);
>+	if (ret)
>+		goto err_unlock;
>+
>+	if (axiom_verify_crcs(ts))
>+		goto err_unlock;
>+
>+	/* Unlock before the input device gets unregistered */
>+	axiom_unlock_input_device(ts);
>+
>+	ret = axiom_update_input_dev(ts);
>+	if (ret) {
>+		dev_err(dev, "Input device update failed after TH2CFG firmware update\n");
>+		goto err_out;
>+	}
>+
>+	dev_info(dev, "TH2CFG update successful\n");
>+
>+	return FW_UPLOAD_ERR_NONE;
>+
>+err_swreset:
>+	axiom_u02_swreset(ts);
>+err_unlock:
>+	axiom_unlock_input_device(ts);
>+err_out:
>+	return ret == -ETIMEDOUT ? FW_UPLOAD_ERR_TIMEOUT : FW_UPLOAD_ERR_HW_ERROR;
>+}
>+
>+static void axiom_cfg_fw_cancel(struct fw_upload *fw_upload)
>+{
>+	struct axiom_data *ts = fw_upload->dd_handle;
>+	struct axiom_firmware *afw = &ts->fw[AXIOM_FW_CFG];
>+
>+	mutex_lock(&afw->lock);
>+	afw->cancel = true;
>+	mutex_unlock(&afw->lock);
>+}
>+
>+static void axiom_cfg_fw_cleanup(struct fw_upload *fw_upload)
>+{
>+	struct axiom_data *ts = fw_upload->dd_handle;
>+
>+	mutex_unlock(&ts->fwupdate_lock);
>+	pm_runtime_mark_last_busy(ts->dev);
>+	pm_runtime_put_sync_autosuspend(ts->dev);
>+}
>+
>+static const struct fw_upload_ops axiom_cfg_fw_upload_ops = {
>+	.prepare = axiom_cfg_fw_prepare,
>+	.write = axiom_cfg_fw_write,
>+	.poll_complete = axiom_fw_poll_complete,
>+	.cancel = axiom_cfg_fw_cancel,
>+	.cleanup = axiom_cfg_fw_cleanup,
>+};
>+
>+static void axiom_remove_axfw_fwl_action(void *data)
>+{
>+	struct axiom_data *ts = data;
>+
>+	firmware_upload_unregister(ts->fw[AXIOM_FW_AXFW].fwl);
>+}
>+
>+static void axiom_remove_cfg_fwl_action(void *data)
>+{
>+	struct axiom_data *ts = data;
>+
>+	firmware_upload_unregister(ts->fw[AXIOM_FW_CFG].fwl);
>+}
>+
>+static int axiom_register_fwl(struct axiom_data *ts)
>+{
>+	struct device *dev = ts->dev;
>+	struct fw_upload *fwl;
>+	char *fw_name;
>+	int ret;
>+
>+	if (!IS_ENABLED(CONFIG_FW_UPLOAD)) {
>+		dev_dbg(dev, "axfw and th2cfgbin update disabled\n");
>+		return 0;
>+	}
>+
>+	mutex_init(&ts->fw[AXIOM_FW_AXFW].lock);
>+	fw_name = kasprintf(GFP_KERNEL, "i2c:%s.axfw", dev_name(dev));
>+	fwl = firmware_upload_register(THIS_MODULE, ts->dev, fw_name,
>+				       &axiom_axfw_fw_upload_ops, ts);
>+	kfree(fw_name);
>+	if (IS_ERR(fwl))
>+		return dev_err_probe(dev, PTR_ERR(fwl),
>+				     "Failed to register firmware upload\n");
>+
>+	ret = devm_add_action_or_reset(dev, axiom_remove_axfw_fwl_action, ts);
>+	if (ret)
>+		return ret;
>+
>+	ts->fw[AXIOM_FW_AXFW].fwl = fwl;
>+
>+	mutex_init(&ts->fw[AXIOM_FW_CFG].lock);
>+	fw_name = kasprintf(GFP_KERNEL, "i2c:%s.th2cfgbin", dev_name(dev));
>+	fwl = firmware_upload_register(THIS_MODULE, ts->dev, fw_name,
>+				       &axiom_cfg_fw_upload_ops, ts);
>+	kfree(fw_name);
>+	if (IS_ERR(fwl))
>+		return dev_err_probe(dev, PTR_ERR(fwl),
>+				     "Failed to register cfg firmware upload\n");
>+
>+	ret = devm_add_action_or_reset(dev, axiom_remove_cfg_fwl_action, ts);
>+	if (ret)
>+		return ret;
>+
>+	ts->fw[AXIOM_FW_CFG].fwl = fwl;
>+
>+	return 0;
>+}
>+
>+/************************* Device handlig *************************************/
>+
>+#define AXIOM_SIMPLE_FW_DEVICE_ATTR(attr)					\
>+	static ssize_t								\
>+	fw_ ## attr ## _show(struct device *dev,				\
>+			     struct device_attribute *_attr, char *buf)		\
>+	{									\
>+		struct i2c_client *i2c = to_i2c_client(dev);			\
>+		struct axiom_data *ts = i2c_get_clientdata(i2c);		\
>+										\
>+		return sysfs_emit(buf, "%u\n", ts->fw_##attr);			\
>+	}									\
>+	static DEVICE_ATTR_RO(fw_##attr)
>+
>+AXIOM_SIMPLE_FW_DEVICE_ATTR(major);
>+AXIOM_SIMPLE_FW_DEVICE_ATTR(minor);
>+AXIOM_SIMPLE_FW_DEVICE_ATTR(rc);
>+
>+static ssize_t fw_status_show(struct device *dev,
>+			      struct device_attribute *attr, char *buf)
>+{
>+	struct i2c_client *i2c = to_i2c_client(dev);
>+	struct axiom_data *ts = i2c_get_clientdata(i2c);
>+	const char *val;
>+
>+	if (ts->fw_status)
>+		val = "production";
>+	else
>+		val = "engineering";
>+
>+	return sysfs_emit(buf, "%s\n", val);
>+}
>+static DEVICE_ATTR_RO(fw_status);
>+
>+static ssize_t fw_variant_show(struct device *dev,
>+			       struct device_attribute *attr, char *buf)
>+{
>+	struct i2c_client *i2c = to_i2c_client(dev);
>+	struct axiom_data *ts = i2c_get_clientdata(i2c);
>+	const char *val;
>+
>+	switch (ts->fw_variant) {
>+	case 0:
>+		val = "3d";
>+		break;
>+	case 1:
>+		val = "2d";
>+		break;
>+	case 3:
>+		val = "force";
>+		break;
>+	default:
>+		val = "unknown";
>+		break;
>+	}

The following are all the variants we currently support in order:
FW_VARIANTS = ["3D", "2D", "FORCE", "0D", "XL"]

>+
>+	return sysfs_emit(buf, "%s\n", val);
>+}
>+static DEVICE_ATTR_RO(fw_variant);
>+
>+static ssize_t device_id_show(struct device *dev,
>+			      struct device_attribute *attr, char *buf)
>+{
>+	struct i2c_client *i2c = to_i2c_client(dev);
>+	struct axiom_data *ts = i2c_get_clientdata(i2c);
>+
>+	return sysfs_emit(buf, "%u\n", ts->device_id);
>+}
>+static DEVICE_ATTR_RO(device_id);
>+
>+static ssize_t device_state_show(struct device *dev,
>+				 struct device_attribute *attr, char *buf)
>+{
>+	struct i2c_client *i2c = to_i2c_client(dev);
>+	struct axiom_data *ts = i2c_get_clientdata(i2c);
>+
>+	return sysfs_emit(buf, "%s\n", axiom_runmode_to_string(ts));
>+}
>+static DEVICE_ATTR_RO(device_state);
>+
>+static struct attribute *axiom_attrs[] = {
>+	&dev_attr_fw_major.attr,
>+	&dev_attr_fw_minor.attr,
>+	&dev_attr_fw_rc.attr,
>+	&dev_attr_fw_status.attr,
>+	&dev_attr_fw_variant.attr,
>+	&dev_attr_device_id.attr,
>+	&dev_attr_device_state.attr,
>+	NULL
>+};
>+ATTRIBUTE_GROUPS(axiom);
>+
>+static void axiom_poll(struct input_dev *input)
>+{
>+	struct axiom_data *ts = input_get_drvdata(input);
>+
>+	axiom_process_report(ts, AXIOM_U34, NULL, 0);
>+}
>+
>+static irqreturn_t axiom_irq(int irq, void *dev_id)
>+{
>+	struct axiom_data *ts = dev_id;
>+
>+	axiom_process_report(ts, AXIOM_U34, NULL, 0);
>+
>+	return IRQ_HANDLED;
>+}
>+
>+static int axiom_input_open(struct input_dev *dev)
>+{
>+	struct axiom_data *ts = input_get_drvdata(dev);
>+
>+	return pm_runtime_resume_and_get(ts->dev);
>+}
>+
>+static void axiom_input_close(struct input_dev *dev)
>+{
>+	struct axiom_data *ts = input_get_drvdata(dev);
>+
>+	pm_runtime_mark_last_busy(ts->dev);
>+	pm_runtime_put_sync_autosuspend(ts->dev);
>+}
>+
>+static int axiom_register_input_dev(struct axiom_data *ts,
>+				    bool update_in_process)
>+{
>+	struct device *dev = ts->dev;
>+	struct i2c_client *client = to_i2c_client(dev);
>+	struct input_dev *input;
>+	int ret;
>+
>+	input = input_allocate_device();
>+	if (!input) {
>+		dev_err(dev, "Failed to allocate input driver data\n");
>+		return -ENOMEM;
>+	}
>+
>+	input->dev.parent = dev;
>+	input->name = "TouchNetix aXiom Touchscreen";
>+	input->id.bustype = BUS_I2C;
>+	input->id.vendor = ts->jedec_id;
>+	input->id.product = ts->device_id;
>+	input->id.version = ts->silicon_rev;
>+
>+	/* Either follow the panel or the open user count, not both */
>+	if (!ts->is_panel_follower) {
>+		input->open = axiom_input_open;
>+		input->close = axiom_input_close;
>+	}
>+
>+	axiom_u64_cds_enabled(ts);
>+	input_set_abs_params(input, ABS_MT_POSITION_X, 0, AXIOM_MAX_XY - 1, 0, 0);
>+	input_set_abs_params(input, ABS_MT_POSITION_Y, 0, AXIOM_MAX_XY - 1, 0, 0);
>+	input_set_abs_params(input, ABS_MT_DISTANCE, 0, 127, 0, 0);
>+	if (ts->cds_enabled)
>+		input_set_abs_params(input, ABS_MT_PRESSURE, 0, 127, 0, 0);
>+
>+	touchscreen_parse_properties(input, true, &ts->prop);
>+
>+	axiom_u42_get_touchslots(ts);
>+	if (!ts->num_slots && update_in_process) {
>+		input_free_device(input);
>+		/*
>+		 * Skip input device registration but don't throw an error to
>+		 * not abort the update since some FW updates require a
>+		 * following CFG update to re-initialize the touchslot handling.
>+		 */
>+		if (update_in_process) {
>+			dev_info(dev, "No touchslots found after FW or CFG update, skip registering input device\n");
>+			return 0;
>+		}
>+
>+		dev_err(dev, "Error firmware has no touchslots enabled\n");
>+		return -EINVAL;
>+	}
>+
>+	ret = input_mt_init_slots(input, ts->num_slots, INPUT_MT_DIRECT);
>+	if (ret) {
>+		input_free_device(input);
>+		dev_err(dev, "Failed to init mt slots\n");
>+		return ret;
>+	}
>+
>+	/*
>+	 * Ensure that the IRQ setup is done only once since the handler belong
>+	 * to the i2c-dev whereas the input-poller belong to the input-dev. The
>+	 * input-dev can get unregistered during a firmware update to reflect
>+	 * the new firmware state. Therefore the input-poller setup must be done
>+	 * always.
>+	 */
>+	if (!ts->irq_setup_done && client->irq) {
>+		ret = devm_request_threaded_irq(dev, client->irq, NULL, axiom_irq,
>+						IRQF_ONESHOT, dev_name(dev), ts);
>+		if (ret) {
>+			dev_err(dev, "Failed to request IRQ\n");
>+			return ret;
>+		}
>+		ts->irq_setup_done = true;
>+	} else {
>+		ret = input_setup_polling(input, axiom_poll);
>+		if (ret) {
>+			input_free_device(input);
>+			dev_err(dev, "Setup polling mode failed\n");
>+			return ret;
>+		}
>+
>+		input_set_poll_interval(input, ts->poll_interval);
>+	}
>+
>+	input_set_drvdata(input, ts);
>+	ts->input = input;
>+
>+	ret = input_register_device(input);
>+	if (ret) {
>+		input_free_device(input);
>+		ts->input = NULL;
>+		dev_err(dev, "Failed to register input device\n");
>+	};
>+
>+	return ret;
>+}
>+
>+static int axiom_update_input_dev(struct axiom_data *ts)
>+{
>+	axiom_unregister_input_dev(ts);
>+
>+	return axiom_register_input_dev(ts, true);
>+}
>+
>+static int axiom_parse_firmware(struct axiom_data *ts)
>+{
>+	struct device *dev = ts->dev;
>+	struct gpio_desc *gpio;
>+	int ret;
>+
>+	ts->supplies[0].supply = "vddi";
>+	ts->supplies[1].supply = "vdda";
>+	ts->num_supplies = ARRAY_SIZE(ts->supplies);
>+
>+	ret = devm_regulator_bulk_get(dev, ts->num_supplies, ts->supplies);
>+	if (ret)
>+		return dev_err_probe(dev, ret,
>+				     "Failed to get power supplies\n");
>+
>+	gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
>+	if (IS_ERR(gpio))
>+		return dev_err_probe(dev, PTR_ERR(gpio),
>+				     "Failed to get reset GPIO\n");
>+	ts->reset_gpio = gpio;
>+
>+	ts->poll_interval = AXIOM_DEFAULT_POLL_INTERVAL_MS;
>+	device_property_read_u32(dev, "poll-interval", &ts->poll_interval);
>+
>+	return 0;
>+}
>+
>+static int axiom_power_device(struct axiom_data *ts, unsigned int enable)
>+{
>+	struct device *dev = ts->dev;
>+	int ret;
>+
>+	if (!enable) {
>+		regulator_bulk_disable(ts->num_supplies, ts->supplies);
>+		return 0;
>+	}
>+
>+	ret = regulator_bulk_enable(ts->num_supplies, ts->supplies);
>+	if (ret) {
>+		dev_err(dev, "Failed to enable power supplies\n");
>+		return ret;
>+	}
>+
>+	gpiod_set_value_cansleep(ts->reset_gpio, 1);
>+	fsleep(2000);
>+	gpiod_set_value_cansleep(ts->reset_gpio, 0);
>+
>+	fsleep(AXIOM_STARTUP_TIME_MS);
>+
>+	return 0;
>+}
>+
>+static int axiom_panel_prepared(struct drm_panel_follower *follower)
>+{
>+	struct axiom_data *ts = container_of(follower, struct axiom_data,
>+					     panel_follower);
>+
>+	return pm_runtime_resume_and_get(ts->dev);
>+}
>+
>+static int axiom_panel_unpreparing(struct drm_panel_follower *follower)
>+{
>+	struct axiom_data *ts = container_of(follower, struct axiom_data,
>+					     panel_follower);
>+
>+	return pm_runtime_put_sync_suspend(ts->dev);
>+}
>+
>+static const struct drm_panel_follower_funcs axiom_panel_follower_funcs = {
>+	.panel_prepared = axiom_panel_prepared,
>+	.panel_unpreparing = axiom_panel_unpreparing,
>+};
>+
>+static int axiom_register_panel_follower(struct axiom_data *ts)
>+{
>+	struct device *dev = ts->dev;
>+
>+	if (!drm_is_panel_follower(dev))
>+		return 0;
>+
>+	if (device_can_wakeup(dev)) {
>+		dev_warn(dev, "Can't follow panel if marked as wakup device\n");
>+		return 0;
>+	}
>+
>+	ts->panel_follower.funcs = &axiom_panel_follower_funcs;
>+	ts->is_panel_follower = true;
>+
>+	return devm_drm_panel_add_follower(dev, &ts->panel_follower);
>+}
>+
>+static int axiom_i2c_probe(struct i2c_client *client)
>+{
>+	struct device *dev = &client->dev;
>+	struct axiom_data *ts;
>+	int ret;
>+
>+	ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
>+	if (!ts)
>+		return dev_err_probe(dev, -ENOMEM,
>+				     "Failed to allocate driver data\n");
>+
>+	ts->regmap = devm_regmap_init_i2c(client, &axiom_i2c_regmap_config);
>+	if (IS_ERR(ts->regmap))
>+		return dev_err_probe(dev, PTR_ERR(ts->regmap),
>+				     "Failed to initialize regmap\n");
>+
>+	i2c_set_clientdata(client, ts);
>+	ts->dev = dev;
>+
>+	init_completion(&ts->boot_complete.completion);
>+	init_completion(&ts->nvm_write.completion);
>+	mutex_init(&ts->fwupdate_lock);
>+
>+	ret = axiom_register_fwl(ts);
>+	if (ret)
>+		return ret;
>+
>+	ret = axiom_parse_firmware(ts);
>+	if (ret)
>+		return ret;
>+
>+	ret = axiom_power_device(ts, 1);
>+	if (ret)
>+		return dev_err_probe(dev, ret, "Failed to power-on device\n");
>+
>+	pm_runtime_set_autosuspend_delay(dev, 10 * MSEC_PER_SEC);
>+	pm_runtime_use_autosuspend(dev);
>+	pm_runtime_set_active(dev);
>+	pm_runtime_get_noresume(dev);
>+	ret = devm_pm_runtime_enable(dev);
>+	if (ret)
>+		return dev_err_probe(dev, ret, "Failed to enable pm-runtime\n");
>+
>+	ret = axiom_register_panel_follower(ts);
>+	if (ret)
>+		return dev_err_probe(dev, ret, "Failed to register panel follower\n");
>+
>+	ret = axiom_u31_device_discover(ts);
>+	/*
>+	 * Register the device to allow FW updates in case that the current FW
>+	 * doesn't support the required driver usages or if the device is in
>+	 * bootloader mode.
>+	 */
>+	if (ret && ret == -EACCES && IS_ENABLED(CONFIG_FW_UPLOAD)) {
>+		dev_warn(dev, "Device discovery failed, wait for user fw update\n");
>+		pm_runtime_mark_last_busy(dev);
>+		pm_runtime_put_sync_autosuspend(dev);
>+		return 0;
>+	} else if (ret) {
>+		pm_runtime_put_sync(dev);
>+		return dev_err_probe(dev, ret, "Device discovery failed\n");
>+	}
>+
>+	ret = axiom_register_input_dev(ts, false);
>+	pm_runtime_mark_last_busy(dev);
>+	pm_runtime_put_sync_autosuspend(dev);
>+	if (ret && IS_ENABLED(CONFIG_FW_UPLOAD))
>+		dev_warn(dev, "Failed to register the input device, wait for user fw update\n");
>+	else if (ret)
>+		return dev_err_probe(dev, ret, "Failed to register input device\n");
>+
>+	return 0;
>+}
>+
>+static void axiom_i2c_remove(struct i2c_client *client)
>+{
>+	struct axiom_data *ts = i2c_get_clientdata(client);
>+
>+	axiom_unregister_input_dev(ts);
>+}
>+
>+static int axiom_runtime_suspend(struct device *dev)
>+{
>+	struct axiom_data *ts = dev_get_drvdata(dev);
>+	struct i2c_client *client = to_i2c_client(dev);
>+
>+	if (client->irq && ts->irq_setup_done)
>+		disable_irq(client->irq);
>+
>+	return axiom_power_device(ts, 0);
>+}
>+
>+static int axiom_runtime_resume(struct device *dev)
>+{
>+	struct axiom_data *ts = dev_get_drvdata(dev);
>+	struct i2c_client *client = to_i2c_client(dev);
>+	int ret;
>+
>+	ret = axiom_power_device(ts, 1);
>+	if (ret)
>+		return ret;
>+
>+	if (client->irq && ts->irq_setup_done)
>+		enable_irq(client->irq);
>+
>+	return 0;
>+}
>+
>+static DEFINE_RUNTIME_DEV_PM_OPS(axiom_pm_ops, axiom_runtime_suspend,
>+				 axiom_runtime_resume, NULL);
>+
>+static const struct i2c_device_id axiom_i2c_id_table[] = {
>+	{ "ax54a" },
>+	{ },
>+};
>+MODULE_DEVICE_TABLE(i2c, axiom_i2c_id_table);
>+
>+static const struct of_device_id axiom_of_match[] = {
>+	{ .compatible = "touchnetix,ax54a", },
>+	{ }
>+};
>+MODULE_DEVICE_TABLE(of, axiom_of_match);
>+
>+static struct i2c_driver axiom_i2c_driver = {
>+	.driver = {
>+		   .name = KBUILD_MODNAME,
>+		   .dev_groups = axiom_groups,
>+		   .pm = pm_ptr(&axiom_pm_ops),
>+		   .of_match_table = axiom_of_match,
>+	},
>+	.id_table = axiom_i2c_id_table,
>+	.probe = axiom_i2c_probe,
>+	.remove = axiom_i2c_remove,
>+};
>+module_i2c_driver(axiom_i2c_driver);
>+
>+MODULE_DESCRIPTION("TouchNetix aXiom touchscreen I2C bus driver");
>+MODULE_LICENSE("GPL");
>
>-- 
>2.47.3
>


^ permalink raw reply

* Re: [PATCH v3 4/4] Input: charlieplex_keypad: add GPIO charlieplex keypad
From: Dmitry Torokhov @ 2026-02-25 17:14 UTC (permalink / raw)
  To: Hugo Villeneuve
  Cc: Andy Shevchenko, robin, andy, geert, robh, krzk+dt, conor+dt,
	hvilleneuve, mkorpershoek, matthias.bgg,
	angelogioacchino.delregno, lee, alexander.sverdlin, marek.vasut,
	akurz, devicetree, linux-kernel, linux-input, linux-arm-kernel,
	linux-mediatek
In-Reply-To: <20260225115652.8beb1979df3824f7a95d22bc@hugovil.com>

On Wed, Feb 25, 2026 at 11:56:52AM -0500, Hugo Villeneuve wrote:
> On Wed, 25 Feb 2026 11:41:55 -0500
> Hugo Villeneuve <hugo@hugovil.com> wrote:
> 
> > Hi Andy,
> > thank you for the review.
> > 
> > On Wed, 25 Feb 2026 18:12:13 +0200
> > Andy Shevchenko <andriy.shevchenko@intel.com> wrote:
> > 
> > > On Wed, Feb 25, 2026 at 10:54:01AM -0500, Hugo Villeneuve wrote:
> > > 
> > > > Add support for GPIO-based charlieplex keypad, allowing to control
> > > > N^2-N keys using N GPIO lines.
> > > > 
> > > > Reuse matrix keypad keymap to simplify, even if there is no concept
> > > > of rows and columns in this type of keyboard.
> > > 
> > > ...
> > > 
> > > > +/*
> > > > + *  GPIO driven charlieplex keypad driver
> > > > + *
> > > > + *  Copyright (c) 2025 Hugo Villeneuve <hvilleneuve@dimonoff.com>
> > > > + *
> > > > + *  Based on matrix_keyboard.c
> > > 
> > > A single space after asterisk is enough.
> > 
> > Ok, leftover from copy/paste from matrix_keyboard.c :)
> > 
> > > 
> > > > + */
> > > 
> > > ...
> > > 
> > > + bitops.h
> > > 
> > > > +#include <linux/delay.h>
> > > 
> > > + dev_printk.h
> > > + device/devres.h
> > > + err.h
> > > 
> > > > +#include <linux/gpio/consumer.h>
> > > > +#include <linux/input.h>
> > > > +#include <linux/input/matrix_keypad.h>
> > > 
> > > + math.h
> > 
> > Ok.
> > 
> > 
> > > 
> > > > +#include <linux/module.h>
> > > 
> > > > +#include <linux/of.h>
> > > 
> > > Is this in use? Or you wanted mod_devicetable.h for OF ID table?
> > 
> > I need only OF ID table, so will replace with mod_devicetable.h.
> 
> Hi Andy,
> finally I need <linux/of.h> for of_match_ptr()...
> 
> But I will keep <mod_devicetable.h> ...

Do we need the dependency on OF? We may include of match pointer
unconditionally and the driver could be used on ACPI systems with
PRP0001 HID.

Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH v3 4/4] Input: charlieplex_keypad: add GPIO charlieplex keypad
From: Dmitry Torokhov @ 2026-02-25 17:12 UTC (permalink / raw)
  To: Hugo Villeneuve
  Cc: Andy Shevchenko, robin, andy, geert, robh, krzk+dt, conor+dt,
	hvilleneuve, mkorpershoek, matthias.bgg,
	angelogioacchino.delregno, lee, alexander.sverdlin, marek.vasut,
	akurz, devicetree, linux-kernel, linux-input, linux-arm-kernel,
	linux-mediatek
In-Reply-To: <20260225114155.3ee2efb002aa0f52a905f535@hugovil.com>

Hi Hugo,

On Wed, Feb 25, 2026 at 11:41:55AM -0500, Hugo Villeneuve wrote:
> Hi Andy,
> thank you for the review.
> 
> On Wed, 25 Feb 2026 18:12:13 +0200
> Andy Shevchenko <andriy.shevchenko@intel.com> wrote:
> 
> > On Wed, Feb 25, 2026 at 10:54:01AM -0500, Hugo Villeneuve wrote:
> > 
> > > Add support for GPIO-based charlieplex keypad, allowing to control
> > > N^2-N keys using N GPIO lines.
> > > 
> > > Reuse matrix keypad keymap to simplify, even if there is no concept
> > > of rows and columns in this type of keyboard.
> > 
> > ...
> > 
> > > +/*
> > > + *  GPIO driven charlieplex keypad driver
> > > + *
> > > + *  Copyright (c) 2025 Hugo Villeneuve <hvilleneuve@dimonoff.com>
> > > + *
> > > + *  Based on matrix_keyboard.c
> > 
> > A single space after asterisk is enough.
> 
> Ok, leftover from copy/paste from matrix_keyboard.c :)
> 
> > 
> > > + */
> > 
> > ...
> > 
> > + bitops.h
> > 
> > > +#include <linux/delay.h>
> > 
> > + dev_printk.h
> > + device/devres.h
> > + err.h
> > 
> > > +#include <linux/gpio/consumer.h>
> > > +#include <linux/input.h>
> > > +#include <linux/input/matrix_keypad.h>
> > 
> > + math.h
> 
> Ok.
> 
> 
> > 
> > > +#include <linux/module.h>
> > 
> > > +#include <linux/of.h>
> > 
> > Is this in use? Or you wanted mod_devicetable.h for OF ID table?
> 
> I need only OF ID table, so will replace with mod_devicetable.h.
> 
> 
> > 
> > > +#include <linux/platform_device.h>
> > > +#include <linux/property.h>
> > > +#include <linux/types.h>
> > 
> > ...
> > 
> > > +	for (code = 0, oline = 0; oline < keypad->nlines; oline++) {
> > > +		DECLARE_BITMAP(values, MATRIX_MAX_ROWS);
> > > +		int iline;
> > 
> > > +		int rc;
> > 
> > I think Dmitry prefers 'error' name for this kind of variables.
> 
> I hate using "error", can be so misleading :)
> 
> I would prefer to use "rc" everywhere, but if Dmitry chimes in and
> specifies "error" or "err", then so it will be.

Yes, I prefer err or error for variables that carry error code or 0.
This allows to write

	error = action(...);
	if (error) {
		// handle it
	}

which is very clear IMO.


> > > +
> > > +	err = input_register_device(keypad->input_dev);
> > > +	if (err)
> > > +		return err;
> > 
> > > +	platform_set_drvdata(pdev, keypad);
> > 
> > Is this needed?
> 
> No, will remove it, and replace last lines with:
> 
>    return input_register_device(keypad->input_dev);

Please use

	err = input_register_device(...);
	if (err)
		return err;

	return 0;

It clearly differentiates error an normal paths, shows that function
returns 0 and not anything else on success, and allows to reorder
or add additional actions easily.

Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH v3 4/4] Input: charlieplex_keypad: add GPIO charlieplex keypad
From: Hugo Villeneuve @ 2026-02-25 16:56 UTC (permalink / raw)
  To: Hugo Villeneuve
  Cc: Andy Shevchenko, robin, andy, geert, robh, krzk+dt, conor+dt,
	dmitry.torokhov, hvilleneuve, mkorpershoek, matthias.bgg,
	angelogioacchino.delregno, lee, alexander.sverdlin, marek.vasut,
	akurz, devicetree, linux-kernel, linux-input, linux-arm-kernel,
	linux-mediatek
In-Reply-To: <20260225114155.3ee2efb002aa0f52a905f535@hugovil.com>

On Wed, 25 Feb 2026 11:41:55 -0500
Hugo Villeneuve <hugo@hugovil.com> wrote:

> Hi Andy,
> thank you for the review.
> 
> On Wed, 25 Feb 2026 18:12:13 +0200
> Andy Shevchenko <andriy.shevchenko@intel.com> wrote:
> 
> > On Wed, Feb 25, 2026 at 10:54:01AM -0500, Hugo Villeneuve wrote:
> > 
> > > Add support for GPIO-based charlieplex keypad, allowing to control
> > > N^2-N keys using N GPIO lines.
> > > 
> > > Reuse matrix keypad keymap to simplify, even if there is no concept
> > > of rows and columns in this type of keyboard.
> > 
> > ...
> > 
> > > +/*
> > > + *  GPIO driven charlieplex keypad driver
> > > + *
> > > + *  Copyright (c) 2025 Hugo Villeneuve <hvilleneuve@dimonoff.com>
> > > + *
> > > + *  Based on matrix_keyboard.c
> > 
> > A single space after asterisk is enough.
> 
> Ok, leftover from copy/paste from matrix_keyboard.c :)
> 
> > 
> > > + */
> > 
> > ...
> > 
> > + bitops.h
> > 
> > > +#include <linux/delay.h>
> > 
> > + dev_printk.h
> > + device/devres.h
> > + err.h
> > 
> > > +#include <linux/gpio/consumer.h>
> > > +#include <linux/input.h>
> > > +#include <linux/input/matrix_keypad.h>
> > 
> > + math.h
> 
> Ok.
> 
> 
> > 
> > > +#include <linux/module.h>
> > 
> > > +#include <linux/of.h>
> > 
> > Is this in use? Or you wanted mod_devicetable.h for OF ID table?
> 
> I need only OF ID table, so will replace with mod_devicetable.h.

Hi Andy,
finally I need <linux/of.h> for of_match_ptr()...

But I will keep <mod_devicetable.h> ...


> > 
> > > +#include <linux/platform_device.h>
> > > +#include <linux/property.h>
> > > +#include <linux/types.h>
> > 
> > ...
> > 
> > > +	for (code = 0, oline = 0; oline < keypad->nlines; oline++) {
> > > +		DECLARE_BITMAP(values, MATRIX_MAX_ROWS);
> > > +		int iline;
> > 
> > > +		int rc;
> > 
> > I think Dmitry prefers 'error' name for this kind of variables.
> 
> I hate using "error", can be so misleading :)
> 
> I would prefer to use "rc" everywhere, but if Dmitry chimes in and
> specifies "error" or "err", then so it will be.
> 
> 
> > 
> > > +		/* Activate only one line as output at a time. */
> > > +		gpiod_direction_output(keypad->line_gpios->desc[oline], 1);
> > > +
> > > +		if (keypad->settling_time_us)
> > > +			fsleep(keypad->settling_time_us);
> > > +
> > > +		/* Read input on all other lines. */
> > > +		rc = gpiod_get_array_value_cansleep(keypad->line_gpios->ndescs,
> > > +						    keypad->line_gpios->desc,
> > > +						    keypad->line_gpios->info, values);
> > > +		if (rc)
> > > +			return;
> > > +
> > > +		for (iline = 0; iline < keypad->nlines; iline++) {
> > > +			if (iline == oline)
> > > +				continue; /* Do not read active output line. */
> > > +
> > > +			/* Check if GPIO is asserted. */
> > > +			if (test_bit(iline, values)) {
> > > +				code = MATRIX_SCAN_CODE(oline, iline,
> > > +							get_count_order(keypad->nlines));
> > > +				/*
> > > +				 * Exit loop immediately since we cannot detect
> > > +				 * more than one key press at a time.
> > > +				 */
> > > +				break;
> > > +			}
> > > +		}
> > > +
> > > +		gpiod_direction_input(keypad->line_gpios->desc[oline]);
> > > +
> > > +		if (code)
> > > +			break;
> > > +	}
> > 
> > ...
> > 
> > > +static int charlieplex_keypad_init_gpio(struct platform_device *pdev,
> > > +					struct charlieplex_keypad *keypad)
> > > +{
> > > +	int i;
> > 
> > Why signed? But see below as well.
> 
> Will switch to unsigned.
> 
> 
> > 
> > > +	keypad->line_gpios = devm_gpiod_get_array(&pdev->dev, "line", GPIOD_IN);
> > > +	if (IS_ERR(keypad->line_gpios))
> > > +		return PTR_ERR(keypad->line_gpios);
> > > +
> > > +	keypad->nlines = keypad->line_gpios->ndescs;
> > > +
> > > +	if (keypad->nlines > MATRIX_MAX_ROWS)
> > > +		return -EINVAL;
> > 
> > > +	for (i = 0; i < keypad->nlines; i++)
> > 
> > iterator is local to the loop, hence
> > 
> > 	for (unsigned int i = 0; i < keypad->nlines; i++)
> 
> Ok
> 
> 
> > 
> > > +		gpiod_set_consumer_name(keypad->line_gpios->desc[i], "charlieplex_kbd_line");
> > > +
> > > +	return 0;
> > > +}
> > 
> > ...
> > 
> > > +static int charlieplex_keypad_probe(struct platform_device *pdev)
> > > +{
> > > +	struct charlieplex_keypad *keypad;
> > > +	unsigned int debounce_interval_ms;
> > > +	unsigned int poll_interval_ms;
> > > +	struct input_dev *input_dev;
> > 
> > > +	int err;
> > 
> > The naming is even inconsistent between the functions...
> 
> Agreed, will fix as stated above.
> 
> 
> > 
> > > +	keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL);
> > > +	if (!keypad)
> > > +		return -ENOMEM;
> > > +
> > > +	input_dev = devm_input_allocate_device(&pdev->dev);
> > > +	if (!input_dev)
> > > +		return -ENOMEM;
> > > +
> > > +	keypad->input_dev = input_dev;
> > > +
> > > +	device_property_read_u32(&pdev->dev, "poll-interval", &poll_interval_ms);
> > > +	device_property_read_u32(&pdev->dev, "debounce-delay-ms", &debounce_interval_ms);
> > > +	device_property_read_u32(&pdev->dev, "settling-time-us", &keypad->settling_time_us);
> > > +
> > > +	keypad->current_code = -1;
> > > +	keypad->debounce_code = -1;
> > > +	keypad->debounce_threshold = DIV_ROUND_UP(debounce_interval_ms, poll_interval_ms);
> > > +
> > > +	err = charlieplex_keypad_init_gpio(pdev, keypad);
> > > +	if (err)
> > > +		return err;
> > > +
> > > +	input_dev->name		= pdev->name;
> > > +	input_dev->id.bustype	= BUS_HOST;
> > > +
> > > +	err = matrix_keypad_build_keymap(NULL, NULL, keypad->nlines,
> > > +					 keypad->nlines, NULL, input_dev);
> > > +	if (err)
> > > +		dev_err_probe(&pdev->dev, -ENOMEM, "failed to build keymap\n");
> > > +
> > > +	if (device_property_read_bool(&pdev->dev, "autorepeat"))
> > > +		__set_bit(EV_REP, input_dev->evbit);
> > > +
> > > +	input_set_capability(input_dev, EV_MSC, MSC_SCAN);
> > > +
> > > +	err = input_setup_polling(input_dev, charlieplex_keypad_poll);
> > > +	if (err)
> > > +		dev_err_probe(&pdev->dev, err, "unable to set up polling\n");
> > > +
> > > +	input_set_poll_interval(input_dev, poll_interval_ms);
> > > +
> > > +	input_set_drvdata(input_dev, keypad);
> > > +
> > > +	err = input_register_device(keypad->input_dev);
> > > +	if (err)
> > > +		return err;
> > 
> > > +	platform_set_drvdata(pdev, keypad);
> > 
> > Is this needed?
> 
> No, will remove it, and replace last lines with:
> 
>    return input_register_device(keypad->input_dev);
> 
> 
> > 
> > > +	return 0;
> > > +}
> > 
> > -- 
> > With Best Regards,
> > Andy Shevchenko
> > 
> > 
> > 
> 
> Hugo Villeneuve


-- 
Hugo Villeneuve

^ permalink raw reply

* Re: [PATCH v3 4/4] Input: charlieplex_keypad: add GPIO charlieplex keypad
From: Hugo Villeneuve @ 2026-02-25 16:41 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: robin, andy, geert, robh, krzk+dt, conor+dt, dmitry.torokhov,
	hvilleneuve, mkorpershoek, matthias.bgg,
	angelogioacchino.delregno, lee, alexander.sverdlin, marek.vasut,
	akurz, devicetree, linux-kernel, linux-input, linux-arm-kernel,
	linux-mediatek
In-Reply-To: <aZ8fXXGMx3fk7gKs@smile.fi.intel.com>

Hi Andy,
thank you for the review.

On Wed, 25 Feb 2026 18:12:13 +0200
Andy Shevchenko <andriy.shevchenko@intel.com> wrote:

> On Wed, Feb 25, 2026 at 10:54:01AM -0500, Hugo Villeneuve wrote:
> 
> > Add support for GPIO-based charlieplex keypad, allowing to control
> > N^2-N keys using N GPIO lines.
> > 
> > Reuse matrix keypad keymap to simplify, even if there is no concept
> > of rows and columns in this type of keyboard.
> 
> ...
> 
> > +/*
> > + *  GPIO driven charlieplex keypad driver
> > + *
> > + *  Copyright (c) 2025 Hugo Villeneuve <hvilleneuve@dimonoff.com>
> > + *
> > + *  Based on matrix_keyboard.c
> 
> A single space after asterisk is enough.

Ok, leftover from copy/paste from matrix_keyboard.c :)

> 
> > + */
> 
> ...
> 
> + bitops.h
> 
> > +#include <linux/delay.h>
> 
> + dev_printk.h
> + device/devres.h
> + err.h
> 
> > +#include <linux/gpio/consumer.h>
> > +#include <linux/input.h>
> > +#include <linux/input/matrix_keypad.h>
> 
> + math.h

Ok.


> 
> > +#include <linux/module.h>
> 
> > +#include <linux/of.h>
> 
> Is this in use? Or you wanted mod_devicetable.h for OF ID table?

I need only OF ID table, so will replace with mod_devicetable.h.


> 
> > +#include <linux/platform_device.h>
> > +#include <linux/property.h>
> > +#include <linux/types.h>
> 
> ...
> 
> > +	for (code = 0, oline = 0; oline < keypad->nlines; oline++) {
> > +		DECLARE_BITMAP(values, MATRIX_MAX_ROWS);
> > +		int iline;
> 
> > +		int rc;
> 
> I think Dmitry prefers 'error' name for this kind of variables.

I hate using "error", can be so misleading :)

I would prefer to use "rc" everywhere, but if Dmitry chimes in and
specifies "error" or "err", then so it will be.


> 
> > +		/* Activate only one line as output at a time. */
> > +		gpiod_direction_output(keypad->line_gpios->desc[oline], 1);
> > +
> > +		if (keypad->settling_time_us)
> > +			fsleep(keypad->settling_time_us);
> > +
> > +		/* Read input on all other lines. */
> > +		rc = gpiod_get_array_value_cansleep(keypad->line_gpios->ndescs,
> > +						    keypad->line_gpios->desc,
> > +						    keypad->line_gpios->info, values);
> > +		if (rc)
> > +			return;
> > +
> > +		for (iline = 0; iline < keypad->nlines; iline++) {
> > +			if (iline == oline)
> > +				continue; /* Do not read active output line. */
> > +
> > +			/* Check if GPIO is asserted. */
> > +			if (test_bit(iline, values)) {
> > +				code = MATRIX_SCAN_CODE(oline, iline,
> > +							get_count_order(keypad->nlines));
> > +				/*
> > +				 * Exit loop immediately since we cannot detect
> > +				 * more than one key press at a time.
> > +				 */
> > +				break;
> > +			}
> > +		}
> > +
> > +		gpiod_direction_input(keypad->line_gpios->desc[oline]);
> > +
> > +		if (code)
> > +			break;
> > +	}
> 
> ...
> 
> > +static int charlieplex_keypad_init_gpio(struct platform_device *pdev,
> > +					struct charlieplex_keypad *keypad)
> > +{
> > +	int i;
> 
> Why signed? But see below as well.

Will switch to unsigned.


> 
> > +	keypad->line_gpios = devm_gpiod_get_array(&pdev->dev, "line", GPIOD_IN);
> > +	if (IS_ERR(keypad->line_gpios))
> > +		return PTR_ERR(keypad->line_gpios);
> > +
> > +	keypad->nlines = keypad->line_gpios->ndescs;
> > +
> > +	if (keypad->nlines > MATRIX_MAX_ROWS)
> > +		return -EINVAL;
> 
> > +	for (i = 0; i < keypad->nlines; i++)
> 
> iterator is local to the loop, hence
> 
> 	for (unsigned int i = 0; i < keypad->nlines; i++)

Ok


> 
> > +		gpiod_set_consumer_name(keypad->line_gpios->desc[i], "charlieplex_kbd_line");
> > +
> > +	return 0;
> > +}
> 
> ...
> 
> > +static int charlieplex_keypad_probe(struct platform_device *pdev)
> > +{
> > +	struct charlieplex_keypad *keypad;
> > +	unsigned int debounce_interval_ms;
> > +	unsigned int poll_interval_ms;
> > +	struct input_dev *input_dev;
> 
> > +	int err;
> 
> The naming is even inconsistent between the functions...

Agreed, will fix as stated above.


> 
> > +	keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL);
> > +	if (!keypad)
> > +		return -ENOMEM;
> > +
> > +	input_dev = devm_input_allocate_device(&pdev->dev);
> > +	if (!input_dev)
> > +		return -ENOMEM;
> > +
> > +	keypad->input_dev = input_dev;
> > +
> > +	device_property_read_u32(&pdev->dev, "poll-interval", &poll_interval_ms);
> > +	device_property_read_u32(&pdev->dev, "debounce-delay-ms", &debounce_interval_ms);
> > +	device_property_read_u32(&pdev->dev, "settling-time-us", &keypad->settling_time_us);
> > +
> > +	keypad->current_code = -1;
> > +	keypad->debounce_code = -1;
> > +	keypad->debounce_threshold = DIV_ROUND_UP(debounce_interval_ms, poll_interval_ms);
> > +
> > +	err = charlieplex_keypad_init_gpio(pdev, keypad);
> > +	if (err)
> > +		return err;
> > +
> > +	input_dev->name		= pdev->name;
> > +	input_dev->id.bustype	= BUS_HOST;
> > +
> > +	err = matrix_keypad_build_keymap(NULL, NULL, keypad->nlines,
> > +					 keypad->nlines, NULL, input_dev);
> > +	if (err)
> > +		dev_err_probe(&pdev->dev, -ENOMEM, "failed to build keymap\n");
> > +
> > +	if (device_property_read_bool(&pdev->dev, "autorepeat"))
> > +		__set_bit(EV_REP, input_dev->evbit);
> > +
> > +	input_set_capability(input_dev, EV_MSC, MSC_SCAN);
> > +
> > +	err = input_setup_polling(input_dev, charlieplex_keypad_poll);
> > +	if (err)
> > +		dev_err_probe(&pdev->dev, err, "unable to set up polling\n");
> > +
> > +	input_set_poll_interval(input_dev, poll_interval_ms);
> > +
> > +	input_set_drvdata(input_dev, keypad);
> > +
> > +	err = input_register_device(keypad->input_dev);
> > +	if (err)
> > +		return err;
> 
> > +	platform_set_drvdata(pdev, keypad);
> 
> Is this needed?

No, will remove it, and replace last lines with:

   return input_register_device(keypad->input_dev);


> 
> > +	return 0;
> > +}
> 
> -- 
> With Best Regards,
> Andy Shevchenko
> 
> 
> 

Hugo Villeneuve

^ permalink raw reply

* Re: [PATCH v3 4/4] Input: charlieplex_keypad: add GPIO charlieplex keypad
From: Andy Shevchenko @ 2026-02-25 16:12 UTC (permalink / raw)
  To: Hugo Villeneuve
  Cc: robin, andy, geert, robh, krzk+dt, conor+dt, dmitry.torokhov,
	hvilleneuve, mkorpershoek, matthias.bgg,
	angelogioacchino.delregno, lee, alexander.sverdlin, marek.vasut,
	akurz, devicetree, linux-kernel, linux-input, linux-arm-kernel,
	linux-mediatek
In-Reply-To: <20260225155409.612478-5-hugo@hugovil.com>

On Wed, Feb 25, 2026 at 10:54:01AM -0500, Hugo Villeneuve wrote:

> Add support for GPIO-based charlieplex keypad, allowing to control
> N^2-N keys using N GPIO lines.
> 
> Reuse matrix keypad keymap to simplify, even if there is no concept
> of rows and columns in this type of keyboard.

...

> +/*
> + *  GPIO driven charlieplex keypad driver
> + *
> + *  Copyright (c) 2025 Hugo Villeneuve <hvilleneuve@dimonoff.com>
> + *
> + *  Based on matrix_keyboard.c

A single space after asterisk is enough.

> + */

...

+ bitops.h

> +#include <linux/delay.h>

+ dev_printk.h
+ device/devres.h
+ err.h

> +#include <linux/gpio/consumer.h>
> +#include <linux/input.h>
> +#include <linux/input/matrix_keypad.h>

+ math.h

> +#include <linux/module.h>

> +#include <linux/of.h>

Is this in use? Or you wanted mod_devicetable.h for OF ID table?

> +#include <linux/platform_device.h>
> +#include <linux/property.h>
> +#include <linux/types.h>

...

> +	for (code = 0, oline = 0; oline < keypad->nlines; oline++) {
> +		DECLARE_BITMAP(values, MATRIX_MAX_ROWS);
> +		int iline;

> +		int rc;

I think Dmitry prefers 'error' name for this kind of variables.

> +		/* Activate only one line as output at a time. */
> +		gpiod_direction_output(keypad->line_gpios->desc[oline], 1);
> +
> +		if (keypad->settling_time_us)
> +			fsleep(keypad->settling_time_us);
> +
> +		/* Read input on all other lines. */
> +		rc = gpiod_get_array_value_cansleep(keypad->line_gpios->ndescs,
> +						    keypad->line_gpios->desc,
> +						    keypad->line_gpios->info, values);
> +		if (rc)
> +			return;
> +
> +		for (iline = 0; iline < keypad->nlines; iline++) {
> +			if (iline == oline)
> +				continue; /* Do not read active output line. */
> +
> +			/* Check if GPIO is asserted. */
> +			if (test_bit(iline, values)) {
> +				code = MATRIX_SCAN_CODE(oline, iline,
> +							get_count_order(keypad->nlines));
> +				/*
> +				 * Exit loop immediately since we cannot detect
> +				 * more than one key press at a time.
> +				 */
> +				break;
> +			}
> +		}
> +
> +		gpiod_direction_input(keypad->line_gpios->desc[oline]);
> +
> +		if (code)
> +			break;
> +	}

...

> +static int charlieplex_keypad_init_gpio(struct platform_device *pdev,
> +					struct charlieplex_keypad *keypad)
> +{
> +	int i;

Why signed? But see below as well.

> +	keypad->line_gpios = devm_gpiod_get_array(&pdev->dev, "line", GPIOD_IN);
> +	if (IS_ERR(keypad->line_gpios))
> +		return PTR_ERR(keypad->line_gpios);
> +
> +	keypad->nlines = keypad->line_gpios->ndescs;
> +
> +	if (keypad->nlines > MATRIX_MAX_ROWS)
> +		return -EINVAL;

> +	for (i = 0; i < keypad->nlines; i++)

iterator is local to the loop, hence

	for (unsigned int i = 0; i < keypad->nlines; i++)

> +		gpiod_set_consumer_name(keypad->line_gpios->desc[i], "charlieplex_kbd_line");
> +
> +	return 0;
> +}

...

> +static int charlieplex_keypad_probe(struct platform_device *pdev)
> +{
> +	struct charlieplex_keypad *keypad;
> +	unsigned int debounce_interval_ms;
> +	unsigned int poll_interval_ms;
> +	struct input_dev *input_dev;

> +	int err;

The naming is even inconsistent between the functions...

> +	keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL);
> +	if (!keypad)
> +		return -ENOMEM;
> +
> +	input_dev = devm_input_allocate_device(&pdev->dev);
> +	if (!input_dev)
> +		return -ENOMEM;
> +
> +	keypad->input_dev = input_dev;
> +
> +	device_property_read_u32(&pdev->dev, "poll-interval", &poll_interval_ms);
> +	device_property_read_u32(&pdev->dev, "debounce-delay-ms", &debounce_interval_ms);
> +	device_property_read_u32(&pdev->dev, "settling-time-us", &keypad->settling_time_us);
> +
> +	keypad->current_code = -1;
> +	keypad->debounce_code = -1;
> +	keypad->debounce_threshold = DIV_ROUND_UP(debounce_interval_ms, poll_interval_ms);
> +
> +	err = charlieplex_keypad_init_gpio(pdev, keypad);
> +	if (err)
> +		return err;
> +
> +	input_dev->name		= pdev->name;
> +	input_dev->id.bustype	= BUS_HOST;
> +
> +	err = matrix_keypad_build_keymap(NULL, NULL, keypad->nlines,
> +					 keypad->nlines, NULL, input_dev);
> +	if (err)
> +		dev_err_probe(&pdev->dev, -ENOMEM, "failed to build keymap\n");
> +
> +	if (device_property_read_bool(&pdev->dev, "autorepeat"))
> +		__set_bit(EV_REP, input_dev->evbit);
> +
> +	input_set_capability(input_dev, EV_MSC, MSC_SCAN);
> +
> +	err = input_setup_polling(input_dev, charlieplex_keypad_poll);
> +	if (err)
> +		dev_err_probe(&pdev->dev, err, "unable to set up polling\n");
> +
> +	input_set_poll_interval(input_dev, poll_interval_ms);
> +
> +	input_set_drvdata(input_dev, keypad);
> +
> +	err = input_register_device(keypad->input_dev);
> +	if (err)
> +		return err;

> +	platform_set_drvdata(pdev, keypad);

Is this needed?

> +	return 0;
> +}

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply

* [PATCH v1] HID: rakk: add support for Rakk Dasig X side buttons
From: Karl Cayme @ 2026-02-25 15:56 UTC (permalink / raw)
  To: jikos, bentiss; +Cc: linux-input, linux-kernel, Karl Cayme

The Rakk Dasig X gaming mouse has a faulty HID report descriptor that
declares USAGE_MAXIMUM=3 (buttons 1-3) while actually sending 5 button
bits (REPORT_COUNT=5). This causes the kernel to ignore side buttons
(buttons 4 and 5).

Fix by patching the descriptor to set USAGE_MAXIMUM=5 in the
report_fixup callback.

The mouse uses Telink vendor ID 0x248a with three product IDs for USB
direct (0xfb01), wireless dongle (0xfa02), and Bluetooth (0x8266)
connection modes. All three variants have the same bug at byte offset 17.

Signed-off-by: Karl Cayme <kcayme@gmail.com>
---
 drivers/hid/Kconfig    |  8 +++++
 drivers/hid/Makefile   |  1 +
 drivers/hid/hid-ids.h  |  5 +++
 drivers/hid/hid-rakk.c | 72 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 86 insertions(+)
 create mode 100644 drivers/hid/hid-rakk.c

diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index c1d9f7c6a5f2..930ea0773169 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -755,6 +755,14 @@ config HID_MEGAWORLD_FF
 	Say Y here if you have a Mega World based game controller and want
 	to have force feedback support for it.
 
+config HID_RAKK
+	tristate "Rakk support"
+	help
+	  Support for Rakk gaming peripherals.
+
+	  Fixes the HID report descriptor of the Rakk Dasig X mouse,
+	  which declares only 3 buttons instead of 5.
+
 config HID_REDRAGON
 	tristate "Redragon keyboards"
 	default !EXPERT
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index e01838239ae6..7800613f5b2b 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -113,6 +113,7 @@ obj-$(CONFIG_HID_PLANTRONICS)	+= hid-plantronics.o
 obj-$(CONFIG_HID_PLAYSTATION)	+= hid-playstation.o
 obj-$(CONFIG_HID_PRIMAX)	+= hid-primax.o
 obj-$(CONFIG_HID_PXRC)		+= hid-pxrc.o
+obj-$(CONFIG_HID_RAKK)		+= hid-rakk.o
 obj-$(CONFIG_HID_RAPOO) += hid-rapoo.o
 obj-$(CONFIG_HID_RAZER)	+= hid-razer.o
 obj-$(CONFIG_HID_REDRAGON)	+= hid-redragon.o
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 3e299a30dcde..68fab837e8b3 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -1369,6 +1369,11 @@
 #define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_017	0x73f6
 #define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5	0x81a7
 
+#define USB_VENDOR_ID_TELINK				0x248a
+#define USB_DEVICE_ID_TELINK_RAKK_DASIG_X		0xfb01
+#define USB_DEVICE_ID_TELINK_RAKK_DASIG_X_DONGLE	0xfa02
+#define USB_DEVICE_ID_TELINK_RAKK_DASIG_X_BT		0x8266
+
 #define USB_VENDOR_ID_TEXAS_INSTRUMENTS	0x2047
 #define USB_DEVICE_ID_TEXAS_INSTRUMENTS_LENOVO_YOGA	0x0855
 
diff --git a/drivers/hid/hid-rakk.c b/drivers/hid/hid-rakk.c
new file mode 100644
index 000000000000..c2b969ce7259
--- /dev/null
+++ b/drivers/hid/hid-rakk.c
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *  HID driver for Rakk devices
+ *
+ *  Copyright (c) 2025 Karl Cayme
+ *
+ *  The Rakk Dasig X gaming mouse has a faulty HID report descriptor that
+ *  declares USAGE_MAXIMUM = 3 (buttons 1-3) while actually sending 5 button
+ *  bits (REPORT_COUNT = 5). This causes the kernel to ignore side buttons
+ *  (buttons 4 and 5). This driver fixes the descriptor so all 5 buttons
+ *  are properly recognized across 3 modes (wired, dongle, and Bluetooth).
+ */
+
+#include <linux/device.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+#include "hid-ids.h"
+
+/*
+ * The faulty byte is at offset 17 in the report descriptor for all three
+ * connection modes (USB direct, wireless dongle, and Bluetooth).
+ *
+ * Bytes 16-17 are: 0x29 0x03 (USAGE_MAXIMUM = 3)
+ * The fix changes byte 17 to 0x05 (USAGE_MAXIMUM = 5).
+ *
+ * Original descriptor bytes 0-17:
+ *   05 01 09 02 a1 01 85 01 09 01 a1 00 05 09 19 01 29 03
+ *                                                       ^^
+ *   Should be 0x05 to declare 5 buttons instead of 3.
+ */
+#define RAKK_RDESC_USAGE_MAX_OFFSET	17
+#define RAKK_RDESC_USAGE_MAX_ORIG	0x03
+#define RAKK_RDESC_USAGE_MAX_FIXED	0x05
+#define RAKK_RDESC_USB_SIZE		193
+#define RAKK_RDESC_DONGLE_SIZE		150
+#define RAKK_RDESC_BT_SIZE		89
+
+static const __u8 *rakk_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+				      unsigned int *rsize)
+{
+	if ((*rsize == RAKK_RDESC_USB_SIZE ||
+	     *rsize == RAKK_RDESC_DONGLE_SIZE ||
+	     *rsize == RAKK_RDESC_BT_SIZE) &&
+	    rdesc[RAKK_RDESC_USAGE_MAX_OFFSET] == RAKK_RDESC_USAGE_MAX_ORIG) {
+		hid_info(hdev, "fixing Rakk Dasig X button count (3 -> 5)\n");
+		rdesc[RAKK_RDESC_USAGE_MAX_OFFSET] = RAKK_RDESC_USAGE_MAX_FIXED;
+	}
+
+	return rdesc;
+}
+
+static const struct hid_device_id rakk_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_TELINK,
+			 USB_DEVICE_ID_TELINK_RAKK_DASIG_X) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_TELINK,
+			 USB_DEVICE_ID_TELINK_RAKK_DASIG_X_DONGLE) },
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_TELINK,
+			       USB_DEVICE_ID_TELINK_RAKK_DASIG_X_BT) },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, rakk_devices);
+
+static struct hid_driver rakk_driver = {
+	.name = "rakk",
+	.id_table = rakk_devices,
+	.report_fixup = rakk_report_fixup,
+};
+module_hid_driver(rakk_driver);
+
+MODULE_DESCRIPTION("HID driver for Rakk Dasig X mouse - fix side button support");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Karl Cayme");
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 4/4] Input: charlieplex_keypad: add GPIO charlieplex keypad
From: Hugo Villeneuve @ 2026-02-25 15:54 UTC (permalink / raw)
  To: robin, andy, geert, robh, krzk+dt, conor+dt, dmitry.torokhov,
	hvilleneuve, mkorpershoek, matthias.bgg,
	angelogioacchino.delregno, lee, alexander.sverdlin, marek.vasut,
	akurz
  Cc: devicetree, linux-kernel, linux-input, linux-arm-kernel,
	linux-mediatek, hugo
In-Reply-To: <20260225155409.612478-1-hugo@hugovil.com>

From: Hugo Villeneuve <hvilleneuve@dimonoff.com>

Add support for GPIO-based charlieplex keypad, allowing to control
N^2-N keys using N GPIO lines.

Reuse matrix keypad keymap to simplify, even if there is no concept
of rows and columns in this type of keyboard.

Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
---
 MAINTAINERS                                 |   7 +
 drivers/input/keyboard/Kconfig              |  14 ++
 drivers/input/keyboard/Makefile             |   1 +
 drivers/input/keyboard/charlieplex_keypad.c | 213 ++++++++++++++++++++
 4 files changed, 235 insertions(+)
 create mode 100644 drivers/input/keyboard/charlieplex_keypad.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 9ed6d11a7746..0b2d71f32b40 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5765,6 +5765,13 @@ S:	Maintained
 F:	Documentation/hwmon/powerz.rst
 F:	drivers/hwmon/powerz.c
 
+CHARLIEPLEX KEYPAD DRIVER
+M:	Hugo Villeneuve <hvilleneuve@dimonoff.com>
+S:	Supported
+W:	http://www.mosaic-industries.com/embedded-systems/microcontroller-projects/electronic-circuits/matrix-keypad-scan-decode
+F:	Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml
+F:	drivers/input/keyboard/charlieplex_keypad.c
+
 CHECKPATCH
 M:	Andy Whitcroft <apw@canonical.com>
 M:	Joe Perches <joe@perches.com>
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 2ff4fef322c2..ae54b4b7e2d8 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -289,6 +289,20 @@ config KEYBOARD_MATRIX
 	  To compile this driver as a module, choose M here: the
 	  module will be called matrix_keypad.
 
+config KEYBOARD_CHARLIEPLEX
+	tristate "GPIO driven chearlieplex keypad support"
+	depends on GPIOLIB || COMPILE_TEST
+	select INPUT_MATRIXKMAP
+	help
+	  Enable support for GPIO driven charlieplex keypad. A charlieplex
+	  keypad allows to use fewer GPIO lines to interface to key switches.
+	  For example, an N lines charlieplex keypad can be used to interface
+	  to N^2-N different key switches. However, this type of keypad
+	  cannot detect more than one key press at a time.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called charlieplex_keypad.
+
 config KEYBOARD_HIL_OLD
 	tristate "HP HIL keyboard support (simple driver)"
 	depends on GSC || HP300
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 2d906e14f3e2..40b5cf5d374d 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_KEYBOARD_LOCOMO)		+= locomokbd.o
 obj-$(CONFIG_KEYBOARD_LPC32XX)		+= lpc32xx-keys.o
 obj-$(CONFIG_KEYBOARD_MAPLE)		+= maple_keyb.o
 obj-$(CONFIG_KEYBOARD_MATRIX)		+= matrix_keypad.o
+obj-$(CONFIG_KEYBOARD_CHARLIEPLEX)	+= charlieplex_keypad.o
 obj-$(CONFIG_KEYBOARD_MAX7359)		+= max7359_keypad.o
 obj-$(CONFIG_KEYBOARD_MAX7360)		+= max7360-keypad.o
 obj-$(CONFIG_KEYBOARD_MPR121)		+= mpr121_touchkey.o
diff --git a/drivers/input/keyboard/charlieplex_keypad.c b/drivers/input/keyboard/charlieplex_keypad.c
new file mode 100644
index 000000000000..fae0aeb1d167
--- /dev/null
+++ b/drivers/input/keyboard/charlieplex_keypad.c
@@ -0,0 +1,213 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  GPIO driven charlieplex keypad driver
+ *
+ *  Copyright (c) 2025 Hugo Villeneuve <hvilleneuve@dimonoff.com>
+ *
+ *  Based on matrix_keyboard.c
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/types.h>
+
+struct charlieplex_keypad {
+	struct input_dev *input_dev;
+	struct gpio_descs *line_gpios;
+	unsigned int nlines;
+	unsigned int settling_time_us;
+	unsigned int debounce_threshold;
+	unsigned int debounce_count;
+	int debounce_code;
+	int current_code;
+};
+
+static void charlieplex_keypad_report_key(struct input_dev *input)
+{
+	struct charlieplex_keypad *keypad = input_get_drvdata(input);
+	const unsigned short *keycodes = input->keycode;
+
+	if (keypad->current_code > 0) {
+		input_event(input, EV_MSC, MSC_SCAN, keypad->current_code);
+		input_report_key(input, keycodes[keypad->current_code], 0);
+	}
+
+	if (keypad->debounce_code) {
+		input_event(input, EV_MSC, MSC_SCAN, keypad->debounce_code);
+		input_report_key(input, keycodes[keypad->debounce_code], 1);
+	}
+
+	input_sync(input);
+	keypad->current_code = keypad->debounce_code;
+}
+
+static void charlieplex_keypad_check_switch_change(struct input_dev *input,
+						   int code)
+{
+	struct charlieplex_keypad *keypad = input_get_drvdata(input);
+
+	if (code != keypad->debounce_code) {
+		keypad->debounce_count = 0;
+		keypad->debounce_code = code;
+	} else if (keypad->debounce_count < keypad->debounce_threshold) {
+		keypad->debounce_count++;
+
+		if (keypad->debounce_count >= keypad->debounce_threshold &&
+		    keypad->debounce_code != keypad->current_code)
+			charlieplex_keypad_report_key(input);
+	}
+}
+
+static void charlieplex_keypad_poll(struct input_dev *input)
+{
+	struct charlieplex_keypad *keypad = input_get_drvdata(input);
+	int oline;
+	int code;
+
+	for (code = 0, oline = 0; oline < keypad->nlines; oline++) {
+		DECLARE_BITMAP(values, MATRIX_MAX_ROWS);
+		int iline;
+		int rc;
+
+		/* Activate only one line as output at a time. */
+		gpiod_direction_output(keypad->line_gpios->desc[oline], 1);
+
+		if (keypad->settling_time_us)
+			fsleep(keypad->settling_time_us);
+
+		/* Read input on all other lines. */
+		rc = gpiod_get_array_value_cansleep(keypad->line_gpios->ndescs,
+						    keypad->line_gpios->desc,
+						    keypad->line_gpios->info, values);
+		if (rc)
+			return;
+
+		for (iline = 0; iline < keypad->nlines; iline++) {
+			if (iline == oline)
+				continue; /* Do not read active output line. */
+
+			/* Check if GPIO is asserted. */
+			if (test_bit(iline, values)) {
+				code = MATRIX_SCAN_CODE(oline, iline,
+							get_count_order(keypad->nlines));
+				/*
+				 * Exit loop immediately since we cannot detect
+				 * more than one key press at a time.
+				 */
+				break;
+			}
+		}
+
+		gpiod_direction_input(keypad->line_gpios->desc[oline]);
+
+		if (code)
+			break;
+	}
+
+	charlieplex_keypad_check_switch_change(input, code);
+}
+
+static int charlieplex_keypad_init_gpio(struct platform_device *pdev,
+					struct charlieplex_keypad *keypad)
+{
+	int i;
+
+	keypad->line_gpios = devm_gpiod_get_array(&pdev->dev, "line", GPIOD_IN);
+	if (IS_ERR(keypad->line_gpios))
+		return PTR_ERR(keypad->line_gpios);
+
+	keypad->nlines = keypad->line_gpios->ndescs;
+
+	if (keypad->nlines > MATRIX_MAX_ROWS)
+		return -EINVAL;
+
+	for (i = 0; i < keypad->nlines; i++)
+		gpiod_set_consumer_name(keypad->line_gpios->desc[i], "charlieplex_kbd_line");
+
+	return 0;
+}
+
+static int charlieplex_keypad_probe(struct platform_device *pdev)
+{
+	struct charlieplex_keypad *keypad;
+	unsigned int debounce_interval_ms;
+	unsigned int poll_interval_ms;
+	struct input_dev *input_dev;
+	int err;
+
+	keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL);
+	if (!keypad)
+		return -ENOMEM;
+
+	input_dev = devm_input_allocate_device(&pdev->dev);
+	if (!input_dev)
+		return -ENOMEM;
+
+	keypad->input_dev = input_dev;
+
+	device_property_read_u32(&pdev->dev, "poll-interval", &poll_interval_ms);
+	device_property_read_u32(&pdev->dev, "debounce-delay-ms", &debounce_interval_ms);
+	device_property_read_u32(&pdev->dev, "settling-time-us", &keypad->settling_time_us);
+
+	keypad->current_code = -1;
+	keypad->debounce_code = -1;
+	keypad->debounce_threshold = DIV_ROUND_UP(debounce_interval_ms, poll_interval_ms);
+
+	err = charlieplex_keypad_init_gpio(pdev, keypad);
+	if (err)
+		return err;
+
+	input_dev->name		= pdev->name;
+	input_dev->id.bustype	= BUS_HOST;
+
+	err = matrix_keypad_build_keymap(NULL, NULL, keypad->nlines,
+					 keypad->nlines, NULL, input_dev);
+	if (err)
+		dev_err_probe(&pdev->dev, -ENOMEM, "failed to build keymap\n");
+
+	if (device_property_read_bool(&pdev->dev, "autorepeat"))
+		__set_bit(EV_REP, input_dev->evbit);
+
+	input_set_capability(input_dev, EV_MSC, MSC_SCAN);
+
+	err = input_setup_polling(input_dev, charlieplex_keypad_poll);
+	if (err)
+		dev_err_probe(&pdev->dev, err, "unable to set up polling\n");
+
+	input_set_poll_interval(input_dev, poll_interval_ms);
+
+	input_set_drvdata(input_dev, keypad);
+
+	err = input_register_device(keypad->input_dev);
+	if (err)
+		return err;
+
+	platform_set_drvdata(pdev, keypad);
+
+	return 0;
+}
+
+static const struct of_device_id charlieplex_keypad_dt_match[] = {
+	{ .compatible = "gpio-charlieplex-keypad" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, charlieplex_keypad_dt_match);
+
+static struct platform_driver charlieplex_keypad_driver = {
+	.probe		= charlieplex_keypad_probe,
+	.driver		= {
+		.name	= "charlieplex-keypad",
+		.of_match_table = of_match_ptr(charlieplex_keypad_dt_match),
+	},
+};
+module_platform_driver(charlieplex_keypad_driver);
+
+MODULE_AUTHOR("Hugo Villeneuve <hvilleneuve@dimonoff.com>");
+MODULE_DESCRIPTION("GPIO driven charlieplex keypad driver");
+MODULE_LICENSE("GPL");
-- 
2.47.3


^ permalink raw reply related

* [PATCH v3 2/4] dt-bindings: input: add settling-time-us common property
From: Hugo Villeneuve @ 2026-02-25 15:53 UTC (permalink / raw)
  To: robin, andy, geert, robh, krzk+dt, conor+dt, dmitry.torokhov,
	hvilleneuve, mkorpershoek, matthias.bgg,
	angelogioacchino.delregno, lee, alexander.sverdlin, marek.vasut,
	akurz
  Cc: devicetree, linux-kernel, linux-input, linux-arm-kernel,
	linux-mediatek, hugo
In-Reply-To: <20260225155409.612478-1-hugo@hugovil.com>

From: Hugo Villeneuve <hvilleneuve@dimonoff.com>

Add common property that can be reused by other bindings.

Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
---
Note: a similar property is used by gpio-matrix-keypad.yaml:
  col-scan-delay-us
---
 Documentation/devicetree/bindings/input/input.yaml | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/input/input.yaml b/Documentation/devicetree/bindings/input/input.yaml
index 502e0b7eb500..14652d324e2c 100644
--- a/Documentation/devicetree/bindings/input/input.yaml
+++ b/Documentation/devicetree/bindings/input/input.yaml
@@ -66,6 +66,14 @@ properties:
       reset automatically. Device with key pressed reset feature can specify
       this property.
 
+  settling-time-us:
+    description:
+      Delay, in microseconds, when activating an output line/col/row GPIO
+      before we can reliably read other input GPIOs that maybe affected by this
+      output. This can be the case for an output with a RC circuit that affects
+      ramp-up/down times.
+    default: 0
+
 dependencies:
   linux,input-type: [ "linux,code" ]
 
-- 
2.47.3


^ permalink raw reply related

* [PATCH v3 3/4] dt-bindings: input: add GPIO charlieplex keypad
From: Hugo Villeneuve @ 2026-02-25 15:54 UTC (permalink / raw)
  To: robin, andy, geert, robh, krzk+dt, conor+dt, dmitry.torokhov,
	hvilleneuve, mkorpershoek, matthias.bgg,
	angelogioacchino.delregno, lee, alexander.sverdlin, marek.vasut,
	akurz
  Cc: devicetree, linux-kernel, linux-input, linux-arm-kernel,
	linux-mediatek, hugo
In-Reply-To: <20260225155409.612478-1-hugo@hugovil.com>

From: Hugo Villeneuve <hvilleneuve@dimonoff.com>

Add DT bindings for GPIO charlieplex keypad.

Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
---
 .../input/gpio-charlieplex-keypad.yaml        | 106 ++++++++++++++++++
 1 file changed, 106 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml

diff --git a/Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml b/Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml
new file mode 100644
index 000000000000..d3eeddc8e533
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml
@@ -0,0 +1,106 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+
+$id: http://devicetree.org/schemas/input/gpio-charlieplex-keypad.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: GPIO charlieplex keypad
+
+maintainers:
+  - Hugo Villeneuve <hvilleneuve@dimonoff.com>
+
+description: |
+  The charlieplex keypad supports N^2)-N different key combinations (where N is
+  the number of lines). Key presses and releases are detected by configuring
+  only one line as output at a time, and reading other line states. This process
+  is repeated for each line. Diodes are required to ensure current flows in only
+  one direction between any pair of pins.
+  This mechanism doesn't allow to detect simultaneous key presses.
+
+  Wiring example for 3 lines keyboard with 6 switches and 3 diodes:
+
+  L0  --+---------------------+----------------------+
+        |                     |                      |
+  L1  -------+-----------+---------------------+     |
+        |    |           |    |                |     |
+  L2  -------------+----------------+-----+    |     |
+        |    |     |     |    |     |     |    |     |
+        |    |     |     |    |     |     |    |     |
+        |  S1 \  S2 \    |  S3 \  S4 \    |  S5 \  S6 \
+        |    |     |     |    |     |     |    |     |
+        |    +--+--+     |    +--+--+     |    +--+--+
+        |       |        |       |        |       |
+        |    D1 v        |    D2 v        |    D3 v
+        |       - (k)    |       - (k)    |       - (k)
+        |       |        |       |        |       |
+        +-------+        +-------+        +-------+
+
+  L: GPIO line
+  S: switch
+  D: diode (k indicates cathode)
+
+allOf:
+  - $ref: input.yaml#
+  - $ref: /schemas/input/matrix-keymap.yaml#
+
+properties:
+  compatible:
+    const: gpio-charlieplex-keypad
+
+  autorepeat: true
+
+  debounce-delay-ms:
+    default: 5
+
+  line-gpios:
+    description:
+      List of GPIOs used as lines. The gpio specifier for this property
+      depends on the gpio controller to which these lines are connected.
+
+  linux,keymap: true
+
+  poll-interval: true
+
+  settling-time-us: true
+
+  wakeup-source: true
+
+required:
+  - compatible
+  - line-gpios
+  - linux,keymap
+  - poll-interval
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/input/input.h>
+
+    charlieplex-keypad {
+        compatible = "gpio-charlieplex-keypad";
+        debounce-delay-ms = <20>;
+        poll-interval = <5>;
+        settling-time-us = <2>;
+
+        line-gpios = <&gpio2 25 GPIO_ACTIVE_HIGH
+                      &gpio2 26 GPIO_ACTIVE_HIGH
+                      &gpio2 27 GPIO_ACTIVE_HIGH>;
+
+        /* MATRIX_KEY(output, input, key-code) */
+        linux,keymap = <
+            /*
+             * According to wiring diagram above, if L1 is configured as
+             * output and HIGH, and we detect a HIGH level on input L0,
+             * then it means S1 is pressed: MATRIX_KEY(L1, L0, KEY...)
+             */
+            MATRIX_KEY(1, 0, KEY_F1) /* S1 */
+            MATRIX_KEY(2, 0, KEY_F2) /* S2 */
+            MATRIX_KEY(0, 1, KEY_F3) /* S3 */
+            MATRIX_KEY(2, 1, KEY_F4) /* S4 */
+            MATRIX_KEY(1, 2, KEY_F5) /* S5 */
+            MATRIX_KEY(0, 2, KEY_F6) /* S6 */
+        >;
+    };
-- 
2.47.3


^ permalink raw reply related

* [PATCH v3 1/4] dt-bindings: input: add debounce-delay-ms common property
From: Hugo Villeneuve @ 2026-02-25 15:53 UTC (permalink / raw)
  To: robin, andy, geert, robh, krzk+dt, conor+dt, dmitry.torokhov,
	hvilleneuve, mkorpershoek, matthias.bgg,
	angelogioacchino.delregno, lee, alexander.sverdlin, marek.vasut,
	akurz
  Cc: devicetree, linux-kernel, linux-input, linux-arm-kernel,
	linux-mediatek, hugo
In-Reply-To: <20260225155409.612478-1-hugo@hugovil.com>

From: Hugo Villeneuve <hvilleneuve@dimonoff.com>

A few bindings are already defining a debounce-delay-ms property, so
add it to the input binding to reduce redundant redefines.

Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
---
 .../devicetree/bindings/auxdisplay/holtek,ht16k33.yaml    | 5 ++---
 .../devicetree/bindings/input/cirrus,ep9307-keypad.yaml   | 7 +++----
 .../devicetree/bindings/input/gpio-matrix-keypad.yaml     | 5 ++---
 Documentation/devicetree/bindings/input/input.yaml        | 8 ++++++++
 .../devicetree/bindings/input/mediatek,mt6779-keypad.yaml | 1 +
 Documentation/devicetree/bindings/mfd/fsl,mc13xxx.yaml    | 2 --
 6 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml b/Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml
index b90eec2077b4..c46a2471f8b1 100644
--- a/Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml
+++ b/Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml
@@ -10,6 +10,7 @@ maintainers:
   - Robin van der Gracht <robin@protonic.nl>
 
 allOf:
+  - $ref: /schemas/input/input.yaml#
   - $ref: /schemas/input/matrix-keymap.yaml#
 
 properties:
@@ -33,9 +34,7 @@ properties:
   interrupts:
     maxItems: 1
 
-  debounce-delay-ms:
-    maxItems: 1
-    description: Debouncing interval time in milliseconds
+  debounce-delay-ms: true
 
   linux,keymap: true
 
diff --git a/Documentation/devicetree/bindings/input/cirrus,ep9307-keypad.yaml b/Documentation/devicetree/bindings/input/cirrus,ep9307-keypad.yaml
index a0d2460c55ab..25b8b29c87d7 100644
--- a/Documentation/devicetree/bindings/input/cirrus,ep9307-keypad.yaml
+++ b/Documentation/devicetree/bindings/input/cirrus,ep9307-keypad.yaml
@@ -10,6 +10,7 @@ maintainers:
   - Alexander Sverdlin <alexander.sverdlin@gmail.com>
 
 allOf:
+  - $ref: input.yaml#
   - $ref: /schemas/input/matrix-keymap.yaml#
 
 description:
@@ -37,10 +38,8 @@ properties:
   clocks:
     maxItems: 1
 
-  debounce-delay-ms:
-    description: |
-          Time in microseconds that key must be pressed or
-          released for state change interrupt to trigger.
+  # Time for state change interrupt to trigger
+  debounce-delay-ms: true
 
   cirrus,prescale:
     description: row/column counter pre-scaler load value
diff --git a/Documentation/devicetree/bindings/input/gpio-matrix-keypad.yaml b/Documentation/devicetree/bindings/input/gpio-matrix-keypad.yaml
index ebfff9e42a36..69df24a5ae70 100644
--- a/Documentation/devicetree/bindings/input/gpio-matrix-keypad.yaml
+++ b/Documentation/devicetree/bindings/input/gpio-matrix-keypad.yaml
@@ -18,6 +18,7 @@ description:
   report the event using GPIO interrupts to the cpu.
 
 allOf:
+  - $ref: input.yaml#
   - $ref: /schemas/input/matrix-keymap.yaml#
 
 properties:
@@ -46,9 +47,7 @@ properties:
       Force GPIO polarity to active low.
       In the absence of this property GPIOs are treated as active high.
 
-  debounce-delay-ms:
-    description: Debounce interval in milliseconds.
-    default: 0
+  debounce-delay-ms: true
 
   col-scan-delay-us:
     description:
diff --git a/Documentation/devicetree/bindings/input/input.yaml b/Documentation/devicetree/bindings/input/input.yaml
index 94f7942189e8..502e0b7eb500 100644
--- a/Documentation/devicetree/bindings/input/input.yaml
+++ b/Documentation/devicetree/bindings/input/input.yaml
@@ -14,6 +14,14 @@ properties:
     description: Enable autorepeat when key is pressed and held down.
     type: boolean
 
+  debounce-delay-ms:
+    description:
+      Debounce delay in milliseconds. This is the time during which the key
+      press or release signal must remain stable before it is considered valid.
+    minimum: 0
+    maximum: 999
+    default: 0
+
   linux,keycodes:
     description:
       Specifies an array of numeric keycode values to be used for reporting
diff --git a/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml b/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml
index e365413732e7..914dd3283df3 100644
--- a/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml
+++ b/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml
@@ -10,6 +10,7 @@ maintainers:
   - Mattijs Korpershoek <mkorpershoek@kernel.org>
 
 allOf:
+  - $ref: input.yaml#
   - $ref: /schemas/input/matrix-keymap.yaml#
 
 description: |
diff --git a/Documentation/devicetree/bindings/mfd/fsl,mc13xxx.yaml b/Documentation/devicetree/bindings/mfd/fsl,mc13xxx.yaml
index d2886f2686a8..542ba5114424 100644
--- a/Documentation/devicetree/bindings/mfd/fsl,mc13xxx.yaml
+++ b/Documentation/devicetree/bindings/mfd/fsl,mc13xxx.yaml
@@ -76,8 +76,6 @@ properties:
           debounce-delay-ms:
             enum: [0, 30, 150, 750]
             default: 30
-            description:
-              Sets the debouncing delay in milliseconds.
 
           active-low:
             description: Set active when pin is pulled low.
-- 
2.47.3


^ permalink raw reply related

* [PATCH v3 0/4] input: add GPIO-based charlieplex keypad
From: Hugo Villeneuve @ 2026-02-25 15:53 UTC (permalink / raw)
  To: robin, andy, geert, robh, krzk+dt, conor+dt, dmitry.torokhov,
	hvilleneuve, mkorpershoek, matthias.bgg,
	angelogioacchino.delregno, lee, alexander.sverdlin, marek.vasut,
	akurz
  Cc: devicetree, linux-kernel, linux-input, linux-arm-kernel,
	linux-mediatek, hugo

From: Hugo Villeneuve <hvilleneuve@dimonoff.com>

Hello,
this patch series add a new GPIO charlieplex keypad driver.

The first two patches simply commonize two properties that are present in
a few bindings, so that the actual patches for the charlieplex keypad driver
can reuse them instead of also redefining them.

I have tested the driver on a custom board with a Solidrun RZ/G2LC SOM
with three charlieplex keyboards, all connected thru a single PCA9416 I2C GPIO
expander.

Link: [v1] https://lore.kernel.org/all/20260203155023.536103-1-hugo@hugovil.com/
Link: [v2] https://lore.kernel.org/all/20260213171431.2228814-1-hugo@hugovil.com/

Changes for v3:
- Add ASCII diagram in bindings, and reference to it in example
- Reorder properties alphabetically
- Add patch to define common input settling-time-us property
- Add patch to define common input debounce-delay-ms property

Changes for v2:
- Fix yamllint error for example
- Remove unused debug variable (nkeys)
- Remove support for custom linux,no-autorepeat DT property
- Remove support for custom gpio-activelow DT property

Thank you.

Hugo Villeneuve (4):
  dt-bindings: input: add debounce-delay-ms common property
  dt-bindings: input: add settling-time-us common property
  dt-bindings: input: add GPIO charlieplex keypad
  Input: charlieplex_keypad: add GPIO charlieplex keypad

 .../bindings/auxdisplay/holtek,ht16k33.yaml   |   5 +-
 .../bindings/input/cirrus,ep9307-keypad.yaml  |   7 +-
 .../input/gpio-charlieplex-keypad.yaml        | 106 +++++++++
 .../bindings/input/gpio-matrix-keypad.yaml    |   5 +-
 .../devicetree/bindings/input/input.yaml      |  16 ++
 .../input/mediatek,mt6779-keypad.yaml         |   1 +
 .../devicetree/bindings/mfd/fsl,mc13xxx.yaml  |   2 -
 MAINTAINERS                                   |   7 +
 drivers/input/keyboard/Kconfig                |  14 ++
 drivers/input/keyboard/Makefile               |   1 +
 drivers/input/keyboard/charlieplex_keypad.c   | 213 ++++++++++++++++++
 11 files changed, 365 insertions(+), 12 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml
 create mode 100644 drivers/input/keyboard/charlieplex_keypad.c


base-commit: ab2e361ca97a42b7af8be1d273646b30d3b75bf3
-- 
2.47.3


^ permalink raw reply

* [PATCH v6 4/7] iio: Rename 'sign' field to `format` in struct iio_scan_type
From: Francesco Lavra @ 2026-02-25 10:17 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Lars-Peter Clausen,
	Michael Hennerich, Lucas Stankus, Jonathan Cameron, David Lechner,
	Nuno Sá, Andy Shevchenko, Puranjay Mohan, Cosmin Tanislav,
	Ramona Gradinariu, Antoniu Miclaus, Petre Rodan, Dan Robertson,
	Benson Leung, Guenter Roeck, Jiri Kosina, Srinivas Pandruvada,
	Matti Vaittinen, Marcelo Schmitt, Esteban Blanc, Jorge Marques,
	Sergiu Cuciurean, Dragos Bogdan, Alisa-Dariana Roman,
	Trevor Gamblin, Renato Lui Geh, Eugen Hristev, Nicolas Ferre,
	Alexandre Belloni, Claudiu Beznea, Andreas Klinger, Paul Cercueil,
	Ramona Bolboaca, Marcus Folkesson, Kent Gustavsson,
	Matthias Brugger, AngeloGioacchino Del Regno, Frank Li,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	Matteo Martelli, Marius Cristea, Heiko Stuebner, Maxime Coquelin,
	Alexandre Torgue, Kurt Borja, Francesco Dolcini,
	João Paulo Gonçalves, Leonard Göhrs,
	Oleksij Rempel, Haibo Chen, Salih Erim, Conall O'Griofa,
	Michal Simek, Gustavo Silva, Tomasz Duszynski, Roan van Dijk,
	Jyoti Bhayana, Mariel Tinaco, Nishant Malpani, Rui Miguel Silva,
	Linus Walleij, Lorenzo Bianconi, Alex Lanzano, Jagath Jog J,
	Jean-Baptiste Maneyrol, Remi Buisson, Christian Eggers,
	Mudit Sharma, Javier Carrasco, Ondřej Jirman, Song Qiang,
	Dixit Parmar, Gerald Loacker, linux-doc, linux-kernel, linux-iio,
	chrome-platform, linux-input, linux-arm-kernel, linux-mips,
	linux-mediatek, imx, linux-rockchip, linux-stm32
In-Reply-To: <20260225100421.2366864-1-flavra@baylibre.com>

This field is used to differentiate between signed and unsigned integers.
A following commit will extend its use to in order to add support for non-
integer scan elements; therefore, change its name from 'sign' to a more
generic 'format'.

Signed-off-by: Francesco Lavra <flavra@baylibre.com>
---
 Documentation/driver-api/iio/buffers.rst      |  4 +-
 drivers/iio/accel/adxl313_core.c              |  2 +-
 drivers/iio/accel/adxl345_core.c              |  2 +-
 drivers/iio/accel/adxl355_core.c              |  4 +-
 drivers/iio/accel/adxl367.c                   |  4 +-
 drivers/iio/accel/adxl372.c                   |  2 +-
 drivers/iio/accel/adxl380.c                   |  4 +-
 drivers/iio/accel/bma180.c                    | 10 ++---
 drivers/iio/accel/bma220_core.c               |  2 +-
 drivers/iio/accel/bma400_core.c               |  4 +-
 drivers/iio/accel/bmc150-accel-core.c         |  2 +-
 drivers/iio/accel/cros_ec_accel_legacy.c      |  2 +-
 drivers/iio/accel/fxls8962af-core.c           |  4 +-
 drivers/iio/accel/hid-sensor-accel-3d.c       |  2 +-
 drivers/iio/accel/kionix-kx022a.c             |  2 +-
 drivers/iio/accel/kxcjk-1013.c                |  2 +-
 drivers/iio/accel/kxsd9.c                     |  4 +-
 drivers/iio/accel/mma7455_core.c              |  2 +-
 drivers/iio/accel/mma8452.c                   |  4 +-
 drivers/iio/accel/msa311.c                    |  2 +-
 drivers/iio/accel/mxc4005.c                   |  2 +-
 drivers/iio/accel/sca3000.c                   |  4 +-
 drivers/iio/accel/sca3300.c                   |  6 +--
 drivers/iio/accel/stk8312.c                   |  2 +-
 drivers/iio/accel/stk8ba50.c                  |  2 +-
 drivers/iio/adc/ad4000.c                      |  8 ++--
 drivers/iio/adc/ad4030.c                      | 10 ++---
 drivers/iio/adc/ad4062.c                      |  8 ++--
 drivers/iio/adc/ad4080.c                      |  2 +-
 drivers/iio/adc/ad4130.c                      |  2 +-
 drivers/iio/adc/ad4170-4.c                    | 12 ++---
 drivers/iio/adc/ad4695.c                      | 24 +++++-----
 drivers/iio/adc/ad4851.c                      | 12 ++---
 drivers/iio/adc/ad7124.c                      |  4 +-
 drivers/iio/adc/ad7173.c                      |  6 +--
 drivers/iio/adc/ad7191.c                      |  6 +--
 drivers/iio/adc/ad7192.c                      |  2 +-
 drivers/iio/adc/ad7266.c                      |  6 +--
 drivers/iio/adc/ad7280a.c                     |  4 +-
 drivers/iio/adc/ad7298.c                      |  4 +-
 drivers/iio/adc/ad7380.c                      | 44 +++++++++----------
 drivers/iio/adc/ad7405.c                      |  2 +-
 drivers/iio/adc/ad7476.c                      |  2 +-
 drivers/iio/adc/ad7606.c                      | 14 +++---
 drivers/iio/adc/ad7625.c                      |  2 +-
 drivers/iio/adc/ad7766.c                      |  2 +-
 drivers/iio/adc/ad7768-1.c                    |  8 ++--
 drivers/iio/adc/ad7779.c                      |  2 +-
 drivers/iio/adc/ad7780.c                      |  2 +-
 drivers/iio/adc/ad7791.c                      |  2 +-
 drivers/iio/adc/ad7793.c                      |  2 +-
 drivers/iio/adc/ad7887.c                      |  2 +-
 drivers/iio/adc/ad7923.c                      |  2 +-
 drivers/iio/adc/ad7944.c                      |  8 ++--
 drivers/iio/adc/ad799x.c                      |  2 +-
 drivers/iio/adc/ad9467.c                      |  4 +-
 drivers/iio/adc/ade9000.c                     |  4 +-
 drivers/iio/adc/at91-sama5d2_adc.c            | 10 ++---
 drivers/iio/adc/at91_adc.c                    |  4 +-
 drivers/iio/adc/cc10001_adc.c                 |  4 +-
 drivers/iio/adc/cpcap-adc.c                   |  2 +-
 drivers/iio/adc/dln2-adc.c                    |  4 +-
 drivers/iio/adc/hx711.c                       |  4 +-
 drivers/iio/adc/ina2xx-adc.c                  |  8 ++--
 drivers/iio/adc/ingenic-adc.c                 | 12 ++---
 drivers/iio/adc/max1027.c                     |  4 +-
 drivers/iio/adc/max1118.c                     |  2 +-
 drivers/iio/adc/max11205.c                    |  2 +-
 drivers/iio/adc/max11410.c                    |  2 +-
 drivers/iio/adc/max1363.c                     |  4 +-
 drivers/iio/adc/mcp3911.c                     |  2 +-
 drivers/iio/adc/mt6359-auxadc.c               |  2 +-
 drivers/iio/adc/mt6360-adc.c                  |  2 +-
 drivers/iio/adc/mxs-lradc-adc.c               |  6 +--
 drivers/iio/adc/nxp-sar-adc.c                 |  2 +-
 drivers/iio/adc/pac1921.c                     |  8 ++--
 drivers/iio/adc/pac1934.c                     | 32 +++++++-------
 drivers/iio/adc/rockchip_saradc.c             |  2 +-
 drivers/iio/adc/rtq6056.c                     | 16 +++----
 drivers/iio/adc/sd_adc_modulator.c            |  2 +-
 drivers/iio/adc/stm32-adc.c                   |  4 +-
 drivers/iio/adc/stm32-dfsdm-adc.c             |  2 +-
 drivers/iio/adc/ti-adc081c.c                  |  2 +-
 drivers/iio/adc/ti-adc0832.c                  |  4 +-
 drivers/iio/adc/ti-adc084s021.c               |  2 +-
 drivers/iio/adc/ti-adc108s102.c               |  2 +-
 drivers/iio/adc/ti-adc12138.c                 |  4 +-
 drivers/iio/adc/ti-adc161s626.c               |  4 +-
 drivers/iio/adc/ti-ads1015.c                  |  4 +-
 drivers/iio/adc/ti-ads1018.c                  |  6 +--
 drivers/iio/adc/ti-ads1100.c                  |  2 +-
 drivers/iio/adc/ti-ads1119.c                  |  2 +-
 drivers/iio/adc/ti-ads124s08.c                |  2 +-
 drivers/iio/adc/ti-ads1298.c                  |  2 +-
 drivers/iio/adc/ti-ads131e08.c                |  2 +-
 drivers/iio/adc/ti-ads7950.c                  |  2 +-
 drivers/iio/adc/ti-ads8688.c                  |  2 +-
 drivers/iio/adc/ti-lmp92064.c                 |  4 +-
 drivers/iio/adc/ti-tlc4541.c                  |  2 +-
 drivers/iio/adc/ti-tsc2046.c                  |  2 +-
 drivers/iio/adc/ti_am335x_adc.c               |  2 +-
 drivers/iio/adc/vf610_adc.c                   |  4 +-
 drivers/iio/adc/xilinx-ams.c                  |  2 +-
 drivers/iio/adc/xilinx-xadc-core.c            | 10 ++---
 drivers/iio/addac/ad74115.c                   |  2 +-
 drivers/iio/addac/ad74413r.c                  |  2 +-
 drivers/iio/chemical/atlas-ezo-sensor.c       |  4 +-
 drivers/iio/chemical/atlas-sensor.c           | 12 ++---
 drivers/iio/chemical/bme680_core.c            |  8 ++--
 drivers/iio/chemical/ccs811.c                 |  4 +-
 drivers/iio/chemical/ens160_core.c            |  4 +-
 drivers/iio/chemical/pms7003.c                |  2 +-
 drivers/iio/chemical/scd30_core.c             |  2 +-
 drivers/iio/chemical/scd4x.c                  |  6 +--
 drivers/iio/chemical/sps30.c                  |  2 +-
 .../common/cros_ec_sensors/cros_ec_activity.c |  2 +-
 .../cros_ec_sensors/cros_ec_lid_angle.c       |  2 +-
 .../common/cros_ec_sensors/cros_ec_sensors.c  |  4 +-
 drivers/iio/common/scmi_sensors/scmi_iio.c    |  4 +-
 .../iio/common/ssp_sensors/ssp_iio_sensor.h   |  4 +-
 drivers/iio/dac/ad3552r-hs.c                  |  2 +-
 drivers/iio/dac/ad3552r.c                     |  2 +-
 drivers/iio/dac/ad5064.c                      |  2 +-
 drivers/iio/dac/ad5360.c                      |  2 +-
 drivers/iio/dac/ad5380.c                      |  2 +-
 drivers/iio/dac/ad5421.c                      |  2 +-
 drivers/iio/dac/ad5446.h                      |  2 +-
 drivers/iio/dac/ad5449.c                      |  2 +-
 drivers/iio/dac/ad5504.c                      |  2 +-
 drivers/iio/dac/ad5592r-base.c                |  2 +-
 drivers/iio/dac/ad5624r_spi.c                 |  2 +-
 drivers/iio/dac/ad5686.c                      |  2 +-
 drivers/iio/dac/ad5755.c                      |  2 +-
 drivers/iio/dac/ad5761.c                      |  2 +-
 drivers/iio/dac/ad5764.c                      |  2 +-
 drivers/iio/dac/ad5766.c                      |  2 +-
 drivers/iio/dac/ad5791.c                      |  4 +-
 drivers/iio/dac/ad7303.c                      |  2 +-
 drivers/iio/dac/ad8460.c                      |  2 +-
 drivers/iio/dac/ad9739a.c                     |  2 +-
 drivers/iio/dac/ltc1660.c                     |  2 +-
 drivers/iio/dac/max5522.c                     |  2 +-
 drivers/iio/dac/mcp4922.c                     |  2 +-
 drivers/iio/dac/stm32-dac.c                   |  2 +-
 drivers/iio/dummy/iio_simple_dummy.c          |  8 ++--
 drivers/iio/gyro/adis16136.c                  |  4 +-
 drivers/iio/gyro/adxrs290.c                   |  4 +-
 drivers/iio/gyro/bmg160_core.c                |  2 +-
 drivers/iio/gyro/fxas21002c_core.c            |  2 +-
 drivers/iio/gyro/hid-sensor-gyro-3d.c         |  2 +-
 drivers/iio/gyro/itg3200_core.c               |  2 +-
 drivers/iio/gyro/mpu3050-core.c               |  4 +-
 drivers/iio/health/afe440x.h                  |  2 +-
 drivers/iio/health/max30100.c                 |  4 +-
 drivers/iio/health/max30102.c                 |  2 +-
 drivers/iio/humidity/am2315.c                 |  4 +-
 drivers/iio/humidity/hdc100x.c                |  4 +-
 drivers/iio/humidity/hid-sensor-humidity.c    |  2 +-
 drivers/iio/humidity/hts221_core.c            |  4 +-
 drivers/iio/imu/adis.c                        |  2 +-
 drivers/iio/imu/adis16400.c                   | 16 +++----
 drivers/iio/imu/adis16460.c                   |  4 +-
 drivers/iio/imu/adis16475.c                   |  6 +--
 drivers/iio/imu/adis16480.c                   |  6 +--
 drivers/iio/imu/adis16550.c                   |  6 +--
 drivers/iio/imu/bmi160/bmi160_core.c          |  2 +-
 drivers/iio/imu/bmi270/bmi270_core.c          |  4 +-
 drivers/iio/imu/bmi323/bmi323_core.c          |  4 +-
 drivers/iio/imu/bno055/bno055.c               |  2 +-
 .../iio/imu/inv_icm42600/inv_icm42600_accel.c |  2 +-
 .../iio/imu/inv_icm42600/inv_icm42600_gyro.c  |  2 +-
 .../iio/imu/inv_icm42600/inv_icm42600_temp.h  |  2 +-
 drivers/iio/imu/inv_icm45600/inv_icm45600.h   |  2 +-
 .../iio/imu/inv_icm45600/inv_icm45600_accel.c |  2 +-
 .../iio/imu/inv_icm45600/inv_icm45600_gyro.c  |  2 +-
 drivers/iio/imu/inv_mpu6050/inv_mpu_core.c    |  6 +--
 drivers/iio/imu/kmx61.c                       |  4 +-
 drivers/iio/imu/smi240.c                      |  4 +-
 drivers/iio/imu/smi330/smi330_core.c          |  6 +--
 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h       |  4 +-
 drivers/iio/industrialio-buffer.c             |  4 +-
 drivers/iio/light/acpi-als.c                  |  2 +-
 drivers/iio/light/adjd_s311.c                 |  2 +-
 drivers/iio/light/apds9960.c                  |  2 +-
 drivers/iio/light/as73211.c                   |  6 +--
 drivers/iio/light/bh1745.c                    |  2 +-
 drivers/iio/light/cros_ec_light_prox.c        |  4 +-
 drivers/iio/light/gp2ap020a00f.c              |  6 +--
 drivers/iio/light/hid-sensor-als.c            |  2 +-
 drivers/iio/light/hid-sensor-prox.c           |  2 +-
 drivers/iio/light/isl29125.c                  |  2 +-
 drivers/iio/light/ltr501.c                    |  4 +-
 drivers/iio/light/max44000.c                  |  4 +-
 drivers/iio/light/opt4060.c                   |  4 +-
 drivers/iio/light/rohm-bu27034.c              |  4 +-
 drivers/iio/light/rpr0521.c                   |  6 +--
 drivers/iio/light/si1145.c                    |  2 +-
 drivers/iio/light/st_uvis25_core.c            |  2 +-
 drivers/iio/light/tcs3414.c                   |  2 +-
 drivers/iio/light/tcs3472.c                   |  2 +-
 drivers/iio/light/vcnl4000.c                  |  2 +-
 drivers/iio/light/vcnl4035.c                  |  4 +-
 drivers/iio/light/veml6030.c                  |  8 ++--
 drivers/iio/light/veml6046x00.c               |  8 ++--
 drivers/iio/light/vl6180.c                    |  6 +--
 drivers/iio/magnetometer/af8133j.c            |  2 +-
 drivers/iio/magnetometer/ak8974.c             |  2 +-
 drivers/iio/magnetometer/ak8975.c             |  2 +-
 drivers/iio/magnetometer/als31300.c           |  4 +-
 drivers/iio/magnetometer/bmc150_magn.c        |  2 +-
 drivers/iio/magnetometer/hid-sensor-magn-3d.c |  2 +-
 drivers/iio/magnetometer/hmc5843_core.c       |  4 +-
 drivers/iio/magnetometer/mag3110.c            |  4 +-
 drivers/iio/magnetometer/rm3100-core.c        |  2 +-
 drivers/iio/magnetometer/tlv493d.c            |  4 +-
 drivers/iio/magnetometer/tmag5273.c           |  8 ++--
 drivers/iio/magnetometer/yamaha-yas530.c      |  4 +-
 drivers/iio/orientation/hid-sensor-incl-3d.c  |  2 +-
 drivers/iio/orientation/hid-sensor-rotation.c |  2 +-
 .../position/hid-sensor-custom-intel-hinge.c  |  6 +--
 drivers/iio/potentiostat/lmp91000.c           |  2 +-
 drivers/iio/pressure/abp2030pa.c              |  4 +-
 drivers/iio/pressure/bmp280-core.c            | 18 ++++----
 drivers/iio/pressure/cros_ec_baro.c           |  4 +-
 drivers/iio/pressure/dlhl60d.c                |  4 +-
 drivers/iio/pressure/hid-sensor-press.c       |  2 +-
 drivers/iio/pressure/hsc030pa.c               |  4 +-
 drivers/iio/pressure/mpl3115.c                |  4 +-
 drivers/iio/pressure/mprls0025pa.c            |  2 +-
 drivers/iio/pressure/ms5611_core.c            |  4 +-
 drivers/iio/pressure/rohm-bm1390.c            |  4 +-
 drivers/iio/pressure/st_pressure_core.c       | 12 ++---
 drivers/iio/pressure/zpa2326.c                |  4 +-
 drivers/iio/proximity/as3935.c                |  2 +-
 drivers/iio/proximity/hx9023s.c               |  2 +-
 drivers/iio/proximity/irsd200.c               |  2 +-
 drivers/iio/proximity/isl29501.c              |  2 +-
 drivers/iio/proximity/mb1232.c                |  2 +-
 .../iio/proximity/pulsedlight-lidar-lite-v2.c |  2 +-
 drivers/iio/proximity/srf08.c                 |  2 +-
 drivers/iio/proximity/sx9310.c                |  2 +-
 drivers/iio/proximity/sx9324.c                |  2 +-
 drivers/iio/proximity/sx9360.c                |  4 +-
 drivers/iio/proximity/sx9500.c                |  2 +-
 drivers/iio/proximity/vl53l0x-i2c.c           |  2 +-
 drivers/iio/resolver/ad2s1210.c               |  4 +-
 .../iio/temperature/hid-sensor-temperature.c  |  2 +-
 drivers/iio/temperature/maxim_thermocouple.c  |  6 +--
 drivers/iio/temperature/tmp006.c              |  4 +-
 include/linux/iio/common/st_sensors.h         |  2 +-
 include/linux/iio/iio.h                       |  6 +--
 include/linux/iio/imu/adis.h                  |  6 +--
 252 files changed, 511 insertions(+), 511 deletions(-)

diff --git a/Documentation/driver-api/iio/buffers.rst b/Documentation/driver-api/iio/buffers.rst
index 63f364e862d1..00398472ce59 100644
--- a/Documentation/driver-api/iio/buffers.rst
+++ b/Documentation/driver-api/iio/buffers.rst
@@ -78,7 +78,7 @@ fields in iio_chan_spec definition::
    /* other members */
            int scan_index
            struct {
-                   char sign;
+                   char format;
                    u8 realbits;
                    u8 storagebits;
                    u8 shift;
@@ -98,7 +98,7 @@ following channel definition::
 		   /* other stuff here */
 		   .scan_index = 0,
 		   .scan_type = {
-		           .sign = 's',
+			   .format = 's',
 			   .realbits = 12,
 			   .storagebits = 16,
 			   .shift = 4,
diff --git a/drivers/iio/accel/adxl313_core.c b/drivers/iio/accel/adxl313_core.c
index 9f5d4d2cb325..f80e6dbb445c 100644
--- a/drivers/iio/accel/adxl313_core.c
+++ b/drivers/iio/accel/adxl313_core.c
@@ -259,7 +259,7 @@ static const int adxl313_odr_freqs[][2] = {
 	.info_mask_shared_by_type_available =				\
 		BIT(IIO_CHAN_INFO_SAMP_FREQ),				\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 13,						\
 		.storagebits = 16,					\
 		.endianness = IIO_BE,					\
diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index 78e3f799ecc1..d98dfd357b2a 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -254,7 +254,7 @@ static const struct iio_event_spec adxl345_events[] = {
 		BIT(IIO_CHAN_INFO_SAMP_FREQ),		\
 	.scan_index = (index),				\
 	.scan_type = {					\
-		.sign = 's',				\
+		.format = 's',				\
 		.realbits = 13,				\
 		.storagebits = 16,			\
 		.endianness = IIO_LE,			\
diff --git a/drivers/iio/accel/adxl355_core.c b/drivers/iio/accel/adxl355_core.c
index 1c1d64d5cbcb..00b0ec7f3e8f 100644
--- a/drivers/iio/accel/adxl355_core.c
+++ b/drivers/iio/accel/adxl355_core.c
@@ -725,7 +725,7 @@ static irqreturn_t adxl355_trigger_handler(int irq, void *p)
 		BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY),	\
 	.scan_index = index,						\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 20,						\
 		.storagebits = 32,					\
 		.shift = 4,						\
@@ -745,7 +745,7 @@ static const struct iio_chan_spec adxl355_channels[] = {
 				      BIT(IIO_CHAN_INFO_OFFSET),
 		.scan_index = 3,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 12,
 			.storagebits = 16,
 			.endianness = IIO_BE,
diff --git a/drivers/iio/accel/adxl367.c b/drivers/iio/accel/adxl367.c
index 0c04b2bb7efb..df4bb72dae68 100644
--- a/drivers/iio/accel/adxl367.c
+++ b/drivers/iio/accel/adxl367.c
@@ -1344,7 +1344,7 @@ static const struct iio_event_spec adxl367_events[] = {
 	.num_event_specs = ARRAY_SIZE(adxl367_events),			\
 	.scan_index = (index),						\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 14,						\
 		.storagebits = 16,					\
 		.endianness = IIO_BE,					\
@@ -1360,7 +1360,7 @@ static const struct iio_event_spec adxl367_events[] = {
 	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
 	.scan_index = (index),						\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 14,						\
 		.storagebits = 16,					\
 		.endianness = IIO_BE,					\
diff --git a/drivers/iio/accel/adxl372.c b/drivers/iio/accel/adxl372.c
index 28a8793a53b6..2d04fecb1508 100644
--- a/drivers/iio/accel/adxl372.c
+++ b/drivers/iio/accel/adxl372.c
@@ -262,7 +262,7 @@ static const struct iio_event_spec adxl372_events[] = {
 		BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),	\
 	.scan_index = index,						\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 12,						\
 		.storagebits = 16,					\
 		.shift = 4,						\
diff --git a/drivers/iio/accel/adxl380.c b/drivers/iio/accel/adxl380.c
index 8fab2fdbe147..4a648ea3f7bc 100644
--- a/drivers/iio/accel/adxl380.c
+++ b/drivers/iio/accel/adxl380.c
@@ -1789,7 +1789,7 @@ static const struct iio_event_spec adxl380_events[] = {
 		BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY),	\
 	.scan_index = index,						\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 16,						\
 		.storagebits = 16,					\
 		.endianness = IIO_BE,					\
@@ -1810,7 +1810,7 @@ static const struct iio_chan_spec adxl380_channels[] = {
 				      BIT(IIO_CHAN_INFO_OFFSET),
 		.scan_index = 3,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 12,
 			.storagebits = 16,
 			.shift = 4,
diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
index 7bc6761f5135..47244a70799b 100644
--- a/drivers/iio/accel/bma180.c
+++ b/drivers/iio/accel/bma180.c
@@ -541,7 +541,7 @@ static int bma180_read_raw(struct iio_dev *indio_dev,
 		iio_device_release_direct(indio_dev);
 		if (ret < 0)
 			return ret;
-		if (chan->scan_type.sign == 's') {
+		if (chan->scan_type.format == 's') {
 			*val = sign_extend32(ret >> chan->scan_type.shift,
 				chan->scan_type.realbits - 1);
 		} else {
@@ -663,7 +663,7 @@ static const struct iio_chan_spec_ext_info bma180_ext_info[] = {
 		BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),	\
 	.scan_index = AXIS_##_axis,					\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = _bits,					\
 		.storagebits = 16,					\
 		.shift = 16 - _bits,					\
@@ -677,7 +677,7 @@ static const struct iio_chan_spec_ext_info bma180_ext_info[] = {
 		BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET),	\
 	.scan_index = TEMP,						\
 	.scan_type = {							\
-		.sign = 'u',						\
+		.format = 'u',						\
 		.realbits = 8,						\
 		.storagebits = 16,					\
 	},								\
@@ -692,7 +692,7 @@ static const struct iio_chan_spec_ext_info bma180_ext_info[] = {
 		BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),	\
 	.scan_index = AXIS_##_axis,					\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = _bits,					\
 		.storagebits = 16,					\
 		.shift = 16 - _bits,					\
@@ -706,7 +706,7 @@ static const struct iio_chan_spec_ext_info bma180_ext_info[] = {
 		BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET),	\
 	.scan_index = TEMP,						\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 8,						\
 		.storagebits = 16,					\
 	},								\
diff --git a/drivers/iio/accel/bma220_core.c b/drivers/iio/accel/bma220_core.c
index f32d875b994e..e4a9b33d1e1c 100644
--- a/drivers/iio/accel/bma220_core.c
+++ b/drivers/iio/accel/bma220_core.c
@@ -107,7 +107,7 @@
 	    BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),		\
 	.scan_index = index,						\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 6,						\
 		.storagebits = 8,					\
 		.shift = 2,						\
diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c
index 05f72707f830..05c17e8ea077 100644
--- a/drivers/iio/accel/bma400_core.c
+++ b/drivers/iio/accel/bma400_core.c
@@ -399,7 +399,7 @@ static const struct attribute_group bma400_event_attribute_group = {
 	.ext_info = bma400_ext_info, \
 	.scan_index = _index,	\
 	.scan_type = {		\
-		.sign = 's',	\
+		.format = 's',		\
 		.realbits = 12,		\
 		.storagebits = 16,	\
 		.endianness = IIO_LE,	\
@@ -428,7 +428,7 @@ static const struct iio_chan_spec bma400_channels[] = {
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 		.scan_index = 3,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 8,
 			.storagebits = 8,
 			.endianness = IIO_LE,
diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c
index 42ccf0316ce5..9712a35929c1 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -1059,7 +1059,7 @@ static const struct iio_event_spec bmc150_accel_event = {
 				BIT(IIO_CHAN_INFO_SAMP_FREQ),		\
 	.scan_index = AXIS_##_axis,					\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = (bits),					\
 		.storagebits = 16,					\
 		.shift = 16 - (bits),					\
diff --git a/drivers/iio/accel/cros_ec_accel_legacy.c b/drivers/iio/accel/cros_ec_accel_legacy.c
index f7e4dc02b34d..82e361e12b3d 100644
--- a/drivers/iio/accel/cros_ec_accel_legacy.c
+++ b/drivers/iio/accel/cros_ec_accel_legacy.c
@@ -189,7 +189,7 @@ static const struct iio_info cros_ec_accel_legacy_info = {
 			BIT(IIO_CHAN_INFO_SAMP_FREQ),			\
 		.ext_info = cros_ec_sensors_ext_info,			\
 		.scan_type = {						\
-			.sign = 's',					\
+			.format = 's',					\
 			.realbits = CROS_EC_SENSOR_BITS,		\
 			.storagebits = CROS_EC_SENSOR_BITS,		\
 		},							\
diff --git a/drivers/iio/accel/fxls8962af-core.c b/drivers/iio/accel/fxls8962af-core.c
index 8763e91c63d2..778e9a927ea4 100644
--- a/drivers/iio/accel/fxls8962af-core.c
+++ b/drivers/iio/accel/fxls8962af-core.c
@@ -731,7 +731,7 @@ static const struct iio_event_spec fxls8962af_event[] = {
 					      BIT(IIO_CHAN_INFO_SAMP_FREQ), \
 	.scan_index = idx, \
 	.scan_type = { \
-		.sign = 's', \
+		.format = 's', \
 		.realbits = 12, \
 		.storagebits = 16, \
 		.endianness = IIO_LE, \
@@ -748,7 +748,7 @@ static const struct iio_event_spec fxls8962af_event[] = {
 			      BIT(IIO_CHAN_INFO_OFFSET),\
 	.scan_index = -1, \
 	.scan_type = { \
-		.sign = 's', \
+		.format = 's', \
 		.realbits = 8, \
 		.storagebits = 8, \
 	}, \
diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c
index 2ff591b3458f..e0a7f7ca72b0 100644
--- a/drivers/iio/accel/hid-sensor-accel-3d.c
+++ b/drivers/iio/accel/hid-sensor-accel-3d.c
@@ -123,7 +123,7 @@ static const struct iio_chan_spec gravity_channels[] = {
 static void accel_3d_adjust_channel_bit_mask(struct iio_chan_spec *channels,
 						int channel, int size)
 {
-	channels[channel].scan_type.sign = 's';
+	channels[channel].scan_type.format = 's';
 	/* Real storage bits will change based on the report desc. */
 	channels[channel].scan_type.realbits = size * 8;
 	/* Maximum size of a sample to capture is u32 */
diff --git a/drivers/iio/accel/kionix-kx022a.c b/drivers/iio/accel/kionix-kx022a.c
index 39485572a76b..7ab15251b416 100644
--- a/drivers/iio/accel/kionix-kx022a.c
+++ b/drivers/iio/accel/kionix-kx022a.c
@@ -348,7 +348,7 @@ static const struct iio_chan_spec_ext_info kx022a_ext_info[] = {
 	.address = reg,						\
 	.scan_index = index,					\
 	.scan_type = {                                          \
-		.sign = 's',					\
+		.format = 's',					\
 		.realbits = 16,					\
 		.storagebits = 16,				\
 		.endianness = IIO_LE,				\
diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c
index 2823ddde4bf2..71bf203d7666 100644
--- a/drivers/iio/accel/kxcjk-1013.c
+++ b/drivers/iio/accel/kxcjk-1013.c
@@ -1147,7 +1147,7 @@ static const struct iio_chan_spec_ext_info kxcjk1013_ext_info[] = {
 				BIT(IIO_CHAN_INFO_SAMP_FREQ),		\
 	.scan_index = AXIS_##_axis,					\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 12,						\
 		.storagebits = 16,					\
 		.shift = 4,						\
diff --git a/drivers/iio/accel/kxsd9.c b/drivers/iio/accel/kxsd9.c
index 4717d80fc24a..36a91cf776ea 100644
--- a/drivers/iio/accel/kxsd9.c
+++ b/drivers/iio/accel/kxsd9.c
@@ -284,7 +284,7 @@ static const struct iio_chan_spec_ext_info kxsd9_ext_info[] = {
 		.address = KXSD9_REG_##axis,				\
 		.scan_index = index,					\
 		.scan_type = {                                          \
-			.sign = 'u',					\
+			.format = 'u',					\
 			.realbits = 12,					\
 			.storagebits = 16,				\
 			.shift = 4,					\
@@ -303,7 +303,7 @@ static const struct iio_chan_spec kxsd9_channels[] = {
 		.address = KXSD9_REG_AUX,
 		.scan_index = 3,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 12,
 			.storagebits = 16,
 			.shift = 4,
diff --git a/drivers/iio/accel/mma7455_core.c b/drivers/iio/accel/mma7455_core.c
index a2b5bdf14dde..3b0b3159892f 100644
--- a/drivers/iio/accel/mma7455_core.c
+++ b/drivers/iio/accel/mma7455_core.c
@@ -219,7 +219,7 @@ static const struct iio_info mma7455_info = {
 				    BIT(IIO_CHAN_INFO_SCALE), \
 	.scan_index = idx, \
 	.scan_type = { \
-		.sign = 's', \
+		.format = 's', \
 		.realbits = 10, \
 		.storagebits = 16, \
 		.endianness = IIO_LE, \
diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c
index 15172ba2972c..69942239d3ed 100644
--- a/drivers/iio/accel/mma8452.c
+++ b/drivers/iio/accel/mma8452.c
@@ -1233,7 +1233,7 @@ static const struct iio_chan_spec_ext_info mma8452_ext_info[] = {
 			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
 	.scan_index = idx, \
 	.scan_type = { \
-		.sign = 's', \
+		.format = 's', \
 		.realbits = (bits), \
 		.storagebits = 16, \
 		.shift = 16 - (bits), \
@@ -1255,7 +1255,7 @@ static const struct iio_chan_spec_ext_info mma8452_ext_info[] = {
 		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
 	.scan_index = idx, \
 	.scan_type = { \
-		.sign = 's', \
+		.format = 's', \
 		.realbits = (bits), \
 		.storagebits = 16, \
 		.shift = 16 - (bits), \
diff --git a/drivers/iio/accel/msa311.c b/drivers/iio/accel/msa311.c
index 5eace0de3750..a239c48d44fb 100644
--- a/drivers/iio/accel/msa311.c
+++ b/drivers/iio/accel/msa311.c
@@ -382,7 +382,7 @@ enum msa311_si {
 					      BIT(IIO_CHAN_INFO_SAMP_FREQ), \
 	.scan_index = MSA311_SI_##axis,                                     \
 	.scan_type = {                                                      \
-		.sign = 's',                                                \
+		.format = 's',                                              \
 		.realbits = 12,                                             \
 		.storagebits = 16,                                          \
 		.shift = 4,                                                 \
diff --git a/drivers/iio/accel/mxc4005.c b/drivers/iio/accel/mxc4005.c
index a2c3cf13d098..f3aa7f25cc7f 100644
--- a/drivers/iio/accel/mxc4005.c
+++ b/drivers/iio/accel/mxc4005.c
@@ -306,7 +306,7 @@ static const unsigned long mxc4005_scan_masks[] = {
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
 	.scan_index = AXIS_##_axis,				\
 	.scan_type = {						\
-		.sign = 's',					\
+		.format = 's',					\
 		.realbits = 12,					\
 		.storagebits = 16,				\
 		.shift = 4,					\
diff --git a/drivers/iio/accel/sca3000.c b/drivers/iio/accel/sca3000.c
index 4a827be439a2..5acba0f31aca 100644
--- a/drivers/iio/accel/sca3000.c
+++ b/drivers/iio/accel/sca3000.c
@@ -485,7 +485,7 @@ static const struct iio_event_spec sca3000_event = {
 		.address = index,				\
 		.scan_index = index,				\
 		.scan_type = {					\
-			.sign = 's',				\
+			.format = 's',				\
 			.realbits = 13,				\
 			.storagebits = 16,			\
 			.shift = 3,				\
@@ -528,7 +528,7 @@ static const struct iio_chan_spec sca3000_channels_with_temp[] = {
 		/* No buffer support */
 		.scan_index = -1,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 9,
 			.storagebits = 16,
 			.shift = 5,
diff --git a/drivers/iio/accel/sca3300.c b/drivers/iio/accel/sca3300.c
index 8380b237831c..ff5fed5f2dbc 100644
--- a/drivers/iio/accel/sca3300.c
+++ b/drivers/iio/accel/sca3300.c
@@ -70,7 +70,7 @@ enum sca3300_scan_indexes {
 	BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),		\
 	.scan_index = index,						\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 16,						\
 		.storagebits = 16,					\
 		.endianness = IIO_CPU,					\
@@ -87,7 +87,7 @@ enum sca3300_scan_indexes {
 	.info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE), \
 	.scan_index = index,						\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 16,						\
 		.storagebits = 16,					\
 		.endianness = IIO_CPU,					\
@@ -100,7 +100,7 @@ enum sca3300_scan_indexes {
 		.scan_index = index,					\
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
 		.scan_type = {						\
-			.sign = 's',					\
+			.format = 's',					\
 			.realbits = 16,					\
 			.storagebits = 16,				\
 			.endianness = IIO_CPU,				\
diff --git a/drivers/iio/accel/stk8312.c b/drivers/iio/accel/stk8312.c
index f31c6ab3392d..2493758f6a82 100644
--- a/drivers/iio/accel/stk8312.c
+++ b/drivers/iio/accel/stk8312.c
@@ -80,7 +80,7 @@ static const struct {
 				    BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
 	.scan_index = index,						\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 8,						\
 		.storagebits = 8,					\
 		.endianness = IIO_CPU,					\
diff --git a/drivers/iio/accel/stk8ba50.c b/drivers/iio/accel/stk8ba50.c
index a9ff2a273fe1..e1a720e7d460 100644
--- a/drivers/iio/accel/stk8ba50.c
+++ b/drivers/iio/accel/stk8ba50.c
@@ -108,7 +108,7 @@ struct stk8ba50_data {
 				    BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
 	.scan_index = index,						\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 10,						\
 		.storagebits = 16,					\
 		.shift = STK8BA50_DATA_SHIFT,				\
diff --git a/drivers/iio/adc/ad4000.c b/drivers/iio/adc/ad4000.c
index fd3d79fca785..b83303ea852e 100644
--- a/drivers/iio/adc/ad4000.c
+++ b/drivers/iio/adc/ad4000.c
@@ -51,7 +51,7 @@
 	.info_mask_separate_available = _reg_access ? BIT(IIO_CHAN_INFO_SCALE) : 0,\
 	.scan_index = 0,							\
 	.scan_type = {								\
-		.sign = _sign,							\
+		.format = _sign,						\
 		.realbits = _real_bits,						\
 		.storagebits = _storage_bits,					\
 		.shift = (_offl ? 0 : _storage_bits - _real_bits),		\
@@ -89,7 +89,7 @@
 	.info_mask_separate_available = _reg_access ? BIT(IIO_CHAN_INFO_SCALE) : 0,\
 	.scan_index = 0,							\
 	.scan_type = {								\
-		.sign = _sign,							\
+		.format = _sign,						\
 		.realbits = _real_bits,						\
 		.storagebits = _storage_bits,					\
 		.shift = (_offl ? 0 : _storage_bits - _real_bits),		\
@@ -540,7 +540,7 @@ static void ad4000_fill_scale_tbl(struct ad4000_state *st,
 	 * ADCs that output two's complement code have one less bit to express
 	 * voltage magnitude.
 	 */
-	if (chan->scan_type.sign == 's')
+	if (chan->scan_type.format == 's')
 		scale_bits = chan->scan_type.realbits - 1;
 	else
 		scale_bits = chan->scan_type.realbits;
@@ -657,7 +657,7 @@ static int ad4000_single_conversion(struct iio_dev *indio_dev,
 
 	sample >>= chan->scan_type.shift;
 
-	if (chan->scan_type.sign == 's')
+	if (chan->scan_type.format == 's')
 		*val = sign_extend32(sample, chan->scan_type.realbits - 1);
 	else
 		*val = sample;
diff --git a/drivers/iio/adc/ad4030.c b/drivers/iio/adc/ad4030.c
index 68446db9bef1..d27acd7f1cb9 100644
--- a/drivers/iio/adc/ad4030.c
+++ b/drivers/iio/adc/ad4030.c
@@ -196,7 +196,7 @@ struct ad4030_state {
 	.channel = ((_idx) - (_ch)) * 2 + (_ch),			\
 	.scan_index = (_idx),						\
 	.scan_type = {							\
-		.sign = 'u',						\
+		.format = 'u',						\
 		.storagebits = 8,					\
 		.realbits = 8,						\
 		.endianness = IIO_BE,					\
@@ -1083,14 +1083,14 @@ static const unsigned long ad4630_channel_masks[] = {
 
 static const struct iio_scan_type ad4030_24_scan_types[] = {
 	[AD4030_SCAN_TYPE_NORMAL] = {
-		.sign = 's',
+		.format = 's',
 		.storagebits = 32,
 		.realbits = 24,
 		.shift = 8,
 		.endianness = IIO_BE,
 	},
 	[AD4030_SCAN_TYPE_AVG] = {
-		.sign = 's',
+		.format = 's',
 		.storagebits = 32,
 		.realbits = 30,
 		.shift = 2,
@@ -1100,14 +1100,14 @@ static const struct iio_scan_type ad4030_24_scan_types[] = {
 
 static const struct iio_scan_type ad4030_16_scan_types[] = {
 	[AD4030_SCAN_TYPE_NORMAL] = {
-		.sign = 's',
+		.format = 's',
 		.storagebits = 32,
 		.realbits = 16,
 		.shift = 16,
 		.endianness = IIO_BE,
 	},
 	[AD4030_SCAN_TYPE_AVG] = {
-		.sign = 's',
+		.format = 's',
 		.storagebits = 32,
 		.realbits = 30,
 		.shift = 2,
diff --git a/drivers/iio/adc/ad4062.c b/drivers/iio/adc/ad4062.c
index dd4ad32aa6f5..985017f04970 100644
--- a/drivers/iio/adc/ad4062.c
+++ b/drivers/iio/adc/ad4062.c
@@ -122,13 +122,13 @@ enum {
 
 static const struct iio_scan_type ad4062_scan_type_12_s[] = {
 	[AD4062_SCAN_TYPE_SAMPLE] = {
-		.sign = 's',
+		.format = 's',
 		.realbits = 12,
 		.storagebits = 16,
 		.endianness = IIO_BE,
 	},
 	[AD4062_SCAN_TYPE_BURST_AVG] = {
-		.sign = 's',
+		.format = 's',
 		.realbits = 14,
 		.storagebits = 16,
 		.endianness = IIO_BE,
@@ -137,13 +137,13 @@ static const struct iio_scan_type ad4062_scan_type_12_s[] = {
 
 static const struct iio_scan_type ad4062_scan_type_16_s[] = {
 	[AD4062_SCAN_TYPE_SAMPLE] = {
-		.sign = 's',
+		.format = 's',
 		.realbits = 16,
 		.storagebits = 16,
 		.endianness = IIO_BE,
 	},
 	[AD4062_SCAN_TYPE_BURST_AVG] = {
-		.sign = 's',
+		.format = 's',
 		.realbits = 20,
 		.storagebits = 32,
 		.endianness = IIO_BE,
diff --git a/drivers/iio/adc/ad4080.c b/drivers/iio/adc/ad4080.c
index 7cf3b6ed7940..7b67e229dedf 100644
--- a/drivers/iio/adc/ad4080.c
+++ b/drivers/iio/adc/ad4080.c
@@ -432,7 +432,7 @@ static struct iio_chan_spec_ext_info ad4080_ext_info[] = {
 	.ext_info = ad4080_ext_info,					\
 	.scan_index = 0,						\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = (bits),					\
 		.storagebits = (storage),				\
 	},								\
diff --git a/drivers/iio/adc/ad4130.c b/drivers/iio/adc/ad4130.c
index 5567ae5dee88..d20a0180201e 100644
--- a/drivers/iio/adc/ad4130.c
+++ b/drivers/iio/adc/ad4130.c
@@ -1002,7 +1002,7 @@ static const struct iio_chan_spec ad4130_channel_template = {
 					BIT(IIO_CHAN_INFO_SAMP_FREQ),
 	.ext_info = ad4130_ext_info,
 	.scan_type = {
-		.sign = 'u',
+		.format = 'u',
 		.endianness = IIO_BE,
 	},
 };
diff --git a/drivers/iio/adc/ad4170-4.c b/drivers/iio/adc/ad4170-4.c
index 82205bfae531..96b0302331cd 100644
--- a/drivers/iio/adc/ad4170-4.c
+++ b/drivers/iio/adc/ad4170-4.c
@@ -955,7 +955,7 @@ static const struct iio_chan_spec ad4170_temp_channel_template = {
 			      BIT(IIO_CHAN_INFO_SAMP_FREQ),
 	.info_mask_separate_available = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 	.scan_type = {
-		.sign = 's',
+		.format = 's',
 		.realbits = 24,
 		.storagebits = 32,
 		.shift = 8,
@@ -1101,7 +1101,7 @@ static int ad4170_get_input_range(struct ad4170_state *st,
 				  struct iio_chan_spec const *chan,
 				  unsigned int ch_reg, unsigned int ref_sel)
 {
-	bool bipolar = chan->scan_type.sign == 's';
+	bool bipolar = chan->scan_type.format == 's';
 	struct device *dev = &st->spi->dev;
 	int refp, refn, ain_voltage, ret;
 
@@ -1228,7 +1228,7 @@ static int __ad4170_read_sample(struct iio_dev *indio_dev,
 	if (ret)
 		return ret;
 
-	if (chan->scan_type.sign == 's')
+	if (chan->scan_type.format == 's')
 		*val = sign_extend32(*val, chan->scan_type.realbits - 1);
 
 	return 0;
@@ -1353,7 +1353,7 @@ static int ad4170_fill_scale_tbl(struct iio_dev *indio_dev,
 	struct ad4170_state *st = iio_priv(indio_dev);
 	struct ad4170_chan_info *chan_info = &st->chan_infos[chan->address];
 	struct device *dev = &st->spi->dev;
-	int bipolar = chan->scan_type.sign == 's' ? 1 : 0;
+	int bipolar = chan->scan_type.format == 's' ? 1 : 0;
 	int precision_bits = chan->scan_type.realbits;
 	int pga, ainm_voltage, ret;
 	unsigned long long offset;
@@ -2335,9 +2335,9 @@ static int ad4170_parse_channel_node(struct iio_dev *indio_dev,
 	bipolar = fwnode_property_read_bool(child, "bipolar");
 	setup->afe |= FIELD_PREP(AD4170_AFE_BIPOLAR_MSK, bipolar);
 	if (bipolar)
-		chan->scan_type.sign = 's';
+		chan->scan_type.format = 's';
 	else
-		chan->scan_type.sign = 'u';
+		chan->scan_type.format = 'u';
 
 	ret = ad4170_validate_channel(st, chan);
 	if (ret)
diff --git a/drivers/iio/adc/ad4695.c b/drivers/iio/adc/ad4695.c
index cda419638d9a..fd7378b3e0e4 100644
--- a/drivers/iio/adc/ad4695.c
+++ b/drivers/iio/adc/ad4695.c
@@ -314,25 +314,25 @@ enum {
 
 static const struct iio_scan_type ad4695_scan_type_offload_u[] = {
 	[AD4695_SCAN_TYPE_OSR_1] = {
-		.sign = 'u',
+		.format = 'u',
 		.realbits = 16,
 		.shift = 3,
 		.storagebits = 32,
 	},
 	[AD4695_SCAN_TYPE_OSR_4] = {
-		.sign = 'u',
+		.format = 'u',
 		.realbits = 17,
 		.shift = 2,
 		.storagebits = 32,
 	},
 	[AD4695_SCAN_TYPE_OSR_16] = {
-		.sign = 'u',
+		.format = 'u',
 		.realbits = 18,
 		.shift = 1,
 		.storagebits = 32,
 	},
 	[AD4695_SCAN_TYPE_OSR_64] = {
-		.sign = 'u',
+		.format = 'u',
 		.realbits = 19,
 		.storagebits = 32,
 	},
@@ -340,25 +340,25 @@ static const struct iio_scan_type ad4695_scan_type_offload_u[] = {
 
 static const struct iio_scan_type ad4695_scan_type_offload_s[] = {
 	[AD4695_SCAN_TYPE_OSR_1] = {
-		.sign = 's',
+		.format = 's',
 		.realbits = 16,
 		.shift = 3,
 		.storagebits = 32,
 	},
 	[AD4695_SCAN_TYPE_OSR_4] = {
-		.sign = 's',
+		.format = 's',
 		.realbits = 17,
 		.shift = 2,
 		.storagebits = 32,
 	},
 	[AD4695_SCAN_TYPE_OSR_16] = {
-		.sign = 's',
+		.format = 's',
 		.realbits = 18,
 		.shift = 1,
 		.storagebits = 32,
 	},
 	[AD4695_SCAN_TYPE_OSR_64] = {
-		.sign = 's',
+		.format = 's',
 		.realbits = 19,
 		.storagebits = 32,
 	},
@@ -375,7 +375,7 @@ static const struct iio_chan_spec ad4695_channel_template = {
 	.info_mask_separate_available = BIT(IIO_CHAN_INFO_CALIBSCALE) |
 					BIT(IIO_CHAN_INFO_CALIBBIAS),
 	.scan_type = {
-		.sign = 'u',
+		.format = 'u',
 		.realbits = 16,
 		.storagebits = 16,
 	},
@@ -388,7 +388,7 @@ static const struct iio_chan_spec ad4695_temp_channel_template = {
 			      BIT(IIO_CHAN_INFO_SCALE) |
 			      BIT(IIO_CHAN_INFO_OFFSET),
 	.scan_type = {
-		.sign = 's',
+		.format = 's',
 		.realbits = 16,
 		.storagebits = 16,
 	},
@@ -1037,7 +1037,7 @@ static int __ad4695_read_info_raw(struct ad4695_state *st,
 	if (ret)
 		return ret;
 
-	if (chan->scan_type.sign == 's')
+	if (chan->scan_type.format == 's')
 		*val = sign_extend32(st->raw_data, realbits - 1);
 	else
 		*val = st->raw_data;
@@ -1603,7 +1603,7 @@ static int ad4695_parse_channel_cfg(struct ad4695_state *st)
 				fwnode_get_name(child));
 
 		if (chan_cfg->bipolar)
-			iio_chan->scan_type.sign = 's';
+			iio_chan->scan_type.format = 's';
 
 		ret = ad4695_write_chn_cfg(st, chan_cfg);
 		if (ret)
diff --git a/drivers/iio/adc/ad4851.c b/drivers/iio/adc/ad4851.c
index 1ad77f2a4580..080f069e0f84 100644
--- a/drivers/iio/adc/ad4851.c
+++ b/drivers/iio/adc/ad4851.c
@@ -891,12 +891,12 @@ static int ad4851_read_avail(struct iio_dev *indio_dev,
 
 static const struct iio_scan_type ad4851_scan_type_20_u[] = {
 	[AD4851_SCAN_TYPE_NORMAL] = {
-		.sign = 'u',
+		.format = 'u',
 		.realbits = 20,
 		.storagebits = 32,
 	},
 	[AD4851_SCAN_TYPE_RESOLUTION_BOOST] = {
-		.sign = 'u',
+		.format = 'u',
 		.realbits = 24,
 		.storagebits = 32,
 	},
@@ -904,12 +904,12 @@ static const struct iio_scan_type ad4851_scan_type_20_u[] = {
 
 static const struct iio_scan_type ad4851_scan_type_20_b[] = {
 	[AD4851_SCAN_TYPE_NORMAL] = {
-		.sign = 's',
+		.format = 's',
 		.realbits = 20,
 		.storagebits = 32,
 	},
 	[AD4851_SCAN_TYPE_RESOLUTION_BOOST] = {
-		.sign = 's',
+		.format = 's',
 		.realbits = 24,
 		.storagebits = 32,
 	},
@@ -949,7 +949,7 @@ static int ad4851_get_current_scan_type(const struct iio_dev *indio_dev,
 {										\
 	AD4851_IIO_CHANNEL,							\
 	.scan_type = {								\
-		.sign = 'u',							\
+		.format = 'u',							\
 		.realbits = 16,							\
 		.storagebits = 16,						\
 	},									\
@@ -997,7 +997,7 @@ static int ad4851_parse_channels_common(struct iio_dev *indio_dev,
 		st->bipolar_ch[reg] = fwnode_property_read_bool(child, "bipolar");
 
 		if (st->bipolar_ch[reg]) {
-			channels->scan_type.sign = 's';
+			channels->scan_type.format = 's';
 		} else {
 			ret = regmap_write(st->regmap, AD4851_REG_CHX_SOFTSPAN(reg),
 					   AD4851_SOFTSPAN_0V_40V);
diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c
index 5c1a8f886bcc..76fdc732d426 100644
--- a/drivers/iio/adc/ad7124.c
+++ b/drivers/iio/adc/ad7124.c
@@ -1182,7 +1182,7 @@ static const struct iio_chan_spec ad7124_channel_template = {
 		BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),
 	.info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE),
 	.scan_type = {
-		.sign = 'u',
+		.format = 'u',
 		.realbits = 24,
 		.storagebits = 32,
 		.endianness = IIO_BE,
@@ -1308,7 +1308,7 @@ static int ad7124_parse_channel_config(struct iio_dev *indio_dev,
 				 * measurement yields an unsigned value, but
 				 * this matches the device's manual.
 				 */
-				.sign = 'u',
+				.format = 'u',
 				.realbits = 24,
 				.storagebits = 32,
 				.endianness = IIO_BE,
diff --git a/drivers/iio/adc/ad7173.c b/drivers/iio/adc/ad7173.c
index d36612352b44..ca8cffd3b279 100644
--- a/drivers/iio/adc/ad7173.c
+++ b/drivers/iio/adc/ad7173.c
@@ -1549,7 +1549,7 @@ static const struct iio_info ad7173_info = {
 };
 
 static const struct iio_scan_type ad4113_scan_type = {
-	.sign = 'u',
+	.format = 'u',
 	.realbits = 16,
 	.storagebits = 16,
 	.endianness = IIO_BE,
@@ -1561,7 +1561,7 @@ static const struct iio_chan_spec ad7173_channel_template = {
 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 		BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_SAMP_FREQ),
 	.scan_type = {
-		.sign = 'u',
+		.format = 'u',
 		.realbits = 24,
 		.storagebits = 32,
 		.endianness = IIO_BE,
@@ -1577,7 +1577,7 @@ static const struct iio_chan_spec ad7173_temp_iio_channel_template = {
 		BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET) |
 		BIT(IIO_CHAN_INFO_SAMP_FREQ),
 	.scan_type = {
-		.sign = 'u',
+		.format = 'u',
 		.realbits = 24,
 		.storagebits = 32,
 		.endianness = IIO_BE,
diff --git a/drivers/iio/adc/ad7191.c b/drivers/iio/adc/ad7191.c
index d9cd903ffdd2..5ebdf06c093c 100644
--- a/drivers/iio/adc/ad7191.c
+++ b/drivers/iio/adc/ad7191.c
@@ -437,7 +437,7 @@ static const struct iio_chan_spec ad7191_channels[] = {
 		.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 24,
 			.storagebits = 32,
 			.endianness = IIO_BE,
@@ -458,7 +458,7 @@ static const struct iio_chan_spec ad7191_channels[] = {
 		.info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 24,
 			.storagebits = 32,
 			.endianness = IIO_BE,
@@ -479,7 +479,7 @@ static const struct iio_chan_spec ad7191_channels[] = {
 		.info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = 2,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 24,
 			.storagebits = 32,
 			.endianness = IIO_BE,
diff --git a/drivers/iio/adc/ad7192.c b/drivers/iio/adc/ad7192.c
index 530e1d307860..f1874071698c 100644
--- a/drivers/iio/adc/ad7192.c
+++ b/drivers/iio/adc/ad7192.c
@@ -1151,7 +1151,7 @@ static const struct iio_info ad7195_info = {
 		.ext_info = (_ext_info), \
 		.scan_index = (_si), \
 		.scan_type = { \
-			.sign = 'u', \
+			.format = 'u', \
 			.realbits = 24, \
 			.storagebits = 32, \
 			.endianness = IIO_BE, \
diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c
index 3364ac6c4631..0a8c0aa98916 100644
--- a/drivers/iio/adc/ad7266.c
+++ b/drivers/iio/adc/ad7266.c
@@ -160,7 +160,7 @@ static int ad7266_read_raw(struct iio_dev *indio_dev,
 		if (ret < 0)
 			return ret;
 		*val = (*val >> 2) & 0xfff;
-		if (chan->scan_type.sign == 's')
+		if (chan->scan_type.format == 's')
 			*val = sign_extend32(*val,
 					     chan->scan_type.realbits - 1);
 
@@ -196,7 +196,7 @@ static int ad7266_read_raw(struct iio_dev *indio_dev,
 		| BIT(IIO_CHAN_INFO_OFFSET),			\
 	.scan_index = (_chan),				\
 	.scan_type = {					\
-		.sign = (_sign),			\
+		.format = (_sign),			\
 		.realbits = 12,				\
 		.storagebits = 16,			\
 		.shift = 2,				\
@@ -244,7 +244,7 @@ static AD7266_DECLARE_SINGLE_ENDED_CHANNELS_FIXED(s, 's');
 		| BIT(IIO_CHAN_INFO_OFFSET),			\
 	.scan_index = (_chan),				\
 	.scan_type = {					\
-		.sign = _sign,			\
+		.format = _sign,			\
 		.realbits = 12,				\
 		.storagebits = 16,			\
 		.shift = 2,				\
diff --git a/drivers/iio/adc/ad7280a.c b/drivers/iio/adc/ad7280a.c
index ba12a3796e2b..d0f9e4db6a63 100644
--- a/drivers/iio/adc/ad7280a.c
+++ b/drivers/iio/adc/ad7280a.c
@@ -621,7 +621,7 @@ static void ad7280_common_fields_init(struct iio_chan_spec *chan, int addr,
 	chan->info_mask_shared_by_all = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO);
 	chan->address = addr;
 	chan->scan_index = cnt;
-	chan->scan_type.sign = 'u';
+	chan->scan_type.format = 'u';
 	chan->scan_type.realbits = 12;
 	chan->scan_type.storagebits = 32;
 }
@@ -638,7 +638,7 @@ static void ad7280_total_voltage_channel_init(struct iio_chan_spec *chan,
 	chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
 	chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE);
 	chan->scan_index = cnt;
-	chan->scan_type.sign = 'u';
+	chan->scan_type.format = 'u';
 	chan->scan_type.realbits = 32;
 	chan->scan_type.storagebits = 32;
 }
diff --git a/drivers/iio/adc/ad7298.c b/drivers/iio/adc/ad7298.c
index 7c0538ea15c8..c5a4a063a432 100644
--- a/drivers/iio/adc/ad7298.c
+++ b/drivers/iio/adc/ad7298.c
@@ -63,7 +63,7 @@ struct ad7298_state {
 		.address = index,					\
 		.scan_index = index,					\
 		.scan_type = {						\
-			.sign = 'u',					\
+			.format = 'u',					\
 			.realbits = 12,					\
 			.storagebits = 16,				\
 			.endianness = IIO_BE,				\
@@ -81,7 +81,7 @@ static const struct iio_chan_spec ad7298_channels[] = {
 		.address = AD7298_CH_TEMP,
 		.scan_index = -1,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 32,
 			.storagebits = 32,
 		},
diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c
index bfd908deefc0..e51a19c15ed8 100644
--- a/drivers/iio/adc/ad7380.c
+++ b/drivers/iio/adc/ad7380.c
@@ -155,13 +155,13 @@ enum {
 /* Extended scan types for 12-bit unsigned chips. */
 static const struct iio_scan_type ad7380_scan_type_12_u[] = {
 	[AD7380_SCAN_TYPE_NORMAL] = {
-		.sign = 'u',
+		.format = 'u',
 		.realbits = 12,
 		.storagebits = 16,
 		.endianness = IIO_CPU,
 	},
 	[AD7380_SCAN_TYPE_RESOLUTION_BOOST] = {
-		.sign = 'u',
+		.format = 'u',
 		.realbits = 14,
 		.storagebits = 16,
 		.endianness = IIO_CPU,
@@ -171,13 +171,13 @@ static const struct iio_scan_type ad7380_scan_type_12_u[] = {
 /* Extended scan types for 14-bit signed chips. */
 static const struct iio_scan_type ad7380_scan_type_14_s[] = {
 	[AD7380_SCAN_TYPE_NORMAL] = {
-		.sign = 's',
+		.format = 's',
 		.realbits = 14,
 		.storagebits = 16,
 		.endianness = IIO_CPU,
 	},
 	[AD7380_SCAN_TYPE_RESOLUTION_BOOST] = {
-		.sign = 's',
+		.format = 's',
 		.realbits = 16,
 		.storagebits = 16,
 		.endianness = IIO_CPU,
@@ -187,13 +187,13 @@ static const struct iio_scan_type ad7380_scan_type_14_s[] = {
 /* Extended scan types for 14-bit unsigned chips. */
 static const struct iio_scan_type ad7380_scan_type_14_u[] = {
 	[AD7380_SCAN_TYPE_NORMAL] = {
-		.sign = 'u',
+		.format = 'u',
 		.realbits = 14,
 		.storagebits = 16,
 		.endianness = IIO_CPU,
 	},
 	[AD7380_SCAN_TYPE_RESOLUTION_BOOST] = {
-		.sign = 'u',
+		.format = 'u',
 		.realbits = 16,
 		.storagebits = 16,
 		.endianness = IIO_CPU,
@@ -203,13 +203,13 @@ static const struct iio_scan_type ad7380_scan_type_14_u[] = {
 /* Extended scan types for 16-bit signed_chips. */
 static const struct iio_scan_type ad7380_scan_type_16_s[] = {
 	[AD7380_SCAN_TYPE_NORMAL] = {
-		.sign = 's',
+		.format = 's',
 		.realbits = 16,
 		.storagebits = 16,
 		.endianness = IIO_CPU,
 	},
 	[AD7380_SCAN_TYPE_RESOLUTION_BOOST] = {
-		.sign = 's',
+		.format = 's',
 		.realbits = 18,
 		.storagebits = 32,
 		.endianness = IIO_CPU,
@@ -219,13 +219,13 @@ static const struct iio_scan_type ad7380_scan_type_16_s[] = {
 /* Extended scan types for 16-bit unsigned chips. */
 static const struct iio_scan_type ad7380_scan_type_16_u[] = {
 	[AD7380_SCAN_TYPE_NORMAL] = {
-		.sign = 'u',
+		.format = 'u',
 		.realbits = 16,
 		.storagebits = 16,
 		.endianness = IIO_CPU,
 	},
 	[AD7380_SCAN_TYPE_RESOLUTION_BOOST] = {
-		.sign = 'u',
+		.format = 'u',
 		.realbits = 18,
 		.storagebits = 32,
 		.endianness = IIO_CPU,
@@ -240,13 +240,13 @@ static const struct iio_scan_type ad7380_scan_type_16_u[] = {
 /* Extended scan types for 12-bit unsigned chips, offload support. */
 static const struct iio_scan_type ad7380_scan_type_12_u_offload[] = {
 	[AD7380_SCAN_TYPE_NORMAL] = {
-		.sign = 'u',
+		.format = 'u',
 		.realbits = 12,
 		.storagebits = 32,
 		.endianness = IIO_CPU,
 	},
 	[AD7380_SCAN_TYPE_RESOLUTION_BOOST] = {
-		.sign = 'u',
+		.format = 'u',
 		.realbits = 14,
 		.storagebits = 32,
 		.endianness = IIO_CPU,
@@ -256,13 +256,13 @@ static const struct iio_scan_type ad7380_scan_type_12_u_offload[] = {
 /* Extended scan types for 14-bit signed chips, offload support. */
 static const struct iio_scan_type ad7380_scan_type_14_s_offload[] = {
 	[AD7380_SCAN_TYPE_NORMAL] = {
-		.sign = 's',
+		.format = 's',
 		.realbits = 14,
 		.storagebits = 32,
 		.endianness = IIO_CPU,
 	},
 	[AD7380_SCAN_TYPE_RESOLUTION_BOOST] = {
-		.sign = 's',
+		.format = 's',
 		.realbits = 16,
 		.storagebits = 32,
 		.endianness = IIO_CPU,
@@ -272,13 +272,13 @@ static const struct iio_scan_type ad7380_scan_type_14_s_offload[] = {
 /* Extended scan types for 14-bit unsigned chips, offload support. */
 static const struct iio_scan_type ad7380_scan_type_14_u_offload[] = {
 	[AD7380_SCAN_TYPE_NORMAL] = {
-		.sign = 'u',
+		.format = 'u',
 		.realbits = 14,
 		.storagebits = 32,
 		.endianness = IIO_CPU,
 	},
 	[AD7380_SCAN_TYPE_RESOLUTION_BOOST] = {
-		.sign = 'u',
+		.format = 'u',
 		.realbits = 16,
 		.storagebits = 32,
 		.endianness = IIO_CPU,
@@ -288,13 +288,13 @@ static const struct iio_scan_type ad7380_scan_type_14_u_offload[] = {
 /* Extended scan types for 16-bit signed_chips, offload support. */
 static const struct iio_scan_type ad7380_scan_type_16_s_offload[] = {
 	[AD7380_SCAN_TYPE_NORMAL] = {
-		.sign = 's',
+		.format = 's',
 		.realbits = 16,
 		.storagebits = 32,
 		.endianness = IIO_CPU,
 	},
 	[AD7380_SCAN_TYPE_RESOLUTION_BOOST] = {
-		.sign = 's',
+		.format = 's',
 		.realbits = 18,
 		.storagebits = 32,
 		.endianness = IIO_CPU,
@@ -304,13 +304,13 @@ static const struct iio_scan_type ad7380_scan_type_16_s_offload[] = {
 /* Extended scan types for 16-bit unsigned chips, offload support. */
 static const struct iio_scan_type ad7380_scan_type_16_u_offload[] = {
 	[AD7380_SCAN_TYPE_NORMAL] = {
-		.sign = 'u',
+		.format = 'u',
 		.realbits = 16,
 		.storagebits = 32,
 		.endianness = IIO_CPU,
 	},
 	[AD7380_SCAN_TYPE_RESOLUTION_BOOST] = {
-		.sign = 'u',
+		.format = 'u',
 		.realbits = 18,
 		.storagebits = 32,
 		.endianness = IIO_CPU,
@@ -1400,14 +1400,14 @@ static int ad7380_read_direct(struct ad7380_state *st, unsigned int scan_index,
 		return ret;
 
 	if (scan_type->realbits > 16) {
-		if (scan_type->sign == 's')
+		if (scan_type->format == 's')
 			*val = sign_extend32(*(u32 *)(st->scan_data + 4 * index),
 					     scan_type->realbits - 1);
 		else
 			*val = *(u32 *)(st->scan_data + 4 * index) &
 				GENMASK(scan_type->realbits - 1, 0);
 	} else {
-		if (scan_type->sign == 's')
+		if (scan_type->format == 's')
 			*val = sign_extend32(*(u16 *)(st->scan_data + 2 * index),
 					     scan_type->realbits - 1);
 		else
diff --git a/drivers/iio/adc/ad7405.c b/drivers/iio/adc/ad7405.c
index 9adf85a732ce..85566b635d3c 100644
--- a/drivers/iio/adc/ad7405.c
+++ b/drivers/iio/adc/ad7405.c
@@ -133,7 +133,7 @@ static const struct iio_chan_spec ad7405_channel = {
 	.differential = 1,
 	.scan_index = 0,
 	.scan_type = {
-		.sign = 'u',
+		.format = 'u',
 		.realbits = 16,
 		.storagebits = 16,
 	},
diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c
index 21d3f6aae972..a52e70827a8b 100644
--- a/drivers/iio/adc/ad7476.c
+++ b/drivers/iio/adc/ad7476.c
@@ -160,7 +160,7 @@ static int ad7476_read_raw(struct iio_dev *indio_dev,
 	.info_mask_separate = _info_mask_sep,			\
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
 	.scan_type = {						\
-		.sign = 'u',					\
+		.format = 'u',					\
 		.realbits = (bits),				\
 		.storagebits = 16,				\
 		.shift = (_shift),				\
diff --git a/drivers/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c
index d9271894f091..80aca38118e3 100644
--- a/drivers/iio/adc/ad7606.c
+++ b/drivers/iio/adc/ad7606.c
@@ -413,7 +413,7 @@ static int ad7606c_18bit_chan_scale_setup(struct iio_dev *indio_dev,
 		/* Bipolar single-ended ranges start at 0 (b0000) */
 		ci->reg_offset = 0;
 		ci->range = 3;
-		chan->scan_type.sign = 's';
+		chan->scan_type.format = 's';
 
 		return 0;
 	}
@@ -424,7 +424,7 @@ static int ad7606c_18bit_chan_scale_setup(struct iio_dev *indio_dev,
 	/* Unipolar single-ended ranges start at 5 (b0101) */
 	ci->reg_offset = 5;
 	ci->range = 1;
-	chan->scan_type.sign = 'u';
+	chan->scan_type.format = 'u';
 
 	return 0;
 }
@@ -458,7 +458,7 @@ static int ad7606c_16bit_chan_scale_setup(struct iio_dev *indio_dev,
 		ci->range = 1;
 		chan->differential = 1;
 		chan->channel2 = chan->channel;
-		chan->scan_type.sign = 's';
+		chan->scan_type.format = 's';
 
 		return 0;
 	}
@@ -472,7 +472,7 @@ static int ad7606c_16bit_chan_scale_setup(struct iio_dev *indio_dev,
 		/* Bipolar single-ended ranges start at 0 (b0000) */
 		ci->reg_offset = 0;
 		ci->range = 3;
-		chan->scan_type.sign = 's';
+		chan->scan_type.format = 's';
 
 		return 0;
 	}
@@ -483,7 +483,7 @@ static int ad7606c_16bit_chan_scale_setup(struct iio_dev *indio_dev,
 	/* Unipolar single-ended ranges start at 5 (b0101) */
 	ci->reg_offset = 5;
 	ci->range = 1;
-	chan->scan_type.sign = 'u';
+	chan->scan_type.format = 'u';
 
 	return 0;
 }
@@ -703,7 +703,7 @@ static int ad7606_scan_direct(struct iio_dev *indio_dev, unsigned int ch,
 
 	*val &= GENMASK(realbits - 1, 0);
 
-	if (chan->scan_type.sign == 's')
+	if (chan->scan_type.format == 's')
 		*val = sign_extend32(*val, realbits - 1);
 
 error_ret:
@@ -1412,7 +1412,7 @@ static int ad7606_probe_channels(struct iio_dev *indio_dev)
 		chan->indexed = 1;
 		chan->channel = i;
 		chan->scan_index = i;
-		chan->scan_type.sign = 's';
+		chan->scan_type.format = 's';
 		chan->scan_type.realbits = st->chip_info->bits;
 		/*
 		 * If in SPI offload mode, storagebits are set based
diff --git a/drivers/iio/adc/ad7625.c b/drivers/iio/adc/ad7625.c
index 0466c0c7eae4..bccc83437611 100644
--- a/drivers/iio/adc/ad7625.c
+++ b/drivers/iio/adc/ad7625.c
@@ -54,7 +54,7 @@ struct ad7625_chip_info {
 	.info_mask_separate = BIT(IIO_CHAN_INFO_SCALE),			\
 	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
 	.scan_index = 0,						\
-	.scan_type.sign = 's',						\
+	.scan_type.format = 's',					\
 	.scan_type.storagebits = (_bits) > 16 ? 32 : 16,		\
 	.scan_type.realbits = (_bits),					\
 }
diff --git a/drivers/iio/adc/ad7766.c b/drivers/iio/adc/ad7766.c
index 9e4a66477d2d..510fbdbb223b 100644
--- a/drivers/iio/adc/ad7766.c
+++ b/drivers/iio/adc/ad7766.c
@@ -154,7 +154,7 @@ static const struct iio_chan_spec ad7766_channels[] = {
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
 		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 24,
 			.storagebits = 32,
 			.endianness = IIO_BE,
diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c
index fcd8aea7152e..43da6d33340d 100644
--- a/drivers/iio/adc/ad7768-1.c
+++ b/drivers/iio/adc/ad7768-1.c
@@ -254,14 +254,14 @@ static const char * const ad7768_filter_enum[] = {
 
 static const struct iio_scan_type ad7768_scan_type[] = {
 	[AD7768_SCAN_TYPE_NORMAL] = {
-		.sign = 's',
+		.format = 's',
 		.realbits = 24,
 		.storagebits = 32,
 		.shift = 8,
 		.endianness = IIO_BE,
 	},
 	[AD7768_SCAN_TYPE_HIGH_SPEED] = {
-		.sign = 's',
+		.format = 's',
 		.realbits = 16,
 		.storagebits = 16,
 		.endianness = IIO_BE,
@@ -541,7 +541,7 @@ static void ad7768_fill_scale_tbl(struct iio_dev *dev)
 	u64 tmp2;
 
 	scan_type = iio_get_current_scan_type(dev, &dev->channels[0]);
-	if (scan_type->sign == 's')
+	if (scan_type->format == 's')
 		val2 = scan_type->realbits - 1;
 	else
 		val2 = scan_type->realbits;
@@ -1102,7 +1102,7 @@ static int ad7768_write_raw(struct iio_dev *indio_dev,
 		if (!st->chip->has_pga)
 			return -EOPNOTSUPP;
 
-		if (scan_type->sign == 's')
+		if (scan_type->format == 's')
 			gain_mode = ad7768_calc_pga_gain(st, val, val2,
 							 scan_type->realbits - 1);
 		else
diff --git a/drivers/iio/adc/ad7779.c b/drivers/iio/adc/ad7779.c
index 695cc79e78da..2e91ebc9196b 100644
--- a/drivers/iio/adc/ad7779.c
+++ b/drivers/iio/adc/ad7779.c
@@ -690,7 +690,7 @@ static const struct iio_chan_spec_ext_info ad7779_ext_filter[] = {
 		.scan_index = (index),					\
 		.ext_info = (_ext_info),				\
 		.scan_type = {						\
-			.sign = 's',					\
+			.format = 's',					\
 			.realbits = 24,					\
 			.storagebits = 32,				\
 			.endianness = IIO_BE,				\
diff --git a/drivers/iio/adc/ad7780.c b/drivers/iio/adc/ad7780.c
index 24d2dcad8f4d..23b50160d150 100644
--- a/drivers/iio/adc/ad7780.c
+++ b/drivers/iio/adc/ad7780.c
@@ -217,7 +217,7 @@ static const struct ad_sigma_delta_info ad7780_sigma_delta_info = {
 	.info_mask_shared_by_all = _mask_all,			\
 	.scan_index = 1,					\
 	.scan_type = {						\
-		.sign = 'u',					\
+		.format = 'u',					\
 		.realbits = (_bits),				\
 		.storagebits = 32,				\
 		.shift = (_wordsize) - (_bits),			\
diff --git a/drivers/iio/adc/ad7791.c b/drivers/iio/adc/ad7791.c
index 041fc25e3209..d033cecfc7cf 100644
--- a/drivers/iio/adc/ad7791.c
+++ b/drivers/iio/adc/ad7791.c
@@ -80,7 +80,7 @@
 		.info_mask_shared_by_all = _mask_all, \
 		.scan_index = (_si), \
 		.scan_type = { \
-			.sign = 'u', \
+			.format = 'u', \
 			.realbits = (_bits), \
 			.storagebits = (_storagebits), \
 			.shift = (_shift), \
diff --git a/drivers/iio/adc/ad7793.c b/drivers/iio/adc/ad7793.c
index ccf18ce48e34..bc28309f52c7 100644
--- a/drivers/iio/adc/ad7793.c
+++ b/drivers/iio/adc/ad7793.c
@@ -568,7 +568,7 @@ static const struct iio_info ad7797_info = {
 		.info_mask_shared_by_all = _mask_all, \
 		.scan_index = (_si), \
 		.scan_type = { \
-			.sign = 'u', \
+			.format = 'u', \
 			.realbits = (_bits), \
 			.storagebits = (_storagebits), \
 			.shift = (_shift), \
diff --git a/drivers/iio/adc/ad7887.c b/drivers/iio/adc/ad7887.c
index 87ff95643794..183a9fdf55d8 100644
--- a/drivers/iio/adc/ad7887.c
+++ b/drivers/iio/adc/ad7887.c
@@ -188,7 +188,7 @@ static int ad7887_read_raw(struct iio_dev *indio_dev,
 	.address = (x), \
 	.scan_index = (x), \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.realbits = 12, \
 		.storagebits = 16, \
 		.shift = 0, \
diff --git a/drivers/iio/adc/ad7923.c b/drivers/iio/adc/ad7923.c
index 0369151c7db1..d0f939ceccfb 100644
--- a/drivers/iio/adc/ad7923.c
+++ b/drivers/iio/adc/ad7923.c
@@ -91,7 +91,7 @@ enum ad7923_id {
 		.address = index,					\
 		.scan_index = index,					\
 		.scan_type = {						\
-			.sign = 'u',					\
+			.format = 'u',					\
 			.realbits = (bits),				\
 			.storagebits = 16,				\
 			.shift = 12 - (bits),				\
diff --git a/drivers/iio/adc/ad7944.c b/drivers/iio/adc/ad7944.c
index 7722cf9e8214..ae17adeebd3a 100644
--- a/drivers/iio/adc/ad7944.c
+++ b/drivers/iio/adc/ad7944.c
@@ -135,7 +135,7 @@ static const struct ad7944_chip_info _name##_chip_info = {		\
 			.channel = 0,					\
 			.channel2 = _diff ? 1 : 0,			\
 			.scan_index = 0,				\
-			.scan_type.sign = _diff ? 's' : 'u',		\
+			.scan_type.format = _diff ? 's' : 'u',		\
 			.scan_type.realbits = _bits,			\
 			.scan_type.storagebits = _bits > 16 ? 32 : 16,	\
 			.scan_type.endianness = IIO_CPU,		\
@@ -152,7 +152,7 @@ static const struct ad7944_chip_info _name##_chip_info = {		\
 			.channel = 0,					\
 			.channel2 = _diff ? 1 : 0,			\
 			.scan_index = 0,				\
-			.scan_type.sign = _diff ? 's' : 'u',		\
+			.scan_type.format = _diff ? 's' : 'u',		\
 			.scan_type.realbits = _bits,			\
 			.scan_type.storagebits = 32,			\
 			.scan_type.endianness = IIO_CPU,		\
@@ -364,7 +364,7 @@ static int ad7944_single_conversion(struct ad7944_adc *adc,
 			*val = adc->sample.raw.u16;
 	}
 
-	if (chan->scan_type.sign == 's')
+	if (chan->scan_type.format == 's')
 		*val = sign_extend32(*val, chan->scan_type.realbits - 1);
 	else
 		*val &= GENMASK(chan->scan_type.realbits - 1, 0);
@@ -410,7 +410,7 @@ static int ad7944_read_raw(struct iio_dev *indio_dev,
 		case IIO_VOLTAGE:
 			*val = adc->ref_mv;
 
-			if (chan->scan_type.sign == 's')
+			if (chan->scan_type.format == 's')
 				*val2 = chan->scan_type.realbits - 1;
 			else
 				*val2 = chan->scan_type.realbits;
diff --git a/drivers/iio/adc/ad799x.c b/drivers/iio/adc/ad799x.c
index 108bb22162ef..5731e6d04eb5 100644
--- a/drivers/iio/adc/ad799x.c
+++ b/drivers/iio/adc/ad799x.c
@@ -586,7 +586,7 @@ static const struct iio_event_spec ad799x_events[] = {
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
 	.scan_index = (_index), \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.realbits = (_realbits), \
 		.storagebits = 16, \
 		.shift = 12 - (_realbits), \
diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c
index 022888545580..31a7d23020d1 100644
--- a/drivers/iio/adc/ad9467.c
+++ b/drivers/iio/adc/ad9467.c
@@ -319,7 +319,7 @@ static void __ad9467_get_scale(struct ad9467_state *st, int index,
 	.info_mask_shared_by_type_available = avai_mask,		\
 	.scan_index = _si,						\
 	.scan_type = {							\
-		.sign = _sign,						\
+		.format = _sign,					\
 		.realbits = _bits,					\
 		.storagebits = 16,					\
 	},								\
@@ -343,7 +343,7 @@ static const struct iio_chan_spec ad9434_channels[] = {
 			BIT(IIO_CHAN_INFO_CALIBBIAS),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 12,
 			.storagebits = 16,
 		},
diff --git a/drivers/iio/adc/ade9000.c b/drivers/iio/adc/ade9000.c
index db085dc5e526..3523c8fb5409 100644
--- a/drivers/iio/adc/ade9000.c
+++ b/drivers/iio/adc/ade9000.c
@@ -451,7 +451,7 @@ static const struct iio_chan_spec_ext_info ade9000_ext_info[] = {
 	.scan_index = num,						\
 	.indexed = 1,							\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 32,						\
 		.storagebits = 32,					\
 		.endianness = IIO_BE,					\
@@ -471,7 +471,7 @@ static const struct iio_chan_spec_ext_info ade9000_ext_info[] = {
 	.scan_index = num + 1,	/* interleave with current channels */	\
 	.indexed = 1,							\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 32,						\
 		.storagebits = 32,					\
 		.endianness = IIO_BE,					\
diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index aa4ba3f5a506..559bed1ed59e 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -337,7 +337,7 @@ static const struct at91_adc_reg_layout sama7g5_layout = {
 		.address = addr,					\
 		.scan_index = index,					\
 		.scan_type = {						\
-			.sign = 'u',					\
+			.format = 'u',					\
 			.realbits = rbits,				\
 			.storagebits = 16,				\
 		},							\
@@ -366,7 +366,7 @@ static const struct at91_adc_reg_layout sama7g5_layout = {
 		.address = addr,					\
 		.scan_index = index,					\
 		.scan_type = {						\
-			.sign = 's',					\
+			.format = 's',					\
 			.realbits = rbits,				\
 			.storagebits = 16,				\
 		},							\
@@ -394,7 +394,7 @@ static const struct at91_adc_reg_layout sama7g5_layout = {
 		.channel2 = mod,					\
 		.scan_index = num,					\
 		.scan_type = {						\
-			.sign = 'u',					\
+			.format = 'u',					\
 			.realbits = 12,					\
 			.storagebits = 16,				\
 		},							\
@@ -411,7 +411,7 @@ static const struct at91_adc_reg_layout sama7g5_layout = {
 		.channel = num,						\
 		.scan_index = num,					\
 		.scan_type = {						\
-			.sign = 'u',					\
+			.format = 'u',					\
 			.realbits = 12,					\
 			.storagebits = 16,				\
 		},							\
@@ -1787,7 +1787,7 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
 	if (ret > 0) {
 		*val = st->conversion_value;
 		ret = at91_adc_adjust_val_osr(st, val);
-		if (chan->scan_type.sign == 's')
+		if (chan->scan_type.format == 's')
 			*val = sign_extend32(*val,
 					     chan->scan_type.realbits - 1);
 		st->conversion_done = false;
diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c
index 920dd9ffd27a..01d52190fd42 100644
--- a/drivers/iio/adc/at91_adc.c
+++ b/drivers/iio/adc/at91_adc.c
@@ -514,7 +514,7 @@ static int at91_adc_channel_init(struct iio_dev *idev)
 		chan->indexed = 1;
 		chan->channel = bit;
 		chan->scan_index = idx;
-		chan->scan_type.sign = 'u';
+		chan->scan_type.format = 'u';
 		chan->scan_type.realbits = st->res;
 		chan->scan_type.storagebits = 16;
 		chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE);
@@ -526,7 +526,7 @@ static int at91_adc_channel_init(struct iio_dev *idev)
 	timestamp->type = IIO_TIMESTAMP;
 	timestamp->channel = -1;
 	timestamp->scan_index = idx;
-	timestamp->scan_type.sign = 's';
+	timestamp->scan_type.format = 's';
 	timestamp->scan_type.realbits = 64;
 	timestamp->scan_type.storagebits = 64;
 
diff --git a/drivers/iio/adc/cc10001_adc.c b/drivers/iio/adc/cc10001_adc.c
index 2c51b90b7101..3a53ab745017 100644
--- a/drivers/iio/adc/cc10001_adc.c
+++ b/drivers/iio/adc/cc10001_adc.c
@@ -281,7 +281,7 @@ static int cc10001_adc_channel_init(struct iio_dev *indio_dev,
 		chan->indexed = 1;
 		chan->channel = bit;
 		chan->scan_index = idx;
-		chan->scan_type.sign = 'u';
+		chan->scan_type.format = 'u';
 		chan->scan_type.realbits = 10;
 		chan->scan_type.storagebits = 16;
 		chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE);
@@ -293,7 +293,7 @@ static int cc10001_adc_channel_init(struct iio_dev *indio_dev,
 	timestamp->type = IIO_TIMESTAMP;
 	timestamp->channel = -1;
 	timestamp->scan_index = idx;
-	timestamp->scan_type.sign = 's';
+	timestamp->scan_type.format = 's';
 	timestamp->scan_type.realbits = 64;
 	timestamp->scan_type.storagebits = 64;
 
diff --git a/drivers/iio/adc/cpcap-adc.c b/drivers/iio/adc/cpcap-adc.c
index d9ee2ea116a7..0c5034c4279e 100644
--- a/drivers/iio/adc/cpcap-adc.c
+++ b/drivers/iio/adc/cpcap-adc.c
@@ -340,7 +340,7 @@ static const int temp_map[CPCAP_MAX_TEMP_LVL][2] = {
 			      BIT(IIO_CHAN_INFO_PROCESSED), \
 	.scan_index = (_index), \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.realbits = 10, \
 		.storagebits = 16, \
 		.endianness = IIO_CPU, \
diff --git a/drivers/iio/adc/dln2-adc.c b/drivers/iio/adc/dln2-adc.c
index eb902a946efe..0db0ac027c9e 100644
--- a/drivers/iio/adc/dln2-adc.c
+++ b/drivers/iio/adc/dln2-adc.c
@@ -438,7 +438,7 @@ static int dln2_update_scan_mode(struct iio_dev *indio_dev,
 	lval.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SCALE) |	\
 				       BIT(IIO_CHAN_INFO_SAMP_FREQ);	\
 	lval.scan_index = idx;						\
-	lval.scan_type.sign = 'u';					\
+	lval.scan_type.format = 'u';					\
 	lval.scan_type.realbits = DLN2_ADC_DATA_BITS;			\
 	lval.scan_type.storagebits = 16;				\
 	lval.scan_type.endianness = IIO_LE;				\
@@ -449,7 +449,7 @@ static int dln2_update_scan_mode(struct iio_dev *indio_dev,
 	lval.type = IIO_TIMESTAMP;			\
 	lval.channel = -1;				\
 	lval.scan_index = _si;				\
-	lval.scan_type.sign = 's';			\
+	lval.scan_type.format = 's';			\
 	lval.scan_type.realbits = 64;			\
 	lval.scan_type.storagebits = 64;		\
 }
diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c
index 1db8b68a8f64..01fe7fa171a5 100644
--- a/drivers/iio/adc/hx711.c
+++ b/drivers/iio/adc/hx711.c
@@ -432,7 +432,7 @@ static const struct iio_chan_spec hx711_chan_spec[] = {
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 24,
 			.storagebits = 32,
 			.endianness = IIO_CPU,
@@ -446,7 +446,7 @@ static const struct iio_chan_spec hx711_chan_spec[] = {
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 24,
 			.storagebits = 32,
 			.endianness = IIO_CPU,
diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c
index 857e1b69d6cd..bee4622f4cf6 100644
--- a/drivers/iio/adc/ina2xx-adc.c
+++ b/drivers/iio/adc/ina2xx-adc.c
@@ -623,7 +623,7 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev,
 	.info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
 	.scan_index = (_index), \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.realbits = 16, \
 		.storagebits = 16, \
 		.endianness = IIO_CPU, \
@@ -641,7 +641,7 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev,
 				   BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
 	.scan_index = (_index), \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.realbits = 16, \
 		.storagebits = 16, \
 		.endianness = IIO_CPU, \
@@ -666,7 +666,7 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev,
 	.info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
 	.scan_index = (_index), \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.shift = _shift, \
 		.realbits = 16 - _shift, \
 		.storagebits = 16, \
@@ -686,7 +686,7 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev,
 				   BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
 	.scan_index = (_index), \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.realbits = 16, \
 		.storagebits = 16, \
 		.endianness = IIO_LE, \
diff --git a/drivers/iio/adc/ingenic-adc.c b/drivers/iio/adc/ingenic-adc.c
index 1e802c8779a4..129b2b697bda 100644
--- a/drivers/iio/adc/ingenic-adc.c
+++ b/drivers/iio/adc/ingenic-adc.c
@@ -456,7 +456,7 @@ static const struct iio_chan_spec jz4770_channels[] = {
 		.channel = INGENIC_ADC_TOUCH_XP,
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 12,
 			.storagebits = 16,
 		},
@@ -467,7 +467,7 @@ static const struct iio_chan_spec jz4770_channels[] = {
 		.channel = INGENIC_ADC_TOUCH_YP,
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 12,
 			.storagebits = 16,
 		},
@@ -478,7 +478,7 @@ static const struct iio_chan_spec jz4770_channels[] = {
 		.channel = INGENIC_ADC_TOUCH_XN,
 		.scan_index = 2,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 12,
 			.storagebits = 16,
 		},
@@ -489,7 +489,7 @@ static const struct iio_chan_spec jz4770_channels[] = {
 		.channel = INGENIC_ADC_TOUCH_YN,
 		.scan_index = 3,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 12,
 			.storagebits = 16,
 		},
@@ -500,7 +500,7 @@ static const struct iio_chan_spec jz4770_channels[] = {
 		.channel = INGENIC_ADC_TOUCH_XD,
 		.scan_index = 4,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 12,
 			.storagebits = 16,
 		},
@@ -511,7 +511,7 @@ static const struct iio_chan_spec jz4770_channels[] = {
 		.channel = INGENIC_ADC_TOUCH_YD,
 		.scan_index = 5,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 12,
 			.storagebits = 16,
 		},
diff --git a/drivers/iio/adc/max1027.c b/drivers/iio/adc/max1027.c
index 7e736e77d8bb..270b38b2a1ea 100644
--- a/drivers/iio/adc/max1027.c
+++ b/drivers/iio/adc/max1027.c
@@ -103,7 +103,7 @@ MODULE_DEVICE_TABLE(of, max1027_adc_dt_ids);
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
 		.scan_index = index + 1,				\
 		.scan_type = {						\
-			.sign = 'u',					\
+			.format = 'u',					\
 			.realbits = depth,				\
 			.storagebits = 16,				\
 			.shift = (depth == 10) ? 2 : 0,			\
@@ -119,7 +119,7 @@ MODULE_DEVICE_TABLE(of, max1027_adc_dt_ids);
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
 		.scan_index = 0,					\
 		.scan_type = {						\
-			.sign = 'u',					\
+			.format = 'u',					\
 			.realbits = 12,					\
 			.storagebits = 16,				\
 			.endianness = IIO_BE,				\
diff --git a/drivers/iio/adc/max1118.c b/drivers/iio/adc/max1118.c
index 7d7001e8e3d9..34a8eb933991 100644
--- a/drivers/iio/adc/max1118.c
+++ b/drivers/iio/adc/max1118.c
@@ -54,7 +54,7 @@ struct max1118 {
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
 		.scan_index = ch,					\
 		.scan_type = {						\
-			.sign = 'u',					\
+			.format = 'u',					\
 			.realbits = 8,					\
 			.storagebits = 8,				\
 		},							\
diff --git a/drivers/iio/adc/max11205.c b/drivers/iio/adc/max11205.c
index 6c803df220b6..04faf995ff99 100644
--- a/drivers/iio/adc/max11205.c
+++ b/drivers/iio/adc/max11205.c
@@ -75,7 +75,7 @@ static const struct iio_chan_spec max11205_channels[] = {
 		.type = IIO_VOLTAGE,
 		.indexed = 1,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_BE,
diff --git a/drivers/iio/adc/max11410.c b/drivers/iio/adc/max11410.c
index 511b2f14dfaf..46e15608cba9 100644
--- a/drivers/iio/adc/max11410.c
+++ b/drivers/iio/adc/max11410.c
@@ -156,7 +156,7 @@ static const struct iio_chan_spec chanspec_template = {
 	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 	.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 	.scan_type = {
-		.sign = 's',
+		.format = 's',
 		.realbits = 24,
 		.storagebits = 32,
 		.endianness = IIO_LE,
diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c
index 9dd547e62b6c..74728dd6ac86 100644
--- a/drivers/iio/adc/max1363.c
+++ b/drivers/iio/adc/max1363.c
@@ -473,7 +473,7 @@ static const struct iio_event_spec max1363_events[] = {
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
 		.datasheet_name = "AIN"#num,				\
 		.scan_type = {						\
-			.sign = 'u',					\
+			.format = 'u',					\
 			.realbits = bits,				\
 			.storagebits = (bits > 8) ? 16 : 8,		\
 			.endianness = IIO_BE,				\
@@ -496,7 +496,7 @@ static const struct iio_event_spec max1363_events[] = {
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
 		.datasheet_name = "AIN"#num"-AIN"#num2,			\
 		.scan_type = {						\
-			.sign = 's',					\
+			.format = 's',					\
 			.realbits = bits,				\
 			.storagebits = (bits > 8) ? 16 : 8,		\
 			.endianness = IIO_BE,				\
diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c
index ddc3721f3f68..1c9338594714 100644
--- a/drivers/iio/adc/mcp3911.c
+++ b/drivers/iio/adc/mcp3911.c
@@ -446,7 +446,7 @@ static int mcp3911_calc_scale_table(u32 vref_mv)
 		.info_mask_separate_available =			\
 			BIT(IIO_CHAN_INFO_SCALE),		\
 		.scan_type = {					\
-			.sign = 's',				\
+			.format = 's',				\
 			.realbits = 24,				\
 			.storagebits = 32,			\
 			.endianness = IIO_BE,			\
diff --git a/drivers/iio/adc/mt6359-auxadc.c b/drivers/iio/adc/mt6359-auxadc.c
index f426a289e867..98b11237ca8d 100644
--- a/drivers/iio/adc/mt6359-auxadc.c
+++ b/drivers/iio/adc/mt6359-auxadc.c
@@ -196,7 +196,7 @@ struct mtk_pmic_auxadc_info {
 	.scan_index = PMIC_AUXADC_CHAN_##_ch_idx,				\
 	.datasheet_name = __stringify(_name),					\
 	.scan_type =  {								\
-		.sign = 'u',							\
+		.format = 'u',							\
 		.realbits = _nbits,						\
 		.storagebits = 16,						\
 		.endianness = IIO_CPU						\
diff --git a/drivers/iio/adc/mt6360-adc.c b/drivers/iio/adc/mt6360-adc.c
index e0e4df418612..c2b2b7aa8dd5 100644
--- a/drivers/iio/adc/mt6360-adc.c
+++ b/drivers/iio/adc/mt6360-adc.c
@@ -230,7 +230,7 @@ static const struct iio_info mt6360_adc_iio_info = {
 	.scan_index = MT6360_CHAN_##_idx,			\
 	.datasheet_name = #_idx,				\
 	.scan_type =  {						\
-		.sign = 'u',					\
+		.format = 'u',					\
 		.realbits = 16,					\
 		.storagebits = 16,				\
 		.endianness = IIO_CPU,				\
diff --git a/drivers/iio/adc/mxs-lradc-adc.c b/drivers/iio/adc/mxs-lradc-adc.c
index dda5182a5076..97b04bccc5a8 100644
--- a/drivers/iio/adc/mxs-lradc-adc.c
+++ b/drivers/iio/adc/mxs-lradc-adc.c
@@ -582,7 +582,7 @@ static const struct iio_buffer_setup_ops mxs_lradc_adc_buffer_ops = {
 	.channel = (idx),					\
 	.address = (idx),					\
 	.scan_type = {						\
-		.sign = 'u',					\
+		.format = 'u',					\
 		.realbits = LRADC_RESOLUTION,			\
 		.storagebits = 32,				\
 	},							\
@@ -607,7 +607,7 @@ static const struct iio_chan_spec mx23_lradc_chan_spec[] = {
 				      BIT(IIO_CHAN_INFO_OFFSET) |
 				      BIT(IIO_CHAN_INFO_SCALE),
 		.channel = 8,
-		.scan_type = {.sign = 'u', .realbits = 18, .storagebits = 32,},
+		.scan_type = {.format = 'u', .realbits = 18, .storagebits = 32,},
 		.datasheet_name = "TEMP_DIE",
 	},
 	/* Hidden channel to keep indexes */
@@ -643,7 +643,7 @@ static const struct iio_chan_spec mx28_lradc_chan_spec[] = {
 				      BIT(IIO_CHAN_INFO_OFFSET) |
 				      BIT(IIO_CHAN_INFO_SCALE),
 		.channel = 8,
-		.scan_type = {.sign = 'u', .realbits = 18, .storagebits = 32,},
+		.scan_type = {.format = 'u', .realbits = 18, .storagebits = 32,},
 		.datasheet_name = "TEMP_DIE",
 	},
 	/* Hidden channel to keep indexes */
diff --git a/drivers/iio/adc/nxp-sar-adc.c b/drivers/iio/adc/nxp-sar-adc.c
index 9efa883c277d..2faa4c583167 100644
--- a/drivers/iio/adc/nxp-sar-adc.c
+++ b/drivers/iio/adc/nxp-sar-adc.c
@@ -167,7 +167,7 @@ struct nxp_sar_adc_data {
 				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
 	.scan_index = (_idx),					\
 	.scan_type = {						\
-		.sign = 'u',					\
+		.format = 'u',					\
 		.realbits = 12,					\
 		.storagebits = 16,				\
 	},							\
diff --git a/drivers/iio/adc/pac1921.c b/drivers/iio/adc/pac1921.c
index a0227b57f238..ec800d2add06 100644
--- a/drivers/iio/adc/pac1921.c
+++ b/drivers/iio/adc/pac1921.c
@@ -937,7 +937,7 @@ static const struct iio_chan_spec pac1921_channels[] = {
 		.address = PAC1921_REG_VBUS,
 		.scan_index = PAC1921_CHAN_VBUS,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 10,
 			.storagebits = 16,
 			.endianness = IIO_CPU
@@ -960,7 +960,7 @@ static const struct iio_chan_spec pac1921_channels[] = {
 		.address = PAC1921_REG_VSENSE,
 		.scan_index = PAC1921_CHAN_VSENSE,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 10,
 			.storagebits = 16,
 			.endianness = IIO_CPU
@@ -983,7 +983,7 @@ static const struct iio_chan_spec pac1921_channels[] = {
 		.address = PAC1921_REG_VSENSE,
 		.scan_index = PAC1921_CHAN_CURRENT,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 10,
 			.storagebits = 16,
 			.endianness = IIO_CPU
@@ -1005,7 +1005,7 @@ static const struct iio_chan_spec pac1921_channels[] = {
 		.address = PAC1921_REG_VPOWER,
 		.scan_index = PAC1921_CHAN_POWER,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 10,
 			.storagebits = 16,
 			.endianness = IIO_CPU
diff --git a/drivers/iio/adc/pac1934.c b/drivers/iio/adc/pac1934.c
index 712b5e9caba6..ab489739a3a5 100644
--- a/drivers/iio/adc/pac1934.c
+++ b/drivers/iio/adc/pac1934.c
@@ -330,7 +330,7 @@ struct pac1934_chip_info {
 	.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
 	.scan_index = (_si),							\
 	.scan_type = {								\
-		.sign = 'u',							\
+		.format = 'u',							\
 		.realbits = 48,							\
 		.storagebits = 64,						\
 		.endianness = IIO_CPU,						\
@@ -348,7 +348,7 @@ struct pac1934_chip_info {
 	.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
 	.scan_index = (_si),							\
 	.scan_type = {								\
-		.sign = 'u',							\
+		.format = 'u',							\
 		.realbits = 16,							\
 		.storagebits = 16,						\
 		.endianness = IIO_CPU,						\
@@ -366,7 +366,7 @@ struct pac1934_chip_info {
 	.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
 	.scan_index = (_si),							\
 	.scan_type = {								\
-		.sign = 'u',							\
+		.format = 'u',							\
 		.realbits = 16,							\
 		.storagebits = 16,						\
 		.endianness = IIO_CPU,						\
@@ -384,7 +384,7 @@ struct pac1934_chip_info {
 	.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
 	.scan_index = (_si),							\
 	.scan_type = {								\
-		.sign = 'u',							\
+		.format = 'u',							\
 		.realbits = 16,							\
 		.storagebits = 16,						\
 		.endianness = IIO_CPU,						\
@@ -402,7 +402,7 @@ struct pac1934_chip_info {
 	.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
 	.scan_index = (_si),							\
 	.scan_type = {								\
-		.sign = 'u',							\
+		.format = 'u',							\
 		.realbits = 16,							\
 		.storagebits = 16,						\
 		.endianness = IIO_CPU,						\
@@ -420,7 +420,7 @@ struct pac1934_chip_info {
 	.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
 	.scan_index = (_si),							\
 	.scan_type = {								\
-		.sign = 'u',							\
+		.format = 'u',							\
 		.realbits = 28,							\
 		.storagebits = 32,						\
 		.shift = 4,							\
@@ -839,7 +839,7 @@ static int pac1934_read_raw(struct iio_dev *indio_dev,
 		case PAC1934_VBUS_AVG_3_ADDR:
 		case PAC1934_VBUS_AVG_4_ADDR:
 			*val = PAC1934_VOLTAGE_MILLIVOLTS_MAX;
-			if (chan->scan_type.sign == 'u')
+			if (chan->scan_type.format == 'u')
 				*val2 = PAC1934_VOLTAGE_U_RES;
 			else
 				*val2 = PAC1934_VOLTAGE_S_RES;
@@ -858,7 +858,7 @@ static int pac1934_read_raw(struct iio_dev *indio_dev,
 		case PAC1934_VSENSE_AVG_3_ADDR:
 		case PAC1934_VSENSE_AVG_4_ADDR:
 			*val = PAC1934_MAX_VSENSE_RSHIFTED_BY_16B;
-			if (chan->scan_type.sign == 'u')
+			if (chan->scan_type.format == 'u')
 				*val2 = info->shunts[channel];
 			else
 				*val2 = info->shunts[channel] >> 1;
@@ -873,7 +873,7 @@ static int pac1934_read_raw(struct iio_dev *indio_dev,
 		case PAC1934_VPOWER_3_ADDR:
 		case PAC1934_VPOWER_4_ADDR:
 			*val = PAC1934_MAX_VPOWER_RSHIFTED_BY_28B;
-			if (chan->scan_type.sign == 'u')
+			if (chan->scan_type.format == 'u')
 				*val2 = info->shunts[channel];
 			else
 				*val2 = info->shunts[channel] >> 1;
@@ -888,7 +888,7 @@ static int pac1934_read_raw(struct iio_dev *indio_dev,
 			 */
 			*val = PAC1934_SCALE_CONSTANT;
 
-			if (chan->scan_type.sign == 'u')
+			if (chan->scan_type.format == 'u')
 				*val2 = info->shunts[channel];
 			else
 				*val2 = info->shunts[channel] >> 1;
@@ -1393,17 +1393,17 @@ static int pac1934_prep_iio_channels(struct pac1934_chip_info *info, struct iio_
 		 * whole chip rail(channel) is bi-directional
 		 */
 		if (info->bi_dir[cnt]) {
-			ch_sp[PAC1934_CH_ENERGY].scan_type.sign = 's';
+			ch_sp[PAC1934_CH_ENERGY].scan_type.format = 's';
 			ch_sp[PAC1934_CH_ENERGY].scan_type.realbits = 47;
-			ch_sp[PAC1934_CH_POWER].scan_type.sign = 's';
+			ch_sp[PAC1934_CH_POWER].scan_type.format = 's';
 			ch_sp[PAC1934_CH_POWER].scan_type.realbits = 27;
-			ch_sp[PAC1934_CH_VOLTAGE].scan_type.sign = 's';
+			ch_sp[PAC1934_CH_VOLTAGE].scan_type.format = 's';
 			ch_sp[PAC1934_CH_VOLTAGE].scan_type.realbits = 15;
-			ch_sp[PAC1934_CH_CURRENT].scan_type.sign = 's';
+			ch_sp[PAC1934_CH_CURRENT].scan_type.format = 's';
 			ch_sp[PAC1934_CH_CURRENT].scan_type.realbits = 15;
-			ch_sp[PAC1934_CH_VOLTAGE_AVERAGE].scan_type.sign = 's';
+			ch_sp[PAC1934_CH_VOLTAGE_AVERAGE].scan_type.format = 's';
 			ch_sp[PAC1934_CH_VOLTAGE_AVERAGE].scan_type.realbits = 15;
-			ch_sp[PAC1934_CH_CURRENT_AVERAGE].scan_type.sign = 's';
+			ch_sp[PAC1934_CH_CURRENT_AVERAGE].scan_type.format = 's';
 			ch_sp[PAC1934_CH_CURRENT_AVERAGE].scan_type.realbits = 15;
 		}
 		tmp_data += sizeof(pac1934_single_channel);
diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c
index 0f0bf2906af0..44d084b32dee 100644
--- a/drivers/iio/adc/rockchip_saradc.c
+++ b/drivers/iio/adc/rockchip_saradc.c
@@ -221,7 +221,7 @@ static const struct iio_info rockchip_saradc_iio_info = {
 	.datasheet_name = _id,					\
 	.scan_index = _index,					\
 	.scan_type = {						\
-		.sign = 'u',					\
+		.format = 'u',					\
 		.realbits = _res,				\
 		.storagebits = 16,				\
 		.endianness = IIO_CPU,				\
diff --git a/drivers/iio/adc/rtq6056.c b/drivers/iio/adc/rtq6056.c
index 2bf3a09ac6b0..b16e0dc507c1 100644
--- a/drivers/iio/adc/rtq6056.c
+++ b/drivers/iio/adc/rtq6056.c
@@ -127,7 +127,7 @@ static const struct iio_chan_spec rtq6056_channels[RTQ6056_MAX_CHANNEL + 1] = {
 		.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
@@ -146,7 +146,7 @@ static const struct iio_chan_spec rtq6056_channels[RTQ6056_MAX_CHANNEL + 1] = {
 		.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
@@ -164,7 +164,7 @@ static const struct iio_chan_spec rtq6056_channels[RTQ6056_MAX_CHANNEL + 1] = {
 		.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
 		.scan_index = 2,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
@@ -181,7 +181,7 @@ static const struct iio_chan_spec rtq6056_channels[RTQ6056_MAX_CHANNEL + 1] = {
 		.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
 		.scan_index = 3,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
@@ -210,7 +210,7 @@ static const struct iio_chan_spec rtq6059_channels[RTQ6056_MAX_CHANNEL + 1] = {
 		.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
@@ -228,7 +228,7 @@ static const struct iio_chan_spec rtq6059_channels[RTQ6056_MAX_CHANNEL + 1] = {
 		.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
@@ -246,7 +246,7 @@ static const struct iio_chan_spec rtq6059_channels[RTQ6056_MAX_CHANNEL + 1] = {
 		.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
 		.scan_index = 2,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
@@ -263,7 +263,7 @@ static const struct iio_chan_spec rtq6059_channels[RTQ6056_MAX_CHANNEL + 1] = {
 		.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
 		.scan_index = 3,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
diff --git a/drivers/iio/adc/sd_adc_modulator.c b/drivers/iio/adc/sd_adc_modulator.c
index 9f7a75168aac..584f9c2d97f9 100644
--- a/drivers/iio/adc/sd_adc_modulator.c
+++ b/drivers/iio/adc/sd_adc_modulator.c
@@ -21,7 +21,7 @@ static const struct iio_chan_spec iio_sd_mod_ch = {
 	.type = IIO_VOLTAGE,
 	.indexed = 1,
 	.scan_type = {
-		.sign = 'u',
+		.format = 'u',
 		.realbits = 1,
 		.shift = 0,
 	},
diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c
index 2d7f88459c7c..80499bca915e 100644
--- a/drivers/iio/adc/stm32-adc.c
+++ b/drivers/iio/adc/stm32-adc.c
@@ -2109,7 +2109,7 @@ static void stm32_adc_chan_init_one(struct iio_dev *indio_dev,
 		chan->info_mask_shared_by_all |= BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO);
 		chan->info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO);
 	}
-	chan->scan_type.sign = 'u';
+	chan->scan_type.format = 'u';
 	chan->scan_type.realbits = adc->cfg->adc_info->resolutions[adc->res];
 	chan->scan_type.storagebits = 16;
 	chan->ext_info = stm32_adc_ext_info;
@@ -2448,7 +2448,7 @@ static int stm32_adc_chan_fw_init(struct iio_dev *indio_dev, bool timestamping)
 		timestamp->type = IIO_TIMESTAMP;
 		timestamp->channel = -1;
 		timestamp->scan_index = scan_index;
-		timestamp->scan_type.sign = 's';
+		timestamp->scan_type.format = 's';
 		timestamp->scan_type.realbits = 64;
 		timestamp->scan_type.storagebits = 64;
 
diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c
index 9664b9bd75d4..7241c443060e 100644
--- a/drivers/iio/adc/stm32-dfsdm-adc.c
+++ b/drivers/iio/adc/stm32-dfsdm-adc.c
@@ -1559,7 +1559,7 @@ static int stm32_dfsdm_adc_chan_init_one(struct iio_dev *indio_dev, struct iio_c
 	} else {
 		ch->scan_type.shift = 8;
 	}
-	ch->scan_type.sign = 's';
+	ch->scan_type.format = 's';
 	ch->scan_type.realbits = 24;
 	ch->scan_type.storagebits = 32;
 
diff --git a/drivers/iio/adc/ti-adc081c.c b/drivers/iio/adc/ti-adc081c.c
index 8ef51c57912d..308e03c08068 100644
--- a/drivers/iio/adc/ti-adc081c.c
+++ b/drivers/iio/adc/ti-adc081c.c
@@ -81,7 +81,7 @@ static int adc081c_read_raw(struct iio_dev *iio,
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
 	.scan_type = {						\
-		.sign = 'u',					\
+		.format = 'u',					\
 		.realbits = (_bits),				\
 		.storagebits = 16,				\
 		.shift = 12 - (_bits),				\
diff --git a/drivers/iio/adc/ti-adc0832.c b/drivers/iio/adc/ti-adc0832.c
index cfcdafbe284b..41554d6f1fd9 100644
--- a/drivers/iio/adc/ti-adc0832.c
+++ b/drivers/iio/adc/ti-adc0832.c
@@ -49,7 +49,7 @@ struct adc0832 {
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
 		.scan_index = chan,					\
 		.scan_type = {						\
-			.sign = 'u',					\
+			.format = 'u',					\
 			.realbits = 8,					\
 			.storagebits = 8,				\
 		},							\
@@ -66,7 +66,7 @@ struct adc0832 {
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
 		.scan_index = si,					\
 		.scan_type = {						\
-			.sign = 'u',					\
+			.format = 'u',					\
 			.realbits = 8,					\
 			.storagebits = 8,				\
 		},							\
diff --git a/drivers/iio/adc/ti-adc084s021.c b/drivers/iio/adc/ti-adc084s021.c
index a100f770fa1c..0651847bfd70 100644
--- a/drivers/iio/adc/ti-adc084s021.c
+++ b/drivers/iio/adc/ti-adc084s021.c
@@ -46,7 +46,7 @@ struct adc084s021 {
 		.indexed = 1,                                        \
 		.scan_index = (num),                                 \
 		.scan_type = {                                       \
-			.sign = 'u',                                       \
+			.format = 'u',                                     \
 			.realbits = 8,                                     \
 			.storagebits = 16,                                 \
 			.shift = 4,                                        \
diff --git a/drivers/iio/adc/ti-adc108s102.c b/drivers/iio/adc/ti-adc108s102.c
index 7d615e2bbf39..2103ef1b149e 100644
--- a/drivers/iio/adc/ti-adc108s102.c
+++ b/drivers/iio/adc/ti-adc108s102.c
@@ -90,7 +90,7 @@ struct adc108s102_state {
 		.address = index,					\
 		.scan_index = index,					\
 		.scan_type = {						\
-			.sign = 'u',					\
+			.format = 'u',					\
 			.realbits = ADC108S102_BITS,			\
 			.storagebits = 16,				\
 			.endianness = IIO_BE,				\
diff --git a/drivers/iio/adc/ti-adc12138.c b/drivers/iio/adc/ti-adc12138.c
index e5ec4b073daa..368ac836316d 100644
--- a/drivers/iio/adc/ti-adc12138.c
+++ b/drivers/iio/adc/ti-adc12138.c
@@ -67,7 +67,7 @@ struct adc12138 {
 					| BIT(IIO_CHAN_INFO_OFFSET),	\
 		.scan_index = chan,					\
 		.scan_type = {						\
-			.sign = 's',					\
+			.format = 's',					\
 			.realbits = 13,					\
 			.storagebits = 16,				\
 			.shift = 3,					\
@@ -87,7 +87,7 @@ struct adc12138 {
 					| BIT(IIO_CHAN_INFO_OFFSET),	\
 		.scan_index = si,					\
 		.scan_type = {						\
-			.sign = 's',					\
+			.format = 's',					\
 			.realbits = 13,					\
 			.storagebits = 16,				\
 			.shift = 3,					\
diff --git a/drivers/iio/adc/ti-adc161s626.c b/drivers/iio/adc/ti-adc161s626.c
index 28aa6b80160c..2446b0be6716 100644
--- a/drivers/iio/adc/ti-adc161s626.c
+++ b/drivers/iio/adc/ti-adc161s626.c
@@ -38,7 +38,7 @@ static const struct iio_chan_spec ti_adc141s626_channels[] = {
 				      BIT(IIO_CHAN_INFO_OFFSET),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 14,
 			.storagebits = 16,
 		},
@@ -55,7 +55,7 @@ static const struct iio_chan_spec ti_adc161s626_channels[] = {
 				      BIT(IIO_CHAN_INFO_OFFSET),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 		},
diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c
index f2a93c63ca14..1a165bc88a46 100644
--- a/drivers/iio/adc/ti-ads1015.c
+++ b/drivers/iio/adc/ti-ads1015.c
@@ -193,7 +193,7 @@ static const struct iio_event_spec ads1015_events[] = {
 				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
 	.scan_index = _addr,					\
 	.scan_type = {						\
-		.sign = 's',					\
+		.format = 's',					\
 		.realbits = (_realbits),			\
 		.storagebits = FIT_CHECK((_realbits) + (_shift), 16),	\
 		.shift = (_shift),				\
@@ -219,7 +219,7 @@ static const struct iio_event_spec ads1015_events[] = {
 				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
 	.scan_index = _addr,					\
 	.scan_type = {						\
-		.sign = 's',					\
+		.format = 's',					\
 		.realbits = (_realbits),			\
 		.storagebits = FIT_CHECK((_realbits) + (_shift), 16),	\
 		.shift = (_shift),				\
diff --git a/drivers/iio/adc/ti-ads1018.c b/drivers/iio/adc/ti-ads1018.c
index 6246b3cab71f..b3757657aa4c 100644
--- a/drivers/iio/adc/ti-ads1018.c
+++ b/drivers/iio/adc/ti-ads1018.c
@@ -105,7 +105,7 @@ struct ads1018 {
 	.channel2 = _chan2,							\
 	.scan_index = _index,							\
 	.scan_type = {								\
-		.sign = 's',							\
+		.format = 's',							\
 		.realbits = _realbits,						\
 		.storagebits = 16,						\
 		.shift = 16 - _realbits,					\
@@ -125,7 +125,7 @@ struct ads1018 {
 	.channel = _chan,							\
 	.scan_index = _index,							\
 	.scan_type = {								\
-		.sign = 's',							\
+		.format = 's',							\
 		.realbits = _realbits,						\
 		.storagebits = 16,						\
 		.shift = 16 - _realbits,					\
@@ -143,7 +143,7 @@ struct ads1018 {
 	.type = IIO_TEMP,							\
 	.scan_index = _index,							\
 	.scan_type = {								\
-		.sign = 's',							\
+		.format = 's',							\
 		.realbits = _realbits,						\
 		.storagebits = 16,						\
 		.shift = 16 - _realbits,					\
diff --git a/drivers/iio/adc/ti-ads1100.c b/drivers/iio/adc/ti-ads1100.c
index aa8946063c7d..386d554c7ba1 100644
--- a/drivers/iio/adc/ti-ads1100.c
+++ b/drivers/iio/adc/ti-ads1100.c
@@ -60,7 +60,7 @@ static const struct iio_chan_spec ads1100_channel = {
 	.info_mask_shared_by_all_available =
 	    BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_SAMP_FREQ),
 	.scan_type = {
-		      .sign = 's',
+		      .format = 's',
 		      .realbits = 16,
 		      .storagebits = 16,
 		      .endianness = IIO_CPU,
diff --git a/drivers/iio/adc/ti-ads1119.c b/drivers/iio/adc/ti-ads1119.c
index c9cedc59cdcd..11a8366597c9 100644
--- a/drivers/iio/adc/ti-ads1119.c
+++ b/drivers/iio/adc/ti-ads1119.c
@@ -586,7 +586,7 @@ static int ads1119_alloc_and_config_channels(struct iio_dev *indio_dev)
 		BIT(IIO_CHAN_INFO_SCALE) |
 		BIT(IIO_CHAN_INFO_SAMP_FREQ),
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
diff --git a/drivers/iio/adc/ti-ads124s08.c b/drivers/iio/adc/ti-ads124s08.c
index 8ea1269f74db..656e5746c1e3 100644
--- a/drivers/iio/adc/ti-ads124s08.c
+++ b/drivers/iio/adc/ti-ads124s08.c
@@ -117,7 +117,7 @@ struct ads124s_private {
 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
 	.scan_index = index,					\
 	.scan_type = {						\
-		.sign = 'u',					\
+		.format = 'u',					\
 		.realbits = 32,					\
 		.storagebits = 32,				\
 	},							\
diff --git a/drivers/iio/adc/ti-ads1298.c b/drivers/iio/adc/ti-ads1298.c
index ae30b47e4514..3f4d763d02f7 100644
--- a/drivers/iio/adc/ti-ads1298.c
+++ b/drivers/iio/adc/ti-ads1298.c
@@ -149,7 +149,7 @@ struct ads1298_private {
 		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),	\
 	.scan_index = index,				\
 	.scan_type = {					\
-		.sign = 's',				\
+		.format = 's',				\
 		.realbits = ADS1298_BITS_PER_SAMPLE,	\
 		.storagebits = 32,			\
 		.endianness = IIO_CPU,			\
diff --git a/drivers/iio/adc/ti-ads131e08.c b/drivers/iio/adc/ti-ads131e08.c
index a585621b0bc3..8e76c224bb13 100644
--- a/drivers/iio/adc/ti-ads131e08.c
+++ b/drivers/iio/adc/ti-ads131e08.c
@@ -768,7 +768,7 @@ static int ads131e08_alloc_channels(struct iio_dev *indio_dev)
 						BIT(IIO_CHAN_INFO_SCALE);
 		channels[i].info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ);
 		channels[i].scan_index = channel;
-		channels[i].scan_type.sign = 's';
+		channels[i].scan_type.format = 's';
 		channels[i].scan_type.realbits = 24;
 		channels[i].scan_type.storagebits = 32;
 		channels[i].scan_type.shift = 8;
diff --git a/drivers/iio/adc/ti-ads7950.c b/drivers/iio/adc/ti-ads7950.c
index bbe1ce577789..a16c5de2afcb 100644
--- a/drivers/iio/adc/ti-ads7950.c
+++ b/drivers/iio/adc/ti-ads7950.c
@@ -144,7 +144,7 @@ enum ti_ads7950_id {
 	.datasheet_name = "CH##index",				\
 	.scan_index = index,					\
 	.scan_type = {						\
-		.sign = 'u',					\
+		.format = 'u',					\
 		.realbits = bits,				\
 		.storagebits = 16,				\
 		.shift = 12 - (bits),				\
diff --git a/drivers/iio/adc/ti-ads8688.c b/drivers/iio/adc/ti-ads8688.c
index b0bf46cae0b6..df57fc4021d2 100644
--- a/drivers/iio/adc/ti-ads8688.c
+++ b/drivers/iio/adc/ti-ads8688.c
@@ -157,7 +157,7 @@ static const struct attribute_group ads8688_attribute_group = {
 			      | BIT(IIO_CHAN_INFO_OFFSET),	\
 	.scan_index = index,					\
 	.scan_type = {						\
-		.sign = 'u',					\
+		.format = 'u',					\
 		.realbits = 16,					\
 		.storagebits = 16,				\
 		.endianness = IIO_BE,				\
diff --git a/drivers/iio/adc/ti-lmp92064.c b/drivers/iio/adc/ti-lmp92064.c
index 7e57006a8a12..1f043180383f 100644
--- a/drivers/iio/adc/ti-lmp92064.c
+++ b/drivers/iio/adc/ti-lmp92064.c
@@ -96,7 +96,7 @@ static const struct iio_chan_spec lmp92064_adc_channels[] = {
 			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = TI_LMP92064_CHAN_INC,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 12,
 			.storagebits = 16,
 		},
@@ -109,7 +109,7 @@ static const struct iio_chan_spec lmp92064_adc_channels[] = {
 			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = TI_LMP92064_CHAN_INV,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 12,
 			.storagebits = 16,
 		},
diff --git a/drivers/iio/adc/ti-tlc4541.c b/drivers/iio/adc/ti-tlc4541.c
index f67945c62c99..514815f048af 100644
--- a/drivers/iio/adc/ti-tlc4541.c
+++ b/drivers/iio/adc/ti-tlc4541.c
@@ -60,7 +60,7 @@ enum tlc4541_id {
 		.info_mask_separate       = BIT(IIO_CHAN_INFO_RAW),   \
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
 		.scan_type = {                                        \
-			.sign = 'u',                                  \
+			.format = 'u',                                \
 			.realbits = (bits),                           \
 			.storagebits = 16,                            \
 			.shift = (bitshift),                          \
diff --git a/drivers/iio/adc/ti-tsc2046.c b/drivers/iio/adc/ti-tsc2046.c
index aba4b10a17ac..cd891338fe4b 100644
--- a/drivers/iio/adc/ti-tsc2046.c
+++ b/drivers/iio/adc/ti-tsc2046.c
@@ -192,7 +192,7 @@ struct tsc2046_adc_priv {
 	.datasheet_name = "#name",				\
 	.scan_index = index,					\
 	.scan_type = {						\
-		.sign = 'u',					\
+		.format = 'u',					\
 		.realbits = bits,				\
 		.storagebits = 16,				\
 		.endianness = IIO_CPU,				\
diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
index a1a28584de93..8ec440503a6c 100644
--- a/drivers/iio/adc/ti_am335x_adc.c
+++ b/drivers/iio/adc/ti_am335x_adc.c
@@ -417,7 +417,7 @@ static int tiadc_channel_init(struct device *dev, struct iio_dev *indio_dev,
 		chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE);
 		chan->datasheet_name = chan_name_ain[chan->channel];
 		chan->scan_index = i;
-		chan->scan_type.sign = 'u';
+		chan->scan_type.format = 'u';
 		chan->scan_type.realbits = 12;
 		chan->scan_type.storagebits = 16;
 	}
diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c
index d7182ed0d2a7..be6f0b4d9ced 100644
--- a/drivers/iio/adc/vf610_adc.c
+++ b/drivers/iio/adc/vf610_adc.c
@@ -515,7 +515,7 @@ static const struct iio_chan_spec_ext_info vf610_ext_info[] = {
 	.ext_info = vf610_ext_info,				\
 	.scan_index = (_idx),			\
 	.scan_type = {					\
-		.sign = 'u',				\
+		.format = 'u',				\
 		.realbits = 12,				\
 		.storagebits = 16,			\
 	},						\
@@ -527,7 +527,7 @@ static const struct iio_chan_spec_ext_info vf610_ext_info[] = {
 	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),	\
 	.scan_index = (_idx),					\
 	.scan_type = {						\
-		.sign = 'u',					\
+		.format = 'u',					\
 		.realbits = 12,					\
 		.storagebits = 16,				\
 	},							\
diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c
index 124470c92529..83c5872b04a4 100644
--- a/drivers/iio/adc/xilinx-ams.c
+++ b/drivers/iio/adc/xilinx-ams.c
@@ -1208,7 +1208,7 @@ static int ams_get_ext_chan(struct fwnode_handle *chan_node,
 		memcpy(chan, &ams_pl_channels[ext_chan], sizeof(*channels));
 
 		if (fwnode_property_read_bool(child, "xlnx,bipolar"))
-			chan->scan_type.sign = 's';
+			chan->scan_type.format = 's';
 
 		num_channels++;
 	}
diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c
index e257c1b94a5f..40c854076e84 100644
--- a/drivers/iio/adc/xilinx-xadc-core.c
+++ b/drivers/iio/adc/xilinx-xadc-core.c
@@ -928,7 +928,7 @@ static int xadc_read_raw(struct iio_dev *indio_dev,
 			return ret;
 
 		val16 >>= chan->scan_type.shift;
-		if (chan->scan_type.sign == 'u')
+		if (chan->scan_type.format == 'u')
 			*val = val16;
 		else
 			*val = sign_extend32(val16, bits - 1);
@@ -1066,7 +1066,7 @@ static const struct iio_event_spec xadc_voltage_events[] = {
 	.num_event_specs = ARRAY_SIZE(xadc_temp_events), \
 	.scan_index = (_scan_index), \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.realbits = (_bits), \
 		.storagebits = 16, \
 		.shift = 16 - (_bits), \
@@ -1086,7 +1086,7 @@ static const struct iio_event_spec xadc_voltage_events[] = {
 	.num_event_specs = (_alarm) ? ARRAY_SIZE(xadc_voltage_events) : 0, \
 	.scan_index = (_scan_index), \
 	.scan_type = { \
-		.sign = ((_addr) == XADC_REG_VREFN) ? 's' : 'u', \
+		.format = ((_addr) == XADC_REG_VREFN) ? 's' : 'u', \
 		.realbits = (_bits), \
 		.storagebits = 16, \
 		.shift = 16 - (_bits), \
@@ -1265,7 +1265,7 @@ static int xadc_parse_dt(struct iio_dev *indio_dev, unsigned int *conf, int irq)
 			continue;
 
 		if (fwnode_property_read_bool(child, "xlnx,bipolar"))
-			chan->scan_type.sign = 's';
+			chan->scan_type.format = 's';
 
 		if (reg == 0) {
 			chan->scan_index = 11;
@@ -1420,7 +1420,7 @@ static int xadc_probe(struct platform_device *pdev)
 
 	bipolar_mask = 0;
 	for (i = 0; i < indio_dev->num_channels; i++) {
-		if (indio_dev->channels[i].scan_type.sign == 's')
+		if (indio_dev->channels[i].scan_type.format == 's')
 			bipolar_mask |= BIT(indio_dev->channels[i].scan_index);
 	}
 
diff --git a/drivers/iio/addac/ad74115.c b/drivers/iio/addac/ad74115.c
index f8b04d86b01f..df3c9ac4c708 100644
--- a/drivers/iio/addac/ad74115.c
+++ b/drivers/iio/addac/ad74115.c
@@ -1280,7 +1280,7 @@ static const struct iio_info ad74115_info = {
 					BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
 		.scan_index = index,					\
 		.scan_type = {						\
-			.sign = 'u',					\
+			.format = 'u',					\
 			.realbits = 16,					\
 			.storagebits = 32,				\
 			.shift = 8,					\
diff --git a/drivers/iio/addac/ad74413r.c b/drivers/iio/addac/ad74413r.c
index a20b4d48c5f7..5b9c1521b1c4 100644
--- a/drivers/iio/addac/ad74413r.c
+++ b/drivers/iio/addac/ad74413r.c
@@ -1120,7 +1120,7 @@ static const struct iio_info ad74413r_info = {
 		.info_mask_separate_available =				\
 					BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
 		.scan_type = {						\
-			.sign = 'u',					\
+			.format = 'u',					\
 			.realbits = 16,					\
 			.storagebits = 32,				\
 			.shift = 8,					\
diff --git a/drivers/iio/chemical/atlas-ezo-sensor.c b/drivers/iio/chemical/atlas-ezo-sensor.c
index 59f3a4fa9e9f..33c6f24c612f 100644
--- a/drivers/iio/chemical/atlas-ezo-sensor.c
+++ b/drivers/iio/chemical/atlas-ezo-sensor.c
@@ -52,7 +52,7 @@ struct atlas_ezo_data {
 			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), \
 		.scan_index = 0, \
 		.scan_type =  { \
-			.sign = 'u', \
+			.format = 'u', \
 			.realbits = 32, \
 			.storagebits = 32, \
 			.endianness = IIO_CPU, \
@@ -74,7 +74,7 @@ static const struct iio_chan_spec atlas_hum_ezo_channels[] = {
 			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = 0,
 		.scan_type =  {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 32,
 			.storagebits = 32,
 			.endianness = IIO_CPU,
diff --git a/drivers/iio/chemical/atlas-sensor.c b/drivers/iio/chemical/atlas-sensor.c
index 8bbba85af699..92876b5cbd89 100644
--- a/drivers/iio/chemical/atlas-sensor.c
+++ b/drivers/iio/chemical/atlas-sensor.c
@@ -118,7 +118,7 @@ static const struct iio_chan_spec atlas_ph_channels[] = {
 			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 32,
 			.storagebits = 32,
 			.endianness = IIO_BE,
@@ -145,7 +145,7 @@ static const struct iio_chan_spec atlas_ph_channels[] = {
 			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), \
 		.scan_index = _idx + 1, \
 		.scan_type = { \
-			.sign = 'u', \
+			.format = 'u', \
 			.realbits = 32, \
 			.storagebits = 32, \
 			.endianness = IIO_BE, \
@@ -160,7 +160,7 @@ static const struct iio_chan_spec atlas_ec_channels[] = {
 			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 32,
 			.storagebits = 32,
 			.endianness = IIO_BE,
@@ -187,7 +187,7 @@ static const struct iio_chan_spec atlas_orp_channels[] = {
 			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 32,
 			.storagebits = 32,
 			.endianness = IIO_BE,
@@ -204,7 +204,7 @@ static const struct iio_chan_spec atlas_do_channels[] = {
 			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 32,
 			.storagebits = 32,
 			.endianness = IIO_BE,
@@ -228,7 +228,7 @@ static const struct iio_chan_spec atlas_rtd_channels[] = {
 		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 32,
 			.storagebits = 32,
 			.endianness = IIO_BE,
diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c
index 70f81c4a96ba..35910ed963a9 100644
--- a/drivers/iio/chemical/bme680_core.c
+++ b/drivers/iio/chemical/bme680_core.c
@@ -172,7 +172,7 @@ static const struct iio_chan_spec bme680_channels[] = {
 				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
@@ -187,7 +187,7 @@ static const struct iio_chan_spec bme680_channels[] = {
 				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 32,
 			.storagebits = 32,
 			.endianness = IIO_CPU,
@@ -202,7 +202,7 @@ static const struct iio_chan_spec bme680_channels[] = {
 				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
 		.scan_index = 2,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 32,
 			.storagebits = 32,
 			.endianness = IIO_CPU,
@@ -213,7 +213,7 @@ static const struct iio_chan_spec bme680_channels[] = {
 		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
 		.scan_index = 3,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 32,
 			.storagebits = 32,
 			.endianness = IIO_CPU,
diff --git a/drivers/iio/chemical/ccs811.c b/drivers/iio/chemical/ccs811.c
index 998c9239c4c7..52f883efeae0 100644
--- a/drivers/iio/chemical/ccs811.c
+++ b/drivers/iio/chemical/ccs811.c
@@ -105,7 +105,7 @@ static const struct iio_chan_spec ccs811_channels[] = {
 				      BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_BE,
@@ -118,7 +118,7 @@ static const struct iio_chan_spec ccs811_channels[] = {
 				       BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_BE,
diff --git a/drivers/iio/chemical/ens160_core.c b/drivers/iio/chemical/ens160_core.c
index bbc96c4c6283..cf12e7230a01 100644
--- a/drivers/iio/chemical/ens160_core.c
+++ b/drivers/iio/chemical/ens160_core.c
@@ -76,7 +76,7 @@ static const struct iio_chan_spec ens160_channels[] = {
 		.address = ENS160_REG_DATA_TVOC,
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_LE,
@@ -91,7 +91,7 @@ static const struct iio_chan_spec ens160_channels[] = {
 		.address = ENS160_REG_DATA_ECO2,
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_LE,
diff --git a/drivers/iio/chemical/pms7003.c b/drivers/iio/chemical/pms7003.c
index 656d4a12c58f..d74c560cd7ce 100644
--- a/drivers/iio/chemical/pms7003.c
+++ b/drivers/iio/chemical/pms7003.c
@@ -178,7 +178,7 @@ static const struct iio_info pms7003_info = {
 	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \
 	.scan_index = _index, \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.realbits = 10, \
 		.storagebits = 16, \
 		.endianness = IIO_CPU, \
diff --git a/drivers/iio/chemical/scd30_core.c b/drivers/iio/chemical/scd30_core.c
index a665fcb78806..2ebe914758d0 100644
--- a/drivers/iio/chemical/scd30_core.c
+++ b/drivers/iio/chemical/scd30_core.c
@@ -455,7 +455,7 @@ static const struct iio_info scd30_info = {
 };
 
 #define SCD30_CHAN_SCAN_TYPE(_sign, _realbits) .scan_type = { \
-	.sign = _sign, \
+	.format = _sign, \
 	.realbits = _realbits, \
 	.storagebits = 32, \
 	.endianness = IIO_CPU, \
diff --git a/drivers/iio/chemical/scd4x.c b/drivers/iio/chemical/scd4x.c
index 23a326fb62a7..f7f999fd593a 100644
--- a/drivers/iio/chemical/scd4x.c
+++ b/drivers/iio/chemical/scd4x.c
@@ -583,7 +583,7 @@ static const struct iio_chan_spec scd4x_channels[] = {
 		.address = SCD4X_CO2,
 		.scan_index = SCD4X_CO2,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
@@ -598,7 +598,7 @@ static const struct iio_chan_spec scd4x_channels[] = {
 		.address = SCD4X_TEMP,
 		.scan_index = SCD4X_TEMP,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
@@ -611,7 +611,7 @@ static const struct iio_chan_spec scd4x_channels[] = {
 		.address = SCD4X_HR,
 		.scan_index = SCD4X_HR,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
diff --git a/drivers/iio/chemical/sps30.c b/drivers/iio/chemical/sps30.c
index a934bf0298dd..a372ce9b58dd 100644
--- a/drivers/iio/chemical/sps30.c
+++ b/drivers/iio/chemical/sps30.c
@@ -299,7 +299,7 @@ static const struct iio_info sps30_info = {
 	.address = _mod, \
 	.scan_index = _index, \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.realbits = 19, \
 		.storagebits = 32, \
 		.endianness = IIO_CPU, \
diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_activity.c b/drivers/iio/common/cros_ec_sensors/cros_ec_activity.c
index 6e38d115b6fe..d44c026833a8 100644
--- a/drivers/iio/common/cros_ec_sensors/cros_ec_activity.c
+++ b/drivers/iio/common/cros_ec_sensors/cros_ec_activity.c
@@ -283,7 +283,7 @@ static int cros_ec_sensors_probe(struct platform_device *pdev)
 	channel->scan_index = index;
 	channel->type = IIO_TIMESTAMP;
 	channel->channel = -1;
-	channel->scan_type.sign = 's';
+	channel->scan_type.format = 's';
 	channel->scan_type.realbits = 64;
 	channel->scan_type.storagebits = 64;
 
diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c b/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c
index 2d3d148b4206..8aa46b9bdb48 100644
--- a/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c
+++ b/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c
@@ -36,7 +36,7 @@ static const struct iio_chan_spec cros_ec_lid_angle_channels[] = {
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 		.scan_type.realbits = CROS_EC_SENSOR_BITS,
 		.scan_type.storagebits = CROS_EC_SENSOR_BITS,
-		.scan_type.sign = 'u',
+		.scan_type.format = 'u',
 		.type = IIO_ANGL
 	},
 	IIO_CHAN_SOFT_TIMESTAMP(1)
diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
index 82cef4a12442..8eb0d1a411d6 100644
--- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
+++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
@@ -260,7 +260,7 @@ static int cros_ec_sensors_probe(struct platform_device *pdev)
 		channel->ext_info = cros_ec_sensors_ext_info;
 		channel->modified = 1;
 		channel->channel2 = IIO_MOD_X + i;
-		channel->scan_type.sign = 's';
+		channel->scan_type.format = 's';
 
 		/* Sensor specific */
 		switch (state->core.type) {
@@ -283,7 +283,7 @@ static int cros_ec_sensors_probe(struct platform_device *pdev)
 	channel->type = IIO_TIMESTAMP;
 	channel->channel = -1;
 	channel->scan_index = CROS_EC_SENSOR_MAX_AXIS;
-	channel->scan_type.sign = 's';
+	channel->scan_type.format = 's';
 	channel->scan_type.realbits = 64;
 	channel->scan_type.storagebits = 64;
 
diff --git a/drivers/iio/common/scmi_sensors/scmi_iio.c b/drivers/iio/common/scmi_sensors/scmi_iio.c
index 5136ad9ada04..cec652be5fcb 100644
--- a/drivers/iio/common/scmi_sensors/scmi_iio.c
+++ b/drivers/iio/common/scmi_sensors/scmi_iio.c
@@ -425,7 +425,7 @@ static void scmi_iio_set_timestamp_channel(struct iio_chan_spec *iio_chan,
 	iio_chan->type = IIO_TIMESTAMP;
 	iio_chan->channel = -1;
 	iio_chan->scan_index = scan_index;
-	iio_chan->scan_type.sign = 'u';
+	iio_chan->scan_type.format = 'u';
 	iio_chan->scan_type.realbits = 64;
 	iio_chan->scan_type.storagebits = 64;
 }
@@ -443,7 +443,7 @@ static void scmi_iio_set_data_channel(struct iio_chan_spec *iio_chan,
 	iio_chan->info_mask_shared_by_type_available =
 		BIT(IIO_CHAN_INFO_SAMP_FREQ);
 	iio_chan->scan_index = scan_index;
-	iio_chan->scan_type.sign = 's';
+	iio_chan->scan_type.format = 's';
 	iio_chan->scan_type.realbits = 64;
 	iio_chan->scan_type.storagebits = 64;
 	iio_chan->scan_type.endianness = IIO_LE;
diff --git a/drivers/iio/common/ssp_sensors/ssp_iio_sensor.h b/drivers/iio/common/ssp_sensors/ssp_iio_sensor.h
index 4528ab55eb68..b5b188fbeafd 100644
--- a/drivers/iio/common/ssp_sensors/ssp_iio_sensor.h
+++ b/drivers/iio/common/ssp_sensors/ssp_iio_sensor.h
@@ -10,7 +10,7 @@
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ),\
 		.scan_index = _index,\
 		.scan_type = {\
-			.sign = 's',\
+			.format = 's',\
 			.realbits = 16,\
 			.storagebits = 16,\
 			.shift = 0,\
@@ -24,7 +24,7 @@
 	.channel = -1,							\
 	.scan_index = _si,						\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 64,						\
 		.storagebits = 64,					\
 		},							\
diff --git a/drivers/iio/dac/ad3552r-hs.c b/drivers/iio/dac/ad3552r-hs.c
index a9578afa7015..00094cbfddda 100644
--- a/drivers/iio/dac/ad3552r-hs.c
+++ b/drivers/iio/dac/ad3552r-hs.c
@@ -766,7 +766,7 @@ static const struct iio_buffer_setup_ops ad3552r_hs_buffer_setup_ops = {
 	.channel = (ch), \
 	.scan_index = (ch), \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.realbits = 16, \
 		.storagebits = 16, \
 		.endianness = IIO_BE, \
diff --git a/drivers/iio/dac/ad3552r.c b/drivers/iio/dac/ad3552r.c
index 93c33bc3e1be..ec93298c574c 100644
--- a/drivers/iio/dac/ad3552r.c
+++ b/drivers/iio/dac/ad3552r.c
@@ -128,7 +128,7 @@ static int ad3552r_update_reg_field(struct ad3552r_desc *dac, u8 addr, u16 mask,
 	.channel = _idx,					\
 	.scan_index = _idx,					\
 	.scan_type = {						\
-		.sign = 'u',					\
+		.format = 'u',					\
 		.realbits = 16,					\
 		.storagebits = 16,				\
 		.endianness = IIO_BE,				\
diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c
index 84be5174babd..1e83e0b9bc0e 100644
--- a/drivers/iio/dac/ad5064.c
+++ b/drivers/iio/dac/ad5064.c
@@ -402,7 +402,7 @@ static const struct iio_chan_spec_ext_info ltc2617_ext_info[] = {
 	BIT(IIO_CHAN_INFO_SCALE),					\
 	.address = addr,					\
 	.scan_type = {						\
-		.sign = 'u',					\
+		.format = 'u',					\
 		.realbits = (bits),				\
 		.storagebits = 16,				\
 		.shift = (_shift),				\
diff --git a/drivers/iio/dac/ad5360.c b/drivers/iio/dac/ad5360.c
index bd32fa57b1d7..47277097abbe 100644
--- a/drivers/iio/dac/ad5360.c
+++ b/drivers/iio/dac/ad5360.c
@@ -109,7 +109,7 @@ enum ad5360_type {
 		BIT(IIO_CHAN_INFO_CALIBSCALE) |			\
 		BIT(IIO_CHAN_INFO_CALIBBIAS),			\
 	.scan_type = {						\
-		.sign = 'u',					\
+		.format = 'u',					\
 		.realbits = (bits),				\
 		.storagebits = 16,				\
 		.shift = 16 - (bits),				\
diff --git a/drivers/iio/dac/ad5380.c b/drivers/iio/dac/ad5380.c
index 8b813cee7625..52ce975b8c8a 100644
--- a/drivers/iio/dac/ad5380.c
+++ b/drivers/iio/dac/ad5380.c
@@ -258,7 +258,7 @@ static const struct iio_chan_spec_ext_info ad5380_ext_info[] = {
 		BIT(IIO_CHAN_INFO_CALIBBIAS),			\
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
 	.scan_type = {						\
-		.sign = 'u',					\
+		.format = 'u',					\
 		.realbits = (_bits),				\
 		.storagebits =  16,				\
 		.shift = 14 - (_bits),				\
diff --git a/drivers/iio/dac/ad5421.c b/drivers/iio/dac/ad5421.c
index d9d7031c4432..9ced9a0561ed 100644
--- a/drivers/iio/dac/ad5421.c
+++ b/drivers/iio/dac/ad5421.c
@@ -116,7 +116,7 @@ static const struct iio_chan_spec ad5421_channels[] = {
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |
 			BIT(IIO_CHAN_INFO_OFFSET),
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 		},
diff --git a/drivers/iio/dac/ad5446.h b/drivers/iio/dac/ad5446.h
index 6ba31d98f415..9dbd03700dcd 100644
--- a/drivers/iio/dac/ad5446.h
+++ b/drivers/iio/dac/ad5446.h
@@ -20,7 +20,7 @@ extern const struct iio_chan_spec_ext_info ad5446_ext_info_powerdown[];
 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.realbits = (bits), \
 		.storagebits = (storage), \
 		.shift = (_shift), \
diff --git a/drivers/iio/dac/ad5449.c b/drivers/iio/dac/ad5449.c
index d8c325260259..2487fda06937 100644
--- a/drivers/iio/dac/ad5449.c
+++ b/drivers/iio/dac/ad5449.c
@@ -203,7 +203,7 @@ static const struct iio_info ad5449_info = {
 		BIT(IIO_CHAN_INFO_SCALE),			\
 	.address = (chan),					\
 	.scan_type = {						\
-		.sign = 'u',					\
+		.format = 'u',					\
 		.realbits = (bits),				\
 		.storagebits = 16,				\
 		.shift = 12 - (bits),				\
diff --git a/drivers/iio/dac/ad5504.c b/drivers/iio/dac/ad5504.c
index 355bcb6a8ba0..c1e52379b970 100644
--- a/drivers/iio/dac/ad5504.c
+++ b/drivers/iio/dac/ad5504.c
@@ -254,7 +254,7 @@ static const struct iio_chan_spec_ext_info ad5504_ext_info[] = {
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
 	.address = AD5504_ADDR_DAC(_chan), \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.realbits = 12, \
 		.storagebits = 16, \
 	}, \
diff --git a/drivers/iio/dac/ad5592r-base.c b/drivers/iio/dac/ad5592r-base.c
index 4720733d66b2..da48cd20c68e 100644
--- a/drivers/iio/dac/ad5592r-base.c
+++ b/drivers/iio/dac/ad5592r-base.c
@@ -480,7 +480,7 @@ static void ad5592r_setup_channel(struct iio_dev *iio_dev,
 	chan->channel = id;
 	chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
 	chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE);
-	chan->scan_type.sign = 'u';
+	chan->scan_type.format = 'u';
 	chan->scan_type.realbits = 12;
 	chan->scan_type.storagebits = 16;
 	chan->ext_info = ad5592r_ext_info;
diff --git a/drivers/iio/dac/ad5624r_spi.c b/drivers/iio/dac/ad5624r_spi.c
index 13aefe769bad..23cba2bc6aa8 100644
--- a/drivers/iio/dac/ad5624r_spi.c
+++ b/drivers/iio/dac/ad5624r_spi.c
@@ -172,7 +172,7 @@ static const struct iio_chan_spec_ext_info ad5624r_ext_info[] = {
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
 	.address = (_chan), \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.realbits = (_bits), \
 		.storagebits = 16, \
 		.shift = 16 - (_bits), \
diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c
index 4b18498aa074..f0db41452bca 100644
--- a/drivers/iio/dac/ad5686.c
+++ b/drivers/iio/dac/ad5686.c
@@ -197,7 +197,7 @@ static const struct iio_chan_spec_ext_info ad5686_ext_info[] = {
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),\
 		.address = addr,				\
 		.scan_type = {					\
-			.sign = 'u',				\
+			.format = 'u',				\
 			.realbits = (bits),			\
 			.storagebits = 16,			\
 			.shift = (_shift),			\
diff --git a/drivers/iio/dac/ad5755.c b/drivers/iio/dac/ad5755.c
index d0e5f35462b1..fa3d3727068f 100644
--- a/drivers/iio/dac/ad5755.c
+++ b/drivers/iio/dac/ad5755.c
@@ -534,7 +534,7 @@ static const struct iio_chan_spec_ext_info ad5755_ext_info[] = {
 		BIT(IIO_CHAN_INFO_CALIBSCALE) |			\
 		BIT(IIO_CHAN_INFO_CALIBBIAS),			\
 	.scan_type = {						\
-		.sign = 'u',					\
+		.format = 'u',					\
 		.realbits = (_bits),				\
 		.storagebits = 16,				\
 		.shift = 16 - (_bits),				\
diff --git a/drivers/iio/dac/ad5761.c b/drivers/iio/dac/ad5761.c
index b5d20f04f070..6253390af191 100644
--- a/drivers/iio/dac/ad5761.c
+++ b/drivers/iio/dac/ad5761.c
@@ -257,7 +257,7 @@ static const struct iio_info ad5761_info = {
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
 		BIT(IIO_CHAN_INFO_OFFSET),		\
 	.scan_type = {					\
-		.sign = 'u',				\
+		.format = 'u',				\
 		.realbits = (_bits),			\
 		.storagebits = 16,			\
 		.shift = 16 - (_bits),			\
diff --git a/drivers/iio/dac/ad5764.c b/drivers/iio/dac/ad5764.c
index fbbd7105a80c..01db3fe903cd 100644
--- a/drivers/iio/dac/ad5764.c
+++ b/drivers/iio/dac/ad5764.c
@@ -84,7 +84,7 @@ enum ad5764_type {
 		BIT(IIO_CHAN_INFO_CALIBBIAS),			\
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET),	\
 	.scan_type = {						\
-		.sign = 'u',					\
+		.format = 'u',					\
 		.realbits = (_bits),				\
 		.storagebits = 16,				\
 		.shift = 16 - (_bits),				\
diff --git a/drivers/iio/dac/ad5766.c b/drivers/iio/dac/ad5766.c
index f6a0a0d84fef..af27a1ad3f5e 100644
--- a/drivers/iio/dac/ad5766.c
+++ b/drivers/iio/dac/ad5766.c
@@ -449,7 +449,7 @@ static const struct iio_chan_spec_ext_info ad5766_ext_info[] = {
 		BIT(IIO_CHAN_INFO_SCALE),				\
 	.scan_index = (_chan),						\
 	.scan_type = {							\
-		.sign = 'u',						\
+		.format = 'u',						\
 		.realbits = (_bits),					\
 		.storagebits = 16,					\
 		.shift = 16 - (_bits),					\
diff --git a/drivers/iio/dac/ad5791.c b/drivers/iio/dac/ad5791.c
index ae7297f08398..3c3740286cba 100644
--- a/drivers/iio/dac/ad5791.c
+++ b/drivers/iio/dac/ad5791.c
@@ -323,7 +323,7 @@ static const struct ad5791_chip_info _name##_chip_info = {		\
 			.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
 				BIT(IIO_CHAN_INFO_OFFSET),		\
 			.scan_type = {					\
-				.sign = 'u',				\
+				.format = 'u',				\
 				.realbits = (bits),			\
 				.storagebits = 32,			\
 				.shift = (_shift),			\
@@ -341,7 +341,7 @@ static const struct ad5791_chip_info _name##_chip_info = {		\
 				BIT(IIO_CHAN_INFO_OFFSET),		\
 			.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),\
 			.scan_type = {					\
-				.sign = 'u',				\
+				.format = 'u',				\
 				.realbits = (bits),			\
 				.storagebits = 32,			\
 				.shift = (_shift),			\
diff --git a/drivers/iio/dac/ad7303.c b/drivers/iio/dac/ad7303.c
index a88cc639047d..7f3e63e1f928 100644
--- a/drivers/iio/dac/ad7303.c
+++ b/drivers/iio/dac/ad7303.c
@@ -185,7 +185,7 @@ static const struct iio_chan_spec_ext_info ad7303_ext_info[] = {
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
 	.address = (chan),					\
 	.scan_type = {						\
-		.sign = 'u',					\
+		.format = 'u',					\
 		.realbits = 8,					\
 		.storagebits = 8,				\
 		.shift = 0,					\
diff --git a/drivers/iio/dac/ad8460.c b/drivers/iio/dac/ad8460.c
index 6e45686902dd..566977b95b41 100644
--- a/drivers/iio/dac/ad8460.c
+++ b/drivers/iio/dac/ad8460.c
@@ -742,7 +742,7 @@ static const struct iio_event_spec ad8460_events[] = {
 	.channel = 0,						\
 	.scan_index = 0,					\
 	.scan_type = {						\
-		.sign = 'u',					\
+		.format = 'u',					\
 		.realbits = 14,					\
 		.storagebits = 16,				\
 		.endianness = IIO_CPU,				\
diff --git a/drivers/iio/dac/ad9739a.c b/drivers/iio/dac/ad9739a.c
index d77b46d83bd4..96952f2d33fd 100644
--- a/drivers/iio/dac/ad9739a.c
+++ b/drivers/iio/dac/ad9739a.c
@@ -335,7 +335,7 @@ static struct iio_chan_spec ad9739a_channels[] = {
 		.output = 1,
 		.ext_info = ad9739a_ext_info,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.storagebits = 16,
 			.realbits = 16,
 		},
diff --git a/drivers/iio/dac/ltc1660.c b/drivers/iio/dac/ltc1660.c
index 6e80b49f4665..20c4cbe92ac2 100644
--- a/drivers/iio/dac/ltc1660.c
+++ b/drivers/iio/dac/ltc1660.c
@@ -109,7 +109,7 @@ static int ltc1660_write_raw(struct iio_dev *indio_dev,
 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),	\
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
 	.scan_type = {					\
-		.sign = 'u',				\
+		.format = 'u',				\
 		.realbits = (bits),			\
 		.storagebits = 16,			\
 		.shift = 12 - (bits),			\
diff --git a/drivers/iio/dac/max5522.c b/drivers/iio/dac/max5522.c
index 1b8fe6b8d26e..cb180ec476af 100644
--- a/drivers/iio/dac/max5522.c
+++ b/drivers/iio/dac/max5522.c
@@ -45,7 +45,7 @@ struct max5522_state {
 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
 			      BIT(IIO_CHAN_INFO_SCALE), \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.realbits = 10, \
 		.storagebits = 16, \
 		.shift = 2, \
diff --git a/drivers/iio/dac/mcp4922.c b/drivers/iio/dac/mcp4922.c
index 74f338afcab9..30a4eb19b515 100644
--- a/drivers/iio/dac/mcp4922.c
+++ b/drivers/iio/dac/mcp4922.c
@@ -41,7 +41,7 @@ struct mcp4922_state {
 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),	\
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
 	.scan_type = {					\
-		.sign = 'u',				\
+		.format = 'u',				\
 		.realbits = (bits),			\
 		.storagebits = 16,			\
 		.shift = 12 - (bits),			\
diff --git a/drivers/iio/dac/stm32-dac.c b/drivers/iio/dac/stm32-dac.c
index b860e18d52a1..c2d592358f51 100644
--- a/drivers/iio/dac/stm32-dac.c
+++ b/drivers/iio/dac/stm32-dac.c
@@ -255,7 +255,7 @@ static const struct iio_chan_spec_ext_info stm32_dac_ext_info[] = {
 		BIT(IIO_CHAN_INFO_SCALE),		\
 	/* scan_index is always 0 as num_channels is 1 */ \
 	.scan_type = {					\
-		.sign = 'u',				\
+		.format = 'u',				\
 		.realbits = 12,				\
 		.storagebits = 16,			\
 	},						\
diff --git a/drivers/iio/dummy/iio_simple_dummy.c b/drivers/iio/dummy/iio_simple_dummy.c
index 19fcdbbc11c6..a950f083a1b6 100644
--- a/drivers/iio/dummy/iio_simple_dummy.c
+++ b/drivers/iio/dummy/iio_simple_dummy.c
@@ -128,7 +128,7 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
 		/* The ordering of elements in the buffer via an enum */
 		.scan_index = DUMMY_INDEX_VOLTAGE_0,
 		.scan_type = { /* Description of storage in buffer */
-			.sign = 'u', /* unsigned */
+			.format = 'u', /* unsigned */
 			.realbits = 13, /* 13 bits */
 			.storagebits = 16, /* 16 bits used for storage */
 			.shift = 0, /* zero shift */
@@ -167,7 +167,7 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
 		 */
 		.scan_index = DUMMY_INDEX_DIFFVOLTAGE_1M2,
 		.scan_type = { /* Description of storage in buffer */
-			.sign = 's', /* signed */
+			.format = 's', /* signed */
 			.realbits = 12, /* 12 bits */
 			.storagebits = 16, /* 16 bits used for storage */
 			.shift = 0, /* zero shift */
@@ -185,7 +185,7 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
 		.info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 		.scan_index = DUMMY_INDEX_DIFFVOLTAGE_3M4,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 11,
 			.storagebits = 16,
 			.shift = 0,
@@ -212,7 +212,7 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
 		.info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 		.scan_index = DUMMY_INDEX_ACCELX,
 		.scan_type = { /* Description of storage in buffer */
-			.sign = 's', /* signed */
+			.format = 's', /* signed */
 			.realbits = 16, /* 16 bits */
 			.storagebits = 16, /* 16 bits used for storage */
 			.shift = 0, /* zero shift */
diff --git a/drivers/iio/gyro/adis16136.c b/drivers/iio/gyro/adis16136.c
index 369c7428e1ef..fd3ad9950e08 100644
--- a/drivers/iio/gyro/adis16136.c
+++ b/drivers/iio/gyro/adis16136.c
@@ -361,7 +361,7 @@ static const struct iio_chan_spec adis16136_channels[] = {
 		.address = ADIS16136_REG_GYRO_OUT2,
 		.scan_index = ADIS16136_SCAN_GYRO,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 32,
 			.storagebits = 32,
 			.endianness = IIO_BE,
@@ -375,7 +375,7 @@ static const struct iio_chan_spec adis16136_channels[] = {
 		.address = ADIS16136_REG_TEMP_OUT,
 		.scan_index = ADIS16136_SCAN_TEMP,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_BE,
diff --git a/drivers/iio/gyro/adxrs290.c b/drivers/iio/gyro/adxrs290.c
index 3efe385ebedc..2efbc4f49d2c 100644
--- a/drivers/iio/gyro/adxrs290.c
+++ b/drivers/iio/gyro/adxrs290.c
@@ -538,7 +538,7 @@ static irqreturn_t adxrs290_trigger_handler(int irq, void *p)
 	BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY),		\
 	.scan_index = ADXRS290_IDX_##axis,				\
 	.scan_type = {                                                  \
-		.sign = 's',                                            \
+		.format = 's',                                          \
 		.realbits = 16,                                         \
 		.storagebits = 16,                                      \
 		.endianness = IIO_LE,					\
@@ -555,7 +555,7 @@ static const struct iio_chan_spec adxrs290_channels[] = {
 		BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = ADXRS290_IDX_TEMP,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 12,
 			.storagebits = 16,
 			.endianness = IIO_LE,
diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c
index 38394b5f3275..7de69d7b7ebd 100644
--- a/drivers/iio/gyro/bmg160_core.c
+++ b/drivers/iio/gyro/bmg160_core.c
@@ -833,7 +833,7 @@ static const struct iio_event_spec bmg160_event = {
 		BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),	\
 	.scan_index = AXIS_##_axis,					\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 16,					\
 		.storagebits = 16,					\
 		.endianness = IIO_LE,					\
diff --git a/drivers/iio/gyro/fxas21002c_core.c b/drivers/iio/gyro/fxas21002c_core.c
index a88670207cec..0773764eed43 100644
--- a/drivers/iio/gyro/fxas21002c_core.c
+++ b/drivers/iio/gyro/fxas21002c_core.c
@@ -696,7 +696,7 @@ static const struct attribute_group fxas21002c_attrs_group = {
 		BIT(IIO_CHAN_INFO_SAMP_FREQ),				\
 	.scan_index = CHANNEL_SCAN_INDEX_##_axis,			\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 16,						\
 		.storagebits = 16,					\
 		.endianness = IIO_BE,					\
diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c
index c43990c518f7..f85122041a67 100644
--- a/drivers/iio/gyro/hid-sensor-gyro-3d.c
+++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c
@@ -86,7 +86,7 @@ static const struct iio_chan_spec gyro_3d_channels[] = {
 static void gyro_3d_adjust_channel_bit_mask(struct iio_chan_spec *channels,
 						int channel, int size)
 {
-	channels[channel].scan_type.sign = 's';
+	channels[channel].scan_type.format = 's';
 	/* Real storage bits will change based on the report desc. */
 	channels[channel].scan_type.realbits = size * 8;
 	/* Maximum size of a sample to capture is u32 */
diff --git a/drivers/iio/gyro/itg3200_core.c b/drivers/iio/gyro/itg3200_core.c
index bfe95ec1abda..1d7df9235d13 100644
--- a/drivers/iio/gyro/itg3200_core.c
+++ b/drivers/iio/gyro/itg3200_core.c
@@ -257,7 +257,7 @@ static const struct iio_chan_spec_ext_info itg3200_ext_info[] = {
 };
 
 #define ITG3200_ST						\
-	{ .sign = 's', .realbits = 16, .storagebits = 16, .endianness = IIO_BE }
+	{ .format = 's', .realbits = 16, .storagebits = 16, .endianness = IIO_BE }
 
 #define ITG3200_GYRO_CHAN(_mod) { \
 	.type = IIO_ANGL_VEL, \
diff --git a/drivers/iio/gyro/mpu3050-core.c b/drivers/iio/gyro/mpu3050-core.c
index ee2fcd20545d..484411bf634a 100644
--- a/drivers/iio/gyro/mpu3050-core.c
+++ b/drivers/iio/gyro/mpu3050-core.c
@@ -697,7 +697,7 @@ static const struct iio_chan_spec_ext_info mpu3050_ext_info[] = {
 		.ext_info = mpu3050_ext_info,				\
 		.scan_index = index,					\
 		.scan_type = {						\
-			.sign = 's',					\
+			.format = 's',					\
 			.realbits = 16,					\
 			.storagebits = 16,				\
 			.endianness = IIO_BE,				\
@@ -713,7 +713,7 @@ static const struct iio_chan_spec mpu3050_channels[] = {
 		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_BE,
diff --git a/drivers/iio/health/afe440x.h b/drivers/iio/health/afe440x.h
index 0adea0047eba..3b1a89f85ed1 100644
--- a/drivers/iio/health/afe440x.h
+++ b/drivers/iio/health/afe440x.h
@@ -87,7 +87,7 @@
 		.address = _index,				\
 		.scan_index = _index,				\
 		.scan_type = {					\
-				.sign = 's',			\
+				.format = 's',			\
 				.realbits = 24,			\
 				.storagebits = 32,		\
 				.endianness = IIO_CPU,		\
diff --git a/drivers/iio/health/max30100.c b/drivers/iio/health/max30100.c
index 7dfdb5eb305e..8b62d7a3546f 100644
--- a/drivers/iio/health/max30100.c
+++ b/drivers/iio/health/max30100.c
@@ -124,7 +124,7 @@ static const struct iio_chan_spec max30100_channels[] = {
 
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_BE,
@@ -137,7 +137,7 @@ static const struct iio_chan_spec max30100_channels[] = {
 
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_BE,
diff --git a/drivers/iio/health/max30102.c b/drivers/iio/health/max30102.c
index 47da44efd68b..acb38b6dd036 100644
--- a/drivers/iio/health/max30102.c
+++ b/drivers/iio/health/max30102.c
@@ -135,7 +135,7 @@ static const unsigned long max30105_scan_masks[] = {
 		.modified = 1, \
 		.scan_index = _si, \
 		.scan_type = { \
-			.sign = 'u', \
+			.format = 'u', \
 			.shift = 8, \
 			.realbits = 18, \
 			.storagebits = 32, \
diff --git a/drivers/iio/humidity/am2315.c b/drivers/iio/humidity/am2315.c
index 02ca23eb8991..c279309464d9 100644
--- a/drivers/iio/humidity/am2315.c
+++ b/drivers/iio/humidity/am2315.c
@@ -51,7 +51,7 @@ static const struct iio_chan_spec am2315_channels[] = {
 				      BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
@@ -63,7 +63,7 @@ static const struct iio_chan_spec am2315_channels[] = {
 				      BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
diff --git a/drivers/iio/humidity/hdc100x.c b/drivers/iio/humidity/hdc100x.c
index c2b36e682e06..8e876cb1c43f 100644
--- a/drivers/iio/humidity/hdc100x.c
+++ b/drivers/iio/humidity/hdc100x.c
@@ -100,7 +100,7 @@ static const struct iio_chan_spec hdc100x_channels[] = {
 			BIT(IIO_CHAN_INFO_OFFSET),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_BE,
@@ -114,7 +114,7 @@ static const struct iio_chan_spec hdc100x_channels[] = {
 			BIT(IIO_CHAN_INFO_INT_TIME),
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_BE,
diff --git a/drivers/iio/humidity/hid-sensor-humidity.c b/drivers/iio/humidity/hid-sensor-humidity.c
index be2338d5f407..4f258cfe3641 100644
--- a/drivers/iio/humidity/hid-sensor-humidity.c
+++ b/drivers/iio/humidity/hid-sensor-humidity.c
@@ -47,7 +47,7 @@ static const struct iio_chan_spec humidity_channels[] = {
 static void humidity_adjust_channel_bit_mask(struct iio_chan_spec *channels,
 					int channel, int size)
 {
-	channels[channel].scan_type.sign = 's';
+	channels[channel].scan_type.format = 's';
 	/* Real storage bits will change based on the report desc. */
 	channels[channel].scan_type.realbits = size * 8;
 	/* Maximum size of a sample to capture is s32 */
diff --git a/drivers/iio/humidity/hts221_core.c b/drivers/iio/humidity/hts221_core.c
index bfeb0a60d3af..ae07945653e9 100644
--- a/drivers/iio/humidity/hts221_core.c
+++ b/drivers/iio/humidity/hts221_core.c
@@ -100,7 +100,7 @@ static const struct iio_chan_spec hts221_channels[] = {
 		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_LE,
@@ -116,7 +116,7 @@ static const struct iio_chan_spec hts221_channels[] = {
 		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_LE,
diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c
index d160147cce0b..80b82637063b 100644
--- a/drivers/iio/imu/adis.c
+++ b/drivers/iio/imu/adis.c
@@ -482,7 +482,7 @@ int adis_single_conversion(struct iio_dev *indio_dev,
 			return ret;
 	}
 
-	if (chan->scan_type.sign == 's')
+	if (chan->scan_type.format == 's')
 		*val = sign_extend32(uval, chan->scan_type.realbits - 1);
 	else
 		*val = uval & ((1 << chan->scan_type.realbits) - 1);
diff --git a/drivers/iio/imu/adis16400.c b/drivers/iio/imu/adis16400.c
index 36323ad149e0..90b029fbce54 100644
--- a/drivers/iio/imu/adis16400.c
+++ b/drivers/iio/imu/adis16400.c
@@ -653,7 +653,7 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
 	.address = (addr), \
 	.scan_index = (si), \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.realbits = (bits), \
 		.storagebits = 16, \
 		.shift = 0, \
@@ -679,7 +679,7 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
 	.address = addr, \
 	.scan_index = ADIS16400_SCAN_GYRO_ ## mod, \
 	.scan_type = { \
-		.sign = 's', \
+		.format = 's', \
 		.realbits = (bits), \
 		.storagebits = 16, \
 		.shift = 0, \
@@ -699,7 +699,7 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
 	.address = (addr), \
 	.scan_index = ADIS16400_SCAN_ACC_ ## mod, \
 	.scan_type = { \
-		.sign = 's', \
+		.format = 's', \
 		.realbits = (bits), \
 		.storagebits = 16, \
 		.shift = 0, \
@@ -718,7 +718,7 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
 	.address = (addr), \
 	.scan_index = ADIS16400_SCAN_MAGN_ ## mod, \
 	.scan_type = { \
-		.sign = 's', \
+		.format = 's', \
 		.realbits = (bits), \
 		.storagebits = 16, \
 		.shift = 0, \
@@ -744,7 +744,7 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
 	.address = (addr), \
 	.scan_index = ADIS16350_SCAN_TEMP_ ## mod, \
 	.scan_type = { \
-		.sign = 's', \
+		.format = 's', \
 		.realbits = (bits), \
 		.storagebits = 16, \
 		.shift = 0, \
@@ -763,7 +763,7 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
 	.address = (addr), \
 	.scan_index = ADIS16350_SCAN_TEMP_X, \
 	.scan_type = { \
-		.sign = 's', \
+		.format = 's', \
 		.realbits = (bits), \
 		.storagebits = 16, \
 		.shift = 0, \
@@ -781,7 +781,7 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
 	.address = (addr), \
 	.scan_index = ADIS16300_SCAN_INCLI_ ## mod, \
 	.scan_type = { \
-		.sign = 's', \
+		.format = 's', \
 		.realbits = (bits), \
 		.storagebits = 16, \
 		.shift = 0, \
@@ -834,7 +834,7 @@ static const struct iio_chan_spec adis16448_channels[] = {
 		.address = ADIS16448_BARO_OUT,
 		.scan_index = ADIS16400_SCAN_BARO,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_BE,
diff --git a/drivers/iio/imu/adis16460.c b/drivers/iio/imu/adis16460.c
index ba1887d36577..e26e83ab4442 100644
--- a/drivers/iio/imu/adis16460.c
+++ b/drivers/iio/imu/adis16460.c
@@ -242,7 +242,7 @@ enum {
 		.address = (_address), \
 		.scan_index = (_si), \
 		.scan_type = { \
-			.sign = 's', \
+			.format = 's', \
 			.realbits = (_bits), \
 			.storagebits = (_bits), \
 			.endianness = IIO_BE, \
@@ -270,7 +270,7 @@ enum {
 		.address = ADIS16460_REG_TEMP_OUT, \
 		.scan_index = ADIS16460_SCAN_TEMP, \
 		.scan_type = { \
-			.sign = 's', \
+			.format = 's', \
 			.realbits = 16, \
 			.storagebits = 16, \
 			.endianness = IIO_BE, \
diff --git a/drivers/iio/imu/adis16475.c b/drivers/iio/imu/adis16475.c
index ab39bea1e729..61b0060e206a 100644
--- a/drivers/iio/imu/adis16475.c
+++ b/drivers/iio/imu/adis16475.c
@@ -671,7 +671,7 @@ static int adis16475_write_raw(struct iio_dev *indio_dev,
 		.address = (_address), \
 		.scan_index = (_si), \
 		.scan_type = { \
-			.sign = 's', \
+			.format = 's', \
 			.realbits = (_r_bits), \
 			.storagebits = (_s_bits), \
 			.endianness = IIO_BE, \
@@ -699,7 +699,7 @@ static int adis16475_write_raw(struct iio_dev *indio_dev,
 		.address = ADIS16475_REG_TEMP_OUT, \
 		.scan_index = ADIS16475_SCAN_TEMP, \
 		.scan_type = { \
-			.sign = 's', \
+			.format = 's', \
 			.realbits = 16, \
 			.storagebits = 16, \
 			.endianness = IIO_BE, \
@@ -717,7 +717,7 @@ static int adis16475_write_raw(struct iio_dev *indio_dev,
 		.address = (_address), \
 		.scan_index = _si, \
 		.scan_type = { \
-			.sign = 's', \
+			.format = 's', \
 			.realbits = (_r_bits), \
 			.storagebits = (_s_bits), \
 			.endianness = IIO_BE, \
diff --git a/drivers/iio/imu/adis16480.c b/drivers/iio/imu/adis16480.c
index 543d5c4bfb11..71bd30a43eb1 100644
--- a/drivers/iio/imu/adis16480.c
+++ b/drivers/iio/imu/adis16480.c
@@ -741,7 +741,7 @@ static int adis16480_write_raw(struct iio_dev *indio_dev,
 		.address = (_address), \
 		.scan_index = (_si), \
 		.scan_type = { \
-			.sign = 's', \
+			.format = 's', \
 			.realbits = (_bits), \
 			.storagebits = (_bits), \
 			.endianness = IIO_BE, \
@@ -798,7 +798,7 @@ static int adis16480_write_raw(struct iio_dev *indio_dev,
 		.address = ADIS16480_REG_BAROM_OUT, \
 		.scan_index = ADIS16480_SCAN_BARO, \
 		.scan_type = { \
-			.sign = 's', \
+			.format = 's', \
 			.realbits = 32, \
 			.storagebits = 32, \
 			.endianness = IIO_BE, \
@@ -816,7 +816,7 @@ static int adis16480_write_raw(struct iio_dev *indio_dev,
 		.address = ADIS16480_REG_TEMP_OUT, \
 		.scan_index = ADIS16480_SCAN_TEMP, \
 		.scan_type = { \
-			.sign = 's', \
+			.format = 's', \
 			.realbits = 16, \
 			.storagebits = 16, \
 			.endianness = IIO_BE, \
diff --git a/drivers/iio/imu/adis16550.c b/drivers/iio/imu/adis16550.c
index 28f0dbd0226c..5e73a756f254 100644
--- a/drivers/iio/imu/adis16550.c
+++ b/drivers/iio/imu/adis16550.c
@@ -706,7 +706,7 @@ static int adis16550_write_raw(struct iio_dev *indio_dev,
 		.address = (_address), \
 		.scan_index = (_si), \
 		.scan_type = { \
-			.sign = 's', \
+			.format = 's', \
 			.realbits = 32, \
 			.storagebits = 32, \
 			.endianness = IIO_BE, \
@@ -731,7 +731,7 @@ static int adis16550_write_raw(struct iio_dev *indio_dev,
 		.address = ADIS16550_REG_TEMP, \
 		.scan_index = ADIS16550_SCAN_TEMP, \
 		.scan_type = { \
-			.sign = 's', \
+			.format = 's', \
 			.realbits = 16, \
 			.storagebits = 32, \
 			.endianness = IIO_BE, \
@@ -748,7 +748,7 @@ static int adis16550_write_raw(struct iio_dev *indio_dev,
 		.address = (_address), \
 		.scan_index = _si, \
 		.scan_type = { \
-			.sign = 's', \
+			.format = 's', \
 			.realbits = 32, \
 			.storagebits = 32, \
 			.endianness = IIO_BE, \
diff --git a/drivers/iio/imu/bmi160/bmi160_core.c b/drivers/iio/imu/bmi160/bmi160_core.c
index 5f47708b4c5d..0a3b7d7c7dd5 100644
--- a/drivers/iio/imu/bmi160/bmi160_core.c
+++ b/drivers/iio/imu/bmi160/bmi160_core.c
@@ -105,7 +105,7 @@
 		BIT(IIO_CHAN_INFO_SAMP_FREQ),			\
 	.scan_index = _index,					\
 	.scan_type = {						\
-		.sign = 's',					\
+		.format = 's',					\
 		.realbits = 16,					\
 		.storagebits = 16,				\
 		.endianness = IIO_LE,				\
diff --git a/drivers/iio/imu/bmi270/bmi270_core.c b/drivers/iio/imu/bmi270/bmi270_core.c
index 2ad230788532..c6a829b8814b 100644
--- a/drivers/iio/imu/bmi270/bmi270_core.c
+++ b/drivers/iio/imu/bmi270/bmi270_core.c
@@ -1275,7 +1275,7 @@ static const struct iio_info bmi270_info = {
 		BIT(IIO_CHAN_INFO_SAMP_FREQ),			\
 	.scan_index = BMI270_SCAN_ACCEL_##_axis,		\
 	.scan_type = {						\
-		.sign = 's',					\
+		.format = 's',					\
 		.realbits = 16,					\
 		.storagebits = 16,				\
 		.endianness = IIO_LE,				\
@@ -1296,7 +1296,7 @@ static const struct iio_info bmi270_info = {
 		BIT(IIO_CHAN_INFO_SAMP_FREQ),			\
 	.scan_index = BMI270_SCAN_GYRO_##_axis,			\
 	.scan_type = {						\
-		.sign = 's',					\
+		.format = 's',					\
 		.realbits = 16,					\
 		.storagebits = 16,				\
 		.endianness = IIO_LE,				\
diff --git a/drivers/iio/imu/bmi323/bmi323_core.c b/drivers/iio/imu/bmi323/bmi323_core.c
index 6bcb9a436581..c7c9184ef6ce 100644
--- a/drivers/iio/imu/bmi323/bmi323_core.c
+++ b/drivers/iio/imu/bmi323/bmi323_core.c
@@ -248,7 +248,7 @@ static const struct iio_event_spec bmi323_accel_event[] = {
 				    BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
 	.scan_index = _index,						\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 16,						\
 		.storagebits = 16,					\
 		.endianness = IIO_LE,					\
@@ -272,7 +272,7 @@ static const struct iio_event_spec bmi323_accel_event[] = {
 				    BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
 	.scan_index = _index,						\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 16,						\
 		.storagebits = 16,					\
 		.endianness = IIO_LE,					\
diff --git a/drivers/iio/imu/bno055/bno055.c b/drivers/iio/imu/bno055/bno055.c
index 303bc308f80a..e74e3e3c5e8c 100644
--- a/drivers/iio/imu/bno055/bno055.c
+++ b/drivers/iio/imu/bno055/bno055.c
@@ -444,7 +444,7 @@ static void bno055_uninit(void *arg)
 	.info_mask_shared_by_type_available = _avail,				\
 	.scan_index = _index,							\
 	.scan_type = {								\
-		.sign = 's',							\
+		.format = 's',							\
 		.realbits = 16,							\
 		.storagebits = 16,						\
 		.endianness = IIO_LE,						\
diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
index 54760d8f92a2..48a8ea89b491 100644
--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
+++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
@@ -42,7 +42,7 @@
 			BIT(IIO_CHAN_INFO_SAMP_FREQ),			\
 		.scan_index = _index,					\
 		.scan_type = {						\
-			.sign = 's',					\
+			.format = 's',					\
 			.realbits = 16,					\
 			.storagebits = 16,				\
 			.endianness = IIO_BE,				\
diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c
index 7ef0a25ec74f..59d23fd62254 100644
--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c
+++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c
@@ -39,7 +39,7 @@
 			BIT(IIO_CHAN_INFO_SAMP_FREQ),			\
 		.scan_index = _index,					\
 		.scan_type = {						\
-			.sign = 's',					\
+			.format = 's',					\
 			.realbits = 16,					\
 			.storagebits = 16,				\
 			.endianness = IIO_BE,				\
diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.h b/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.h
index 3941186512fb..a2f58b8982dc 100644
--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.h
+++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.h
@@ -17,7 +17,7 @@
 			BIT(IIO_CHAN_INFO_SCALE),			\
 		.scan_index = _index,					\
 		.scan_type = {						\
-			.sign = 's',					\
+			.format = 's',					\
 			.realbits = 16,					\
 			.storagebits = 16,				\
 		},							\
diff --git a/drivers/iio/imu/inv_icm45600/inv_icm45600.h b/drivers/iio/imu/inv_icm45600/inv_icm45600.h
index c5b5446f6c3b..485287c05493 100644
--- a/drivers/iio/imu/inv_icm45600/inv_icm45600.h
+++ b/drivers/iio/imu/inv_icm45600/inv_icm45600.h
@@ -346,7 +346,7 @@ inv_icm45600_get_mount_matrix(const struct iio_dev *indio_dev,
 			BIT(IIO_CHAN_INFO_SCALE),			\
 		.scan_index = _index,					\
 		.scan_type = {						\
-			.sign = 's',					\
+			.format = 's',					\
 			.realbits = 16,					\
 			.storagebits = 16,				\
 			.endianness = IIO_LE,				\
diff --git a/drivers/iio/imu/inv_icm45600/inv_icm45600_accel.c b/drivers/iio/imu/inv_icm45600/inv_icm45600_accel.c
index efa22e02657f..6235c03fc9bd 100644
--- a/drivers/iio/imu/inv_icm45600/inv_icm45600_accel.c
+++ b/drivers/iio/imu/inv_icm45600/inv_icm45600_accel.c
@@ -52,7 +52,7 @@ static const struct iio_chan_spec_ext_info inv_icm45600_accel_ext_infos[] = {
 			BIT(IIO_CHAN_INFO_SAMP_FREQ),			\
 		.scan_index = _index,					\
 		.scan_type = {						\
-			.sign = 's',					\
+			.format = 's',					\
 			.realbits = 16,					\
 			.storagebits = 16,				\
 			.endianness = IIO_LE,				\
diff --git a/drivers/iio/imu/inv_icm45600/inv_icm45600_gyro.c b/drivers/iio/imu/inv_icm45600/inv_icm45600_gyro.c
index 1e85fd0e4ea9..a374b276d813 100644
--- a/drivers/iio/imu/inv_icm45600/inv_icm45600_gyro.c
+++ b/drivers/iio/imu/inv_icm45600/inv_icm45600_gyro.c
@@ -52,7 +52,7 @@ static const struct iio_chan_spec_ext_info inv_icm45600_gyro_ext_infos[] = {
 			BIT(IIO_CHAN_INFO_SAMP_FREQ),			\
 		.scan_index = _index,					\
 		.scan_type = {						\
-			.sign = 's',					\
+			.format = 's',					\
 			.realbits = 16,					\
 			.storagebits = 16,				\
 			.endianness = IIO_LE,				\
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
index b2fa1f4957a5..418a623ab856 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
@@ -1469,7 +1469,7 @@ static const struct iio_event_spec inv_wom_events[] = {
 				      BIT(IIO_CHAN_INFO_CALIBBIAS),   \
 		.scan_index = _index,                                 \
 		.scan_type = {                                        \
-				.sign = 's',                          \
+				.format = 's',                        \
 				.realbits = 16,                       \
 				.storagebits = 16,                    \
 				.shift = 0,                           \
@@ -1486,7 +1486,7 @@ static const struct iio_event_spec inv_wom_events[] = {
 				| BIT(IIO_CHAN_INFO_SCALE),	\
 		.scan_index = _index,				\
 		.scan_type = {					\
-			.sign = 's',				\
+			.format = 's',				\
 			.realbits = 16,				\
 			.storagebits = 16,			\
 			.shift = 0,				\
@@ -1578,7 +1578,7 @@ static const unsigned long inv_mpu_scan_masks[] = {
 				      BIT(IIO_CHAN_INFO_RAW),		\
 		.scan_index = _index,					\
 		.scan_type = {						\
-			.sign = 's',					\
+			.format = 's',					\
 			.realbits = _bits,				\
 			.storagebits = 16,				\
 			.shift = 0,					\
diff --git a/drivers/iio/imu/kmx61.c b/drivers/iio/imu/kmx61.c
index 3cd91d8a89ee..43c6281da0bd 100644
--- a/drivers/iio/imu/kmx61.c
+++ b/drivers/iio/imu/kmx61.c
@@ -234,7 +234,7 @@ static const struct iio_event_spec kmx61_event = {
 	.address = KMX61_ACC, \
 	.scan_index = KMX61_AXIS_ ## _axis, \
 	.scan_type = { \
-		.sign = 's', \
+		.format = 's', \
 		.realbits = 12, \
 		.storagebits = 16, \
 		.shift = 4, \
@@ -254,7 +254,7 @@ static const struct iio_event_spec kmx61_event = {
 				BIT(IIO_CHAN_INFO_SAMP_FREQ), \
 	.scan_index = KMX61_AXIS_ ## _axis, \
 	.scan_type = { \
-		.sign = 's', \
+		.format = 's', \
 		.realbits = 14, \
 		.storagebits = 16, \
 		.shift = 2, \
diff --git a/drivers/iio/imu/smi240.c b/drivers/iio/imu/smi240.c
index d159ee59acdd..f2a504c69e6a 100644
--- a/drivers/iio/imu/smi240.c
+++ b/drivers/iio/imu/smi240.c
@@ -80,7 +80,7 @@
 		BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),	\
 	.scan_index = _index,						\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 16,						\
 		.storagebits = 16,					\
 		.endianness = IIO_CPU,					\
@@ -96,7 +96,7 @@
 		BIT(IIO_CHAN_INFO_SCALE),		\
 	.scan_index = _index,				\
 	.scan_type = {					\
-		.sign = 's',				\
+		.format = 's',				\
 		.realbits = 16,				\
 		.storagebits = 16,			\
 		.endianness = IIO_CPU,			\
diff --git a/drivers/iio/imu/smi330/smi330_core.c b/drivers/iio/imu/smi330/smi330_core.c
index 7ec5ae7f521a..5d7f6730e2ca 100644
--- a/drivers/iio/imu/smi330/smi330_core.c
+++ b/drivers/iio/imu/smi330/smi330_core.c
@@ -85,7 +85,7 @@
 		BIT(IIO_CHAN_INFO_SAMP_FREQ),				\
 	.scan_index = SMI330_SCAN_ACCEL_##_axis,			\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 16,						\
 		.storagebits = 16,					\
 		.endianness = IIO_LE,					\
@@ -110,7 +110,7 @@
 		BIT(IIO_CHAN_INFO_SAMP_FREQ),				\
 	.scan_index = SMI330_SCAN_GYRO_##_axis,				\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 16,						\
 		.storagebits = 16,					\
 		.endianness = IIO_LE,					\
@@ -124,7 +124,7 @@
 		BIT(IIO_CHAN_INFO_SCALE),		\
 	.scan_index = _index,				\
 	.scan_type = {					\
-		.sign = 's',				\
+		.format = 's',				\
 		.realbits = 16,				\
 		.storagebits = 16,			\
 		.endianness = IIO_LE,			\
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
index 07b1773c87bd..39d23b9e677c 100644
--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
@@ -92,7 +92,7 @@ enum st_lsm6dsx_hw_id {
 	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
 	.scan_index = scan_idx,						\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 16,						\
 		.storagebits = 16,					\
 		.endianness = IIO_LE,					\
@@ -113,7 +113,7 @@ enum st_lsm6dsx_hw_id {
 	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
 	.scan_index = scan_idx,						\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 16,						\
 		.storagebits = 16,					\
 		.endianness = IIO_LE,					\
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c
index f15a180dc49e..60f16749c79d 100644
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -421,7 +421,7 @@ static ssize_t iio_show_fixed_type(struct device *dev,
 	if (scan_type->repeat > 1)
 		return sysfs_emit(buf, "%s:%c%d/%dX%d>>%u\n",
 		       iio_endian_prefix[type],
-		       scan_type->sign,
+		       scan_type->format,
 		       scan_type->realbits,
 		       scan_type->storagebits,
 		       scan_type->repeat,
@@ -429,7 +429,7 @@ static ssize_t iio_show_fixed_type(struct device *dev,
 	else
 		return sysfs_emit(buf, "%s:%c%d/%d>>%u\n",
 		       iio_endian_prefix[type],
-		       scan_type->sign,
+		       scan_type->format,
 		       scan_type->realbits,
 		       scan_type->storagebits,
 		       scan_type->shift);
diff --git a/drivers/iio/light/acpi-als.c b/drivers/iio/light/acpi-als.c
index d5d1a8b9c035..84626ff5d5bc 100644
--- a/drivers/iio/light/acpi-als.c
+++ b/drivers/iio/light/acpi-als.c
@@ -38,7 +38,7 @@ static const struct iio_chan_spec acpi_als_channels[] = {
 	{
 		.type		= IIO_LIGHT,
 		.scan_type	= {
-			.sign		= 's',
+			.format		= 's',
 			.realbits	= 32,
 			.storagebits	= 32,
 		},
diff --git a/drivers/iio/light/adjd_s311.c b/drivers/iio/light/adjd_s311.c
index edb3d9dc8bed..377bbd821870 100644
--- a/drivers/iio/light/adjd_s311.c
+++ b/drivers/iio/light/adjd_s311.c
@@ -152,7 +152,7 @@ static irqreturn_t adjd_s311_trigger_handler(int irq, void *p)
 	.channel2 = (IIO_MOD_LIGHT_##_color), \
 	.scan_index = (_scan_idx), \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.realbits = 10, \
 		.storagebits = 16, \
 		.endianness = IIO_CPU, \
diff --git a/drivers/iio/light/apds9960.c b/drivers/iio/light/apds9960.c
index 785c5dbe2d08..f227ff629628 100644
--- a/drivers/iio/light/apds9960.c
+++ b/drivers/iio/light/apds9960.c
@@ -278,7 +278,7 @@ static const struct iio_event_spec apds9960_als_event_spec[] = {
 	.scan_index = _si, \
 	.indexed = 1, \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.realbits = 8, \
 		.storagebits = 8, \
 	}, \
diff --git a/drivers/iio/light/as73211.c b/drivers/iio/light/as73211.c
index 32719f584c47..e41aa5a89684 100644
--- a/drivers/iio/light/as73211.c
+++ b/drivers/iio/light/as73211.c
@@ -142,7 +142,7 @@ struct as73211_data {
 	.address = _addr, \
 	.scan_index = _si, \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.realbits = 16, \
 		.storagebits = 16, \
 		.endianness = IIO_LE, \
@@ -194,7 +194,7 @@ static const struct iio_chan_spec as73211_channels[] = {
 		.address = AS73211_OUT_TEMP,
 		.scan_index = AS73211_SCAN_INDEX_TEMP,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_LE,
@@ -216,7 +216,7 @@ static const struct iio_chan_spec as7331_channels[] = {
 		.address = AS73211_OUT_TEMP,
 		.scan_index = AS73211_SCAN_INDEX_TEMP,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_LE,
diff --git a/drivers/iio/light/bh1745.c b/drivers/iio/light/bh1745.c
index 10b00344bbed..d13b58db8c40 100644
--- a/drivers/iio/light/bh1745.c
+++ b/drivers/iio/light/bh1745.c
@@ -207,7 +207,7 @@ static const struct iio_event_spec bh1745_event_spec[] = {
 		.channel2 = IIO_MOD_LIGHT_##_colour, .address = _addr,  \
 		.scan_index = _si,                                      \
 		.scan_type = {                                          \
-			.sign = 'u',                                    \
+			.format = 'u',                                  \
 			.realbits = 16,                                 \
 			.storagebits = 16,                              \
 			.endianness = IIO_CPU,                          \
diff --git a/drivers/iio/light/cros_ec_light_prox.c b/drivers/iio/light/cros_ec_light_prox.c
index 815806ceb5c8..2178ab3f2936 100644
--- a/drivers/iio/light/cros_ec_light_prox.c
+++ b/drivers/iio/light/cros_ec_light_prox.c
@@ -200,7 +200,7 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev)
 	channel->scan_type.shift = 0;
 	channel->scan_index = 0;
 	channel->ext_info = cros_ec_sensors_ext_info;
-	channel->scan_type.sign = 'u';
+	channel->scan_type.format = 'u';
 
 	/* Sensor specific */
 	switch (state->core.type) {
@@ -228,7 +228,7 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev)
 	channel->type = IIO_TIMESTAMP;
 	channel->channel = -1;
 	channel->scan_index = 1;
-	channel->scan_type.sign = 's';
+	channel->scan_type.format = 's';
 	channel->scan_type.realbits = 64;
 	channel->scan_type.storagebits = 64;
 
diff --git a/drivers/iio/light/gp2ap020a00f.c b/drivers/iio/light/gp2ap020a00f.c
index c7df4b258e2c..d493819376ba 100644
--- a/drivers/iio/light/gp2ap020a00f.c
+++ b/drivers/iio/light/gp2ap020a00f.c
@@ -1327,7 +1327,7 @@ static const struct iio_chan_spec gp2ap020a00f_channels[] = {
 		.modified = 1,
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 24,
 			.shift = 0,
 			.storagebits = 32,
@@ -1344,7 +1344,7 @@ static const struct iio_chan_spec gp2ap020a00f_channels[] = {
 		.modified = 1,
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 24,
 			.shift = 0,
 			.storagebits = 32,
@@ -1358,7 +1358,7 @@ static const struct iio_chan_spec gp2ap020a00f_channels[] = {
 		.modified = 0,
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.shift = 0,
 			.storagebits = 16,
diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c
index 384572844162..631602f865e6 100644
--- a/drivers/iio/light/hid-sensor-als.c
+++ b/drivers/iio/light/hid-sensor-als.c
@@ -121,7 +121,7 @@ static const struct iio_chan_spec als_channels[] = {
 static void als_adjust_channel_bit_mask(struct iio_chan_spec *channels,
 					int channel, int size)
 {
-	channels[channel].scan_type.sign = 's';
+	channels[channel].scan_type.format = 's';
 	/* Real storage bits will change based on the report desc. */
 	channels[channel].scan_type.realbits = size * 8;
 	/* Maximum size of a sample to capture is u32 */
diff --git a/drivers/iio/light/hid-sensor-prox.c b/drivers/iio/light/hid-sensor-prox.c
index efa904a70d0e..f4506c9fe2f0 100644
--- a/drivers/iio/light/hid-sensor-prox.c
+++ b/drivers/iio/light/hid-sensor-prox.c
@@ -71,7 +71,7 @@ static const struct iio_chan_spec prox_channels[] = {
 static void prox_adjust_channel_bit_mask(struct iio_chan_spec *channels,
 					int channel, int size)
 {
-	channels[channel].scan_type.sign = 's';
+	channels[channel].scan_type.format = 's';
 	/* Real storage bits will change based on the report desc. */
 	channels[channel].scan_type.realbits = size * 8;
 	/* Maximum size of a sample to capture is u32 */
diff --git a/drivers/iio/light/isl29125.c b/drivers/iio/light/isl29125.c
index 3acb8a4f1d12..8dec5ab93055 100644
--- a/drivers/iio/light/isl29125.c
+++ b/drivers/iio/light/isl29125.c
@@ -61,7 +61,7 @@ struct isl29125_data {
 	.channel2 = IIO_MOD_LIGHT_##_color, \
 	.scan_index = _si, \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.realbits = 16, \
 		.storagebits = 16, \
 		.endianness = IIO_CPU, \
diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c
index 022e0693983b..889ce4fa8d44 100644
--- a/drivers/iio/light/ltr501.c
+++ b/drivers/iio/light/ltr501.c
@@ -585,7 +585,7 @@ static const struct iio_event_spec ltr501_pxs_event_spec[] = {
 	.info_mask_shared_by_type = (_shared), \
 	.scan_index = (_idx), \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.realbits = 16, \
 		.storagebits = 16, \
 		.endianness = IIO_CPU, \
@@ -617,7 +617,7 @@ static const struct iio_chan_spec ltr501_channels[] = {
 			BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = 2,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 11,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
diff --git a/drivers/iio/light/max44000.c b/drivers/iio/light/max44000.c
index 039d45af3a7f..eacb20c9c945 100644
--- a/drivers/iio/light/max44000.c
+++ b/drivers/iio/light/max44000.c
@@ -135,7 +135,7 @@ static const struct iio_chan_spec max44000_channels[] = {
 					    BIT(IIO_CHAN_INFO_INT_TIME),
 		.scan_index = MAX44000_SCAN_INDEX_ALS,
 		.scan_type = {
-			.sign		= 'u',
+			.format		= 'u',
 			.realbits	= 14,
 			.storagebits	= 16,
 		}
@@ -145,7 +145,7 @@ static const struct iio_chan_spec max44000_channels[] = {
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 		.scan_index = MAX44000_SCAN_INDEX_PRX,
 		.scan_type = {
-			.sign		= 'u',
+			.format		= 'u',
 			.realbits	= 8,
 			.storagebits	= 16,
 		}
diff --git a/drivers/iio/light/opt4060.c b/drivers/iio/light/opt4060.c
index d6e915ab355d..584ecf30082a 100644
--- a/drivers/iio/light/opt4060.c
+++ b/drivers/iio/light/opt4060.c
@@ -534,7 +534,7 @@ static void opt4060_chip_off_action(void *chip)
 	.address = OPT4060_##_color##_MSB,					\
 	.scan_index = OPT4060_##_color,						\
 	.scan_type = {								\
-		.sign = 'u',							\
+		.format = 'u',							\
 		.realbits = 32,							\
 		.storagebits = 32,						\
 		.endianness = IIO_CPU,						\
@@ -558,7 +558,7 @@ static void opt4060_chip_off_action(void *chip)
 	.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME),	\
 	.scan_index = OPT4060_##_channel,					\
 	.scan_type = {								\
-		.sign = 'u',							\
+		.format = 'u',							\
 		.realbits = 32,							\
 		.storagebits = 32,						\
 		.endianness = IIO_CPU,						\
diff --git a/drivers/iio/light/rohm-bu27034.c b/drivers/iio/light/rohm-bu27034.c
index 28d111ac8c0a..800bf2ed51b9 100644
--- a/drivers/iio/light/rohm-bu27034.c
+++ b/drivers/iio/light/rohm-bu27034.c
@@ -158,7 +158,7 @@ static const struct iio_itime_sel_mul bu27034_itimes[] = {
 	.address = BU27034_REG_##_name##_LO,				\
 	.scan_index = BU27034_CHAN_##_name,				\
 	.scan_type = {							\
-		.sign = 'u',						\
+		.format = 'u',						\
 		.realbits = 16,						\
 		.storagebits = 16,					\
 		.endianness = IIO_LE,					\
@@ -174,7 +174,7 @@ static const struct iio_chan_spec bu27034_channels[] = {
 		.channel = BU27034_CHAN_ALS,
 		.scan_index = BU27034_CHAN_ALS,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 32,
 			.storagebits = 32,
 			.endianness = IIO_CPU,
diff --git a/drivers/iio/light/rpr0521.c b/drivers/iio/light/rpr0521.c
index 9341c1d58cbe..f40950750239 100644
--- a/drivers/iio/light/rpr0521.c
+++ b/drivers/iio/light/rpr0521.c
@@ -249,7 +249,7 @@ static const struct iio_chan_spec rpr0521_channels[] = {
 		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 		.scan_index = RPR0521_CHAN_INDEX_PXS,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_LE,
@@ -265,7 +265,7 @@ static const struct iio_chan_spec rpr0521_channels[] = {
 		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 		.scan_index = RPR0521_CHAN_INDEX_BOTH,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_LE,
@@ -281,7 +281,7 @@ static const struct iio_chan_spec rpr0521_channels[] = {
 		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 		.scan_index = RPR0521_CHAN_INDEX_IR,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_LE,
diff --git a/drivers/iio/light/si1145.c b/drivers/iio/light/si1145.c
index ef0abc4499b7..78c1cc320d38 100644
--- a/drivers/iio/light/si1145.c
+++ b/drivers/iio/light/si1145.c
@@ -793,7 +793,7 @@ static int si1145_write_raw(struct iio_dev *indio_dev,
 }
 
 #define SI1145_ST { \
-	.sign = 'u', \
+	.format = 'u', \
 	.realbits = 16, \
 	.storagebits = 16, \
 	.endianness = IIO_LE, \
diff --git a/drivers/iio/light/st_uvis25_core.c b/drivers/iio/light/st_uvis25_core.c
index bcd729a9924e..a18fbf791a90 100644
--- a/drivers/iio/light/st_uvis25_core.c
+++ b/drivers/iio/light/st_uvis25_core.c
@@ -43,7 +43,7 @@ static const struct iio_chan_spec st_uvis25_channels[] = {
 		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 8,
 			.storagebits = 8,
 		},
diff --git a/drivers/iio/light/tcs3414.c b/drivers/iio/light/tcs3414.c
index 5be461e6dbdb..9b4c8184af8f 100644
--- a/drivers/iio/light/tcs3414.c
+++ b/drivers/iio/light/tcs3414.c
@@ -65,7 +65,7 @@ struct tcs3414_data {
 	.address = _addr, \
 	.scan_index = _si, \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.realbits = 16, \
 		.storagebits = 16, \
 		.endianness = IIO_CPU, \
diff --git a/drivers/iio/light/tcs3472.c b/drivers/iio/light/tcs3472.c
index 12429a3261b3..7328631876fb 100644
--- a/drivers/iio/light/tcs3472.c
+++ b/drivers/iio/light/tcs3472.c
@@ -93,7 +93,7 @@ static const struct iio_event_spec tcs3472_events[] = {
 	.address = _addr, \
 	.scan_index = _si, \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.realbits = 16, \
 		.storagebits = 16, \
 		.endianness = IIO_CPU, \
diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c
index a36c23813679..29e719a392ef 100644
--- a/drivers/iio/light/vcnl4000.c
+++ b/drivers/iio/light/vcnl4000.c
@@ -1809,7 +1809,7 @@ static const struct iio_chan_spec vcnl4010_channels[] = {
 		.num_event_specs = ARRAY_SIZE(vcnl4000_event_spec),
 		.ext_info = vcnl4000_ext_info,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
diff --git a/drivers/iio/light/vcnl4035.c b/drivers/iio/light/vcnl4035.c
index 963747927425..976383b72ac0 100644
--- a/drivers/iio/light/vcnl4035.c
+++ b/drivers/iio/light/vcnl4035.c
@@ -378,7 +378,7 @@ static const struct iio_chan_spec vcnl4035_channels[] = {
 		.num_event_specs = ARRAY_SIZE(vcnl4035_event_spec),
 		.scan_index = VCNL4035_CHAN_INDEX_LIGHT,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_LE,
@@ -392,7 +392,7 @@ static const struct iio_chan_spec vcnl4035_channels[] = {
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 		.scan_index = VCNL4035_CHAN_INDEX_WHITE_LED,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_LE,
diff --git a/drivers/iio/light/veml6030.c b/drivers/iio/light/veml6030.c
index 6bcacae3863c..a1c63ad52246 100644
--- a/drivers/iio/light/veml6030.c
+++ b/drivers/iio/light/veml6030.c
@@ -285,7 +285,7 @@ static const struct iio_chan_spec veml6030_channels[] = {
 		.num_event_specs = ARRAY_SIZE(veml6030_event_spec),
 		.scan_index = VEML6030_SCAN_ALS,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
@@ -303,7 +303,7 @@ static const struct iio_chan_spec veml6030_channels[] = {
 						     BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = VEML6030_SCAN_WH,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
@@ -324,7 +324,7 @@ static const struct iio_chan_spec veml7700_channels[] = {
 						     BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = VEML6030_SCAN_ALS,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
@@ -342,7 +342,7 @@ static const struct iio_chan_spec veml7700_channels[] = {
 						     BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = VEML6030_SCAN_WH,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
diff --git a/drivers/iio/light/veml6046x00.c b/drivers/iio/light/veml6046x00.c
index e60f24d46e7b..692cdedd202d 100644
--- a/drivers/iio/light/veml6046x00.c
+++ b/drivers/iio/light/veml6046x00.c
@@ -329,7 +329,7 @@ static const struct iio_chan_spec veml6046x00_channels[] = {
 						     BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = VEML6046X00_SCAN_R,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_LE,
@@ -347,7 +347,7 @@ static const struct iio_chan_spec veml6046x00_channels[] = {
 						     BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = VEML6046X00_SCAN_G,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_LE,
@@ -365,7 +365,7 @@ static const struct iio_chan_spec veml6046x00_channels[] = {
 						     BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = VEML6046X00_SCAN_B,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_LE,
@@ -383,7 +383,7 @@ static const struct iio_chan_spec veml6046x00_channels[] = {
 						     BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = VEML6046X00_SCAN_IR,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_LE,
diff --git a/drivers/iio/light/vl6180.c b/drivers/iio/light/vl6180.c
index c1314b144367..3aebeea6ece9 100644
--- a/drivers/iio/light/vl6180.c
+++ b/drivers/iio/light/vl6180.c
@@ -281,7 +281,7 @@ static const struct iio_chan_spec vl6180_channels[] = {
 		.address = VL6180_ALS,
 		.scan_index = VL6180_ALS,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 		},
@@ -295,7 +295,7 @@ static const struct iio_chan_spec vl6180_channels[] = {
 		.address = VL6180_RANGE,
 		.scan_index = VL6180_RANGE,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 8,
 			.storagebits = 8,
 		},
@@ -307,7 +307,7 @@ static const struct iio_chan_spec vl6180_channels[] = {
 		.address = VL6180_PROX,
 		.scan_index = VL6180_PROX,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 		},
diff --git a/drivers/iio/magnetometer/af8133j.c b/drivers/iio/magnetometer/af8133j.c
index b1768c3aa8f3..cac53f85a6e6 100644
--- a/drivers/iio/magnetometer/af8133j.c
+++ b/drivers/iio/magnetometer/af8133j.c
@@ -84,7 +84,7 @@ static const struct iio_chan_spec_ext_info af8133j_ext_info[] = {
 	.ext_info = af8133j_ext_info, \
 	.scan_index = _si, \
 	.scan_type = { \
-		.sign = 's', \
+		.format = 's', \
 		.realbits = 16, \
 		.storagebits = 16, \
 		.endianness = IIO_LE, \
diff --git a/drivers/iio/magnetometer/ak8974.c b/drivers/iio/magnetometer/ak8974.c
index 68ece700c7ce..000429798b9e 100644
--- a/drivers/iio/magnetometer/ak8974.c
+++ b/drivers/iio/magnetometer/ak8974.c
@@ -716,7 +716,7 @@ static const struct iio_chan_spec_ext_info ak8974_ext_info[] = {
 		.address = index,					\
 		.scan_index = index,					\
 		.scan_type = {						\
-			.sign = 's',					\
+			.format = 's',					\
 			.realbits = bits,				\
 			.storagebits = 16,				\
 			.endianness = IIO_LE				\
diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c
index d30315ad85de..d0414ab6a155 100644
--- a/drivers/iio/magnetometer/ak8975.c
+++ b/drivers/iio/magnetometer/ak8975.c
@@ -830,7 +830,7 @@ static const struct iio_chan_spec_ext_info ak8975_ext_info[] = {
 		.address = index,					\
 		.scan_index = index,					\
 		.scan_type = {						\
-			.sign = 's',					\
+			.format = 's',					\
 			.realbits = 16,					\
 			.storagebits = 16,				\
 			.endianness = IIO_CPU				\
diff --git a/drivers/iio/magnetometer/als31300.c b/drivers/iio/magnetometer/als31300.c
index 2a2677428ed5..26b2c791eb8f 100644
--- a/drivers/iio/magnetometer/als31300.c
+++ b/drivers/iio/magnetometer/als31300.c
@@ -261,7 +261,7 @@ static irqreturn_t als31300_trigger_handler(int irq, void *p)
 		.address = index,					     \
 		.scan_index = index,					     \
 		.scan_type = {						     \
-			.sign = 's',					     \
+			.format = 's',					     \
 			.realbits = 12,					     \
 			.storagebits = 16,				     \
 			.endianness = IIO_CPU,				     \
@@ -277,7 +277,7 @@ static const struct iio_chan_spec als31300_channels[] = {
 		.address = TEMPERATURE,
 		.scan_index = TEMPERATURE,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
diff --git a/drivers/iio/magnetometer/bmc150_magn.c b/drivers/iio/magnetometer/bmc150_magn.c
index a022e1805dff..52669027c63b 100644
--- a/drivers/iio/magnetometer/bmc150_magn.c
+++ b/drivers/iio/magnetometer/bmc150_magn.c
@@ -633,7 +633,7 @@ static const struct attribute_group bmc150_magn_attrs_group = {
 				    BIT(IIO_CHAN_INFO_SCALE),		\
 	.scan_index = AXIS_##_axis,					\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 32,						\
 		.storagebits = 32,					\
 		.endianness = IIO_LE					\
diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index c673f9323e47..177236c60ce5 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -136,7 +136,7 @@ static const struct iio_chan_spec magn_3d_channels[] = {
 static void magn_3d_adjust_channel_bit_mask(struct iio_chan_spec *channels,
 						int channel, int size)
 {
-	channels[channel].scan_type.sign = 's';
+	channels[channel].scan_type.format = 's';
 	/* Real storage bits will change based on the report desc. */
 	channels[channel].scan_type.realbits = size * 8;
 	/* Maximum size of a sample to capture is u32 */
diff --git a/drivers/iio/magnetometer/hmc5843_core.c b/drivers/iio/magnetometer/hmc5843_core.c
index fc16ebd314f7..876653ec3f68 100644
--- a/drivers/iio/magnetometer/hmc5843_core.c
+++ b/drivers/iio/magnetometer/hmc5843_core.c
@@ -471,7 +471,7 @@ static irqreturn_t hmc5843_trigger_handler(int irq, void *p)
 			BIT(IIO_CHAN_INFO_SAMP_FREQ),			\
 		.scan_index = idx,					\
 		.scan_type = {						\
-			.sign = 's',					\
+			.format = 's',					\
 			.realbits = 16,					\
 			.storagebits = 16,				\
 			.endianness = IIO_BE,				\
@@ -489,7 +489,7 @@ static irqreturn_t hmc5843_trigger_handler(int irq, void *p)
 			BIT(IIO_CHAN_INFO_SAMP_FREQ),			\
 		.scan_index = idx,					\
 		.scan_type = {						\
-			.sign = 's',					\
+			.format = 's',					\
 			.realbits = 16,					\
 			.storagebits = 16,				\
 			.endianness = IIO_BE,				\
diff --git a/drivers/iio/magnetometer/mag3110.c b/drivers/iio/magnetometer/mag3110.c
index ff09250a06e7..4d7bdd74318e 100644
--- a/drivers/iio/magnetometer/mag3110.c
+++ b/drivers/iio/magnetometer/mag3110.c
@@ -422,7 +422,7 @@ static irqreturn_t mag3110_trigger_handler(int irq, void *p)
 		BIT(IIO_CHAN_INFO_SCALE), \
 	.scan_index = idx, \
 	.scan_type = { \
-		.sign = 's', \
+		.format = 's', \
 		.realbits = 16, \
 		.storagebits = 16, \
 		.endianness = IIO_BE, \
@@ -439,7 +439,7 @@ static const struct iio_chan_spec mag3110_channels[] = {
 			BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = 3,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 8,
 			.storagebits = 8,
 			},
diff --git a/drivers/iio/magnetometer/rm3100-core.c b/drivers/iio/magnetometer/rm3100-core.c
index 2b2884425746..498520dc514f 100644
--- a/drivers/iio/magnetometer/rm3100-core.c
+++ b/drivers/iio/magnetometer/rm3100-core.c
@@ -237,7 +237,7 @@ static int rm3100_read_mag(struct rm3100_data *data, int idx, int *val)
 			BIT(IIO_CHAN_INFO_SAMP_FREQ),			\
 		.scan_index = idx,					\
 		.scan_type = {						\
-			.sign = 's',					\
+			.format = 's',					\
 			.realbits = 24,					\
 			.storagebits = 32,				\
 			.shift = 8,					\
diff --git a/drivers/iio/magnetometer/tlv493d.c b/drivers/iio/magnetometer/tlv493d.c
index ec53fd40277b..6731088a0320 100644
--- a/drivers/iio/magnetometer/tlv493d.c
+++ b/drivers/iio/magnetometer/tlv493d.c
@@ -379,7 +379,7 @@ static irqreturn_t tlv493d_trigger_handler(int irq, void *ptr)
 		.address = index,				\
 		.scan_index = index,				\
 		.scan_type = {					\
-			.sign = 's',				\
+			.format = 's',				\
 			.realbits = 12,				\
 			.storagebits = 16,			\
 			.endianness = IIO_CPU,			\
@@ -398,7 +398,7 @@ static const struct iio_chan_spec tlv493d_channels[] = {
 		.address = TLV493D_TEMPERATURE,
 		.scan_index = TLV493D_TEMPERATURE,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 12,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
diff --git a/drivers/iio/magnetometer/tmag5273.c b/drivers/iio/magnetometer/tmag5273.c
index 2adc3c036ab4..61790147bdea 100644
--- a/drivers/iio/magnetometer/tmag5273.c
+++ b/drivers/iio/magnetometer/tmag5273.c
@@ -405,7 +405,7 @@ static int tmag5273_write_raw(struct iio_dev *indio_dev,
 		.address = index,					     \
 		.scan_index = index,					     \
 		.scan_type = {						     \
-			.sign = 's',					     \
+			.format = 's',					     \
 			.realbits = 16,					     \
 			.storagebits = 16,				     \
 			.endianness = IIO_CPU,				     \
@@ -421,7 +421,7 @@ static const struct iio_chan_spec tmag5273_channels[] = {
 		.address = TEMPERATURE,
 		.scan_index = TEMPERATURE,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
@@ -441,7 +441,7 @@ static const struct iio_chan_spec tmag5273_channels[] = {
 		.address = ANGLE,
 		.scan_index = ANGLE,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
@@ -457,7 +457,7 @@ static const struct iio_chan_spec tmag5273_channels[] = {
 		.address = MAGNITUDE,
 		.scan_index = MAGNITUDE,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
diff --git a/drivers/iio/magnetometer/yamaha-yas530.c b/drivers/iio/magnetometer/yamaha-yas530.c
index d49e37edcbed..f836c7cc6790 100644
--- a/drivers/iio/magnetometer/yamaha-yas530.c
+++ b/drivers/iio/magnetometer/yamaha-yas530.c
@@ -713,7 +713,7 @@ static const struct iio_chan_spec_ext_info yas5xx_ext_info[] = {
 		.address = index,					\
 		.scan_index = index,					\
 		.scan_type = {						\
-			.sign = 's',					\
+			.format = 's',					\
 			.realbits = 32,					\
 			.storagebits = 32,				\
 			.endianness = IIO_CPU,				\
@@ -727,7 +727,7 @@ static const struct iio_chan_spec yas5xx_channels[] = {
 		.address = 0,
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 32,
 			.storagebits = 32,
 			.endianness = IIO_CPU,
diff --git a/drivers/iio/orientation/hid-sensor-incl-3d.c b/drivers/iio/orientation/hid-sensor-incl-3d.c
index 4e23a598a3fb..577b4a5bad34 100644
--- a/drivers/iio/orientation/hid-sensor-incl-3d.c
+++ b/drivers/iio/orientation/hid-sensor-incl-3d.c
@@ -89,7 +89,7 @@ static const struct iio_chan_spec incl_3d_channels[] = {
 static void incl_3d_adjust_channel_bit_mask(struct iio_chan_spec *chan,
 						int size)
 {
-	chan->scan_type.sign = 's';
+	chan->scan_type.format = 's';
 	/* Real storage bits will change based on the report desc. */
 	chan->scan_type.realbits = size * 8;
 	/* Maximum size of a sample to capture is u32 */
diff --git a/drivers/iio/orientation/hid-sensor-rotation.c b/drivers/iio/orientation/hid-sensor-rotation.c
index e759f91a710a..dddf8dfc328b 100644
--- a/drivers/iio/orientation/hid-sensor-rotation.c
+++ b/drivers/iio/orientation/hid-sensor-rotation.c
@@ -54,7 +54,7 @@ static const struct iio_chan_spec dev_rot_channels[] = {
 static void dev_rot_adjust_channel_bit_mask(struct iio_chan_spec *chan,
 						int size)
 {
-	chan->scan_type.sign = 's';
+	chan->scan_type.format = 's';
 	/* Real storage bits will change based on the report desc. */
 	chan->scan_type.realbits = size * 8;
 	/* Maximum size of a sample to capture is u32 */
diff --git a/drivers/iio/position/hid-sensor-custom-intel-hinge.c b/drivers/iio/position/hid-sensor-custom-intel-hinge.c
index a26d391661fd..fb4e38dbdb89 100644
--- a/drivers/iio/position/hid-sensor-custom-intel-hinge.c
+++ b/drivers/iio/position/hid-sensor-custom-intel-hinge.c
@@ -65,7 +65,7 @@ static const struct iio_chan_spec hinge_channels[] = {
 			BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS),
 		.scan_index = CHANNEL_SCAN_INDEX_HINGE_ANGLE,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.storagebits = 32,
 		},
 	}, {
@@ -78,7 +78,7 @@ static const struct iio_chan_spec hinge_channels[] = {
 			BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS),
 		.scan_index = CHANNEL_SCAN_INDEX_SCREEN_ANGLE,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.storagebits = 32,
 		},
 	}, {
@@ -91,7 +91,7 @@ static const struct iio_chan_spec hinge_channels[] = {
 			BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS),
 		.scan_index = CHANNEL_SCAN_INDEX_KEYBOARD_ANGLE,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.storagebits = 32,
 		},
 	},
diff --git a/drivers/iio/potentiostat/lmp91000.c b/drivers/iio/potentiostat/lmp91000.c
index eccc2a34358f..4bd06ada903d 100644
--- a/drivers/iio/potentiostat/lmp91000.c
+++ b/drivers/iio/potentiostat/lmp91000.c
@@ -85,7 +85,7 @@ static const struct iio_chan_spec lmp91000_channels[] = {
 				      BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 32,
 			.storagebits = 32,
 		},
diff --git a/drivers/iio/pressure/abp2030pa.c b/drivers/iio/pressure/abp2030pa.c
index 4ca056a73cef..734cdaa4b252 100644
--- a/drivers/iio/pressure/abp2030pa.c
+++ b/drivers/iio/pressure/abp2030pa.c
@@ -426,7 +426,7 @@ static const struct iio_chan_spec abp2_channels[] = {
 					BIT(IIO_CHAN_INFO_OFFSET),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 24,
 			.storagebits = 32,
 			.endianness = IIO_CPU,
@@ -439,7 +439,7 @@ static const struct iio_chan_spec abp2_channels[] = {
 				      BIT(IIO_CHAN_INFO_OFFSET),
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 24,
 			.storagebits = 32,
 			.endianness = IIO_CPU,
diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
index d983ce9c0b99..59e04154cfe2 100644
--- a/drivers/iio/pressure/bmp280-core.c
+++ b/drivers/iio/pressure/bmp280-core.c
@@ -161,7 +161,7 @@ static const struct iio_chan_spec bmp280_channels[] = {
 				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 32,
 			.storagebits = 32,
 			.endianness = IIO_CPU,
@@ -176,7 +176,7 @@ static const struct iio_chan_spec bmp280_channels[] = {
 				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 32,
 			.storagebits = 32,
 			.endianness = IIO_CPU,
@@ -195,7 +195,7 @@ static const struct iio_chan_spec bme280_channels[] = {
 				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 32,
 			.storagebits = 32,
 			.endianness = IIO_CPU,
@@ -210,7 +210,7 @@ static const struct iio_chan_spec bme280_channels[] = {
 				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 32,
 			.storagebits = 32,
 			.endianness = IIO_CPU,
@@ -225,7 +225,7 @@ static const struct iio_chan_spec bme280_channels[] = {
 				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
 		.scan_index = 2,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 32,
 			.storagebits = 32,
 			.endianness = IIO_CPU,
@@ -246,7 +246,7 @@ static const struct iio_chan_spec bmp380_channels[] = {
 					   BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 32,
 			.storagebits = 32,
 			.endianness = IIO_CPU,
@@ -263,7 +263,7 @@ static const struct iio_chan_spec bmp380_channels[] = {
 					   BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 32,
 			.storagebits = 32,
 			.endianness = IIO_CPU,
@@ -284,7 +284,7 @@ static const struct iio_chan_spec bmp580_channels[] = {
 					   BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 24,
 			.storagebits = 32,
 			.endianness = IIO_LE,
@@ -301,7 +301,7 @@ static const struct iio_chan_spec bmp580_channels[] = {
 					   BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 24,
 			.storagebits = 32,
 			.endianness = IIO_LE,
diff --git a/drivers/iio/pressure/cros_ec_baro.c b/drivers/iio/pressure/cros_ec_baro.c
index c6b950c596c1..d1d722089521 100644
--- a/drivers/iio/pressure/cros_ec_baro.c
+++ b/drivers/iio/pressure/cros_ec_baro.c
@@ -158,7 +158,7 @@ static int cros_ec_baro_probe(struct platform_device *pdev)
 	channel->scan_type.shift = 0;
 	channel->scan_index = 0;
 	channel->ext_info = cros_ec_sensors_ext_info;
-	channel->scan_type.sign = 'u';
+	channel->scan_type.format = 'u';
 
 	/* Sensor specific */
 	switch (state->core.type) {
@@ -175,7 +175,7 @@ static int cros_ec_baro_probe(struct platform_device *pdev)
 	channel->type = IIO_TIMESTAMP;
 	channel->channel = -1;
 	channel->scan_index = 1;
-	channel->scan_type.sign = 's';
+	channel->scan_type.format = 's';
 	channel->scan_type.realbits = 64;
 	channel->scan_type.storagebits = 64;
 
diff --git a/drivers/iio/pressure/dlhl60d.c b/drivers/iio/pressure/dlhl60d.c
index 46feb27fe632..5fb02cdfac39 100644
--- a/drivers/iio/pressure/dlhl60d.c
+++ b/drivers/iio/pressure/dlhl60d.c
@@ -214,7 +214,7 @@ static const struct iio_chan_spec dlh_channels[] = {
 			BIT(IIO_CHAN_INFO_OFFSET),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = DLH_NUM_PR_BITS,
 			.storagebits = 32,
 			.shift = 8,
@@ -229,7 +229,7 @@ static const struct iio_chan_spec dlh_channels[] = {
 			BIT(IIO_CHAN_INFO_OFFSET),
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = DLH_NUM_TEMP_BITS,
 			.storagebits = 32,
 			.shift = 8,
diff --git a/drivers/iio/pressure/hid-sensor-press.c b/drivers/iio/pressure/hid-sensor-press.c
index 5f1d6abda3e4..5248f8390c8e 100644
--- a/drivers/iio/pressure/hid-sensor-press.c
+++ b/drivers/iio/pressure/hid-sensor-press.c
@@ -57,7 +57,7 @@ static const struct iio_chan_spec press_channels[] = {
 static void press_adjust_channel_bit_mask(struct iio_chan_spec *channels,
 					int channel, int size)
 {
-	channels[channel].scan_type.sign = 's';
+	channels[channel].scan_type.format = 's';
 	/* Real storage bits will change based on the report desc. */
 	channels[channel].scan_type.realbits = size * 8;
 	/* Maximum size of a sample to capture is u32 */
diff --git a/drivers/iio/pressure/hsc030pa.c b/drivers/iio/pressure/hsc030pa.c
index 2d00c0656259..914513f2ca99 100644
--- a/drivers/iio/pressure/hsc030pa.c
+++ b/drivers/iio/pressure/hsc030pa.c
@@ -410,7 +410,7 @@ static const struct iio_chan_spec hsc_channels[] = {
 				      BIT(IIO_CHAN_INFO_OFFSET),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 14,
 			.storagebits = 16,
 			.endianness = IIO_BE,
@@ -423,7 +423,7 @@ static const struct iio_chan_spec hsc_channels[] = {
 				      BIT(IIO_CHAN_INFO_OFFSET),
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 11,
 			.storagebits = 16,
 			.shift = 5,
diff --git a/drivers/iio/pressure/mpl3115.c b/drivers/iio/pressure/mpl3115.c
index aeac1586f12e..4f73f2a80298 100644
--- a/drivers/iio/pressure/mpl3115.c
+++ b/drivers/iio/pressure/mpl3115.c
@@ -341,7 +341,7 @@ static const struct iio_chan_spec mpl3115_channels[] = {
 			BIT(IIO_CHAN_INFO_SAMP_FREQ),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 20,
 			.storagebits = 32,
 			.shift = 12,
@@ -359,7 +359,7 @@ static const struct iio_chan_spec mpl3115_channels[] = {
 			BIT(IIO_CHAN_INFO_SAMP_FREQ),
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 12,
 			.storagebits = 16,
 			.shift = 4,
diff --git a/drivers/iio/pressure/mprls0025pa.c b/drivers/iio/pressure/mprls0025pa.c
index e8c495f336ff..515b7d5c01e3 100644
--- a/drivers/iio/pressure/mprls0025pa.c
+++ b/drivers/iio/pressure/mprls0025pa.c
@@ -166,7 +166,7 @@ static const struct iio_chan_spec mpr_channels[] = {
 					BIT(IIO_CHAN_INFO_OFFSET),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 24,
 			.storagebits = 32,
 			.endianness = IIO_CPU,
diff --git a/drivers/iio/pressure/ms5611_core.c b/drivers/iio/pressure/ms5611_core.c
index bdac27bd5a5d..89705f578cc2 100644
--- a/drivers/iio/pressure/ms5611_core.c
+++ b/drivers/iio/pressure/ms5611_core.c
@@ -347,7 +347,7 @@ static const struct iio_chan_spec ms5611_channels[] = {
 			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 32,
 			.storagebits = 32,
 			.endianness = IIO_CPU,
@@ -360,7 +360,7 @@ static const struct iio_chan_spec ms5611_channels[] = {
 			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 32,
 			.storagebits = 32,
 			.endianness = IIO_CPU,
diff --git a/drivers/iio/pressure/rohm-bm1390.c b/drivers/iio/pressure/rohm-bm1390.c
index dac27fd359ad..fc6f9e66baed 100644
--- a/drivers/iio/pressure/rohm-bm1390.c
+++ b/drivers/iio/pressure/rohm-bm1390.c
@@ -176,7 +176,7 @@ static const struct iio_chan_spec bm1390_channels[] = {
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = BM1390_CHAN_PRESSURE,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 22,
 			.storagebits = 32,
 			.endianness = IIO_LE,
@@ -188,7 +188,7 @@ static const struct iio_chan_spec bm1390_channels[] = {
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = BM1390_CHAN_TEMP,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_BE,
diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c
index b70d1cee82f3..d74cc65986e6 100644
--- a/drivers/iio/pressure/st_pressure_core.c
+++ b/drivers/iio/pressure/st_pressure_core.c
@@ -127,7 +127,7 @@ static const struct iio_chan_spec st_press_1_channels[] = {
 		.address = ST_PRESS_1_OUT_XL_ADDR,
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 24,
 			.storagebits = 32,
 			.endianness = IIO_LE,
@@ -141,7 +141,7 @@ static const struct iio_chan_spec st_press_1_channels[] = {
 		.address = ST_TEMP_1_OUT_L_ADDR,
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_LE,
@@ -161,7 +161,7 @@ static const struct iio_chan_spec st_press_lps001wp_channels[] = {
 		.address = ST_PRESS_LPS001WP_OUT_L_ADDR,
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_LE,
@@ -175,7 +175,7 @@ static const struct iio_chan_spec st_press_lps001wp_channels[] = {
 		.address = ST_TEMP_LPS001WP_OUT_L_ADDR,
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_LE,
@@ -193,7 +193,7 @@ static const struct iio_chan_spec st_press_lps22hb_channels[] = {
 		.address = ST_PRESS_1_OUT_XL_ADDR,
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 24,
 			.storagebits = 32,
 			.endianness = IIO_LE,
@@ -208,7 +208,7 @@ static const struct iio_chan_spec st_press_lps22hb_channels[] = {
 		.address = ST_TEMP_1_OUT_L_ADDR,
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_LE,
diff --git a/drivers/iio/pressure/zpa2326.c b/drivers/iio/pressure/zpa2326.c
index 4923a558a26a..99ce1961a493 100644
--- a/drivers/iio/pressure/zpa2326.c
+++ b/drivers/iio/pressure/zpa2326.c
@@ -1545,7 +1545,7 @@ static const struct iio_chan_spec zpa2326_channels[] = {
 		.type                    = IIO_PRESSURE,
 		.scan_index              = 0,
 		.scan_type               = {
-			.sign                   = 'u',
+			.format                 = 'u',
 			.realbits               = 24,
 			.storagebits            = 32,
 			.endianness             = IIO_LE,
@@ -1558,7 +1558,7 @@ static const struct iio_chan_spec zpa2326_channels[] = {
 		.type                    = IIO_TEMP,
 		.scan_index              = 1,
 		.scan_type               = {
-			.sign                   = 's',
+			.format                 = 's',
 			.realbits               = 16,
 			.storagebits            = 16,
 			.endianness             = IIO_LE,
diff --git a/drivers/iio/proximity/as3935.c b/drivers/iio/proximity/as3935.c
index f1018b14aecf..ee8d2ea2fa3b 100644
--- a/drivers/iio/proximity/as3935.c
+++ b/drivers/iio/proximity/as3935.c
@@ -77,7 +77,7 @@ static const struct iio_chan_spec as3935_channels[] = {
 			BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index     = 0,
 		.scan_type = {
-			.sign           = 'u',
+			.format         = 'u',
 			.realbits       = 6,
 			.storagebits    = 8,
 		},
diff --git a/drivers/iio/proximity/hx9023s.c b/drivers/iio/proximity/hx9023s.c
index 2918dfc0df54..7de66a823cf0 100644
--- a/drivers/iio/proximity/hx9023s.c
+++ b/drivers/iio/proximity/hx9023s.c
@@ -248,7 +248,7 @@ static const struct iio_event_spec hx9023s_events[] = {
 	.num_event_specs = ARRAY_SIZE(hx9023s_events),		\
 	.scan_index = idx,					\
 	.scan_type = {						\
-		.sign = 's',					\
+		.format = 's',					\
 		.realbits = 16,					\
 		.storagebits = 16,				\
 		.endianness = IIO_BE,				\
diff --git a/drivers/iio/proximity/irsd200.c b/drivers/iio/proximity/irsd200.c
index 65af31d43453..93e2e5c4218c 100644
--- a/drivers/iio/proximity/irsd200.c
+++ b/drivers/iio/proximity/irsd200.c
@@ -844,7 +844,7 @@ static const struct iio_chan_spec irsd200_channels[] = {
 		.event_spec = irsd200_event_spec,
 		.num_event_specs = ARRAY_SIZE(irsd200_event_spec),
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
diff --git a/drivers/iio/proximity/isl29501.c b/drivers/iio/proximity/isl29501.c
index f69db6f2f380..03ea16bfdd4d 100644
--- a/drivers/iio/proximity/isl29501.c
+++ b/drivers/iio/proximity/isl29501.c
@@ -496,7 +496,7 @@ static const struct iio_chan_spec isl29501_channels[] = {
 			BIT(IIO_CHAN_INFO_SCALE) |
 			BIT(IIO_CHAN_INFO_CALIBBIAS),
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
diff --git a/drivers/iio/proximity/mb1232.c b/drivers/iio/proximity/mb1232.c
index 34b49c54e68b..eb786eeaf9f8 100644
--- a/drivers/iio/proximity/mb1232.c
+++ b/drivers/iio/proximity/mb1232.c
@@ -166,7 +166,7 @@ static const struct iio_chan_spec mb1232_channels[] = {
 				      BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
diff --git a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c
index 21336b8f122a..c011f18f256b 100644
--- a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c
+++ b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c
@@ -52,7 +52,7 @@ static const struct iio_chan_spec lidar_channels[] = {
 			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 		},
diff --git a/drivers/iio/proximity/srf08.c b/drivers/iio/proximity/srf08.c
index d7e4cc48cfbf..63896279ca1f 100644
--- a/drivers/iio/proximity/srf08.c
+++ b/drivers/iio/proximity/srf08.c
@@ -417,7 +417,7 @@ static const struct iio_chan_spec srf08_channels[] = {
 				BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_CPU,
diff --git a/drivers/iio/proximity/sx9310.c b/drivers/iio/proximity/sx9310.c
index fb02eac78ed4..088c33ae9ffd 100644
--- a/drivers/iio/proximity/sx9310.c
+++ b/drivers/iio/proximity/sx9310.c
@@ -151,7 +151,7 @@ static_assert(SX9310_NUM_CHANNELS <= SX_COMMON_MAX_NUM_CHANNELS);
 	.num_event_specs = ARRAY_SIZE(sx_common_events),	 \
 	.scan_index = idx,					 \
 	.scan_type = {						 \
-		.sign = 's',					 \
+		.format = 's',					 \
 		.realbits = 12,					 \
 		.storagebits = 16,				 \
 		.endianness = IIO_BE,				 \
diff --git a/drivers/iio/proximity/sx9324.c b/drivers/iio/proximity/sx9324.c
index c7b2d03c23bc..9b26d0675957 100644
--- a/drivers/iio/proximity/sx9324.c
+++ b/drivers/iio/proximity/sx9324.c
@@ -222,7 +222,7 @@ static const struct iio_chan_spec_ext_info sx9324_channel_ext_info[] = {
 	.num_event_specs = ARRAY_SIZE(sx_common_events),	 \
 	.scan_index = idx,					 \
 	.scan_type = {						 \
-		.sign = 's',					 \
+		.format = 's',					 \
 		.realbits = 12,					 \
 		.storagebits = 16,				 \
 		.endianness = IIO_BE,				 \
diff --git a/drivers/iio/proximity/sx9360.c b/drivers/iio/proximity/sx9360.c
index 4448988d4e7e..02b7dad3686d 100644
--- a/drivers/iio/proximity/sx9360.c
+++ b/drivers/iio/proximity/sx9360.c
@@ -138,7 +138,7 @@ static const struct iio_chan_spec sx9360_channels[] = {
 		.channel = 0,
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 12,
 			.storagebits = 16,
 			.endianness = IIO_BE,
@@ -160,7 +160,7 @@ static const struct iio_chan_spec sx9360_channels[] = {
 		.channel = 1,
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 12,
 			.storagebits = 16,
 			.endianness = IIO_BE,
diff --git a/drivers/iio/proximity/sx9500.c b/drivers/iio/proximity/sx9500.c
index 6c67bae7488c..536ac37934c0 100644
--- a/drivers/iio/proximity/sx9500.c
+++ b/drivers/iio/proximity/sx9500.c
@@ -114,7 +114,7 @@ static const struct iio_event_spec sx9500_events[] = {
 		.num_event_specs = ARRAY_SIZE(sx9500_events),	\
 		.scan_index = idx,				\
 		.scan_type = {					\
-			.sign = 'u',				\
+			.format = 'u',				\
 			.realbits = 16,				\
 			.storagebits = 16,			\
 			.shift = 0,				\
diff --git a/drivers/iio/proximity/vl53l0x-i2c.c b/drivers/iio/proximity/vl53l0x-i2c.c
index ad3e46d47fa8..eb35694beb98 100644
--- a/drivers/iio/proximity/vl53l0x-i2c.c
+++ b/drivers/iio/proximity/vl53l0x-i2c.c
@@ -202,7 +202,7 @@ static const struct iio_chan_spec vl53l0x_channels[] = {
 				      BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 12,
 			.storagebits = 16,
 		},
diff --git a/drivers/iio/resolver/ad2s1210.c b/drivers/iio/resolver/ad2s1210.c
index 06d9c784f93e..2fa3c48702d0 100644
--- a/drivers/iio/resolver/ad2s1210.c
+++ b/drivers/iio/resolver/ad2s1210.c
@@ -925,7 +925,7 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
 		.channel = 0,
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 'u',
+			.format = 'u',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_BE,
@@ -941,7 +941,7 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
 		.channel = 0,
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_BE,
diff --git a/drivers/iio/temperature/hid-sensor-temperature.c b/drivers/iio/temperature/hid-sensor-temperature.c
index 9f628a8e5cfb..2d631cb516af 100644
--- a/drivers/iio/temperature/hid-sensor-temperature.c
+++ b/drivers/iio/temperature/hid-sensor-temperature.c
@@ -47,7 +47,7 @@ static const struct iio_chan_spec temperature_channels[] = {
 static void temperature_adjust_channel_bit_mask(struct iio_chan_spec *channels,
 					int channel, int size)
 {
-	channels[channel].scan_type.sign = 's';
+	channels[channel].scan_type.format = 's';
 	/* Real storage bits will change based on the report desc. */
 	channels[channel].scan_type.realbits = size * 8;
 	/* Maximum size of a sample to capture is s32 */
diff --git a/drivers/iio/temperature/maxim_thermocouple.c b/drivers/iio/temperature/maxim_thermocouple.c
index 205939680fd4..cf07fc7a6925 100644
--- a/drivers/iio/temperature/maxim_thermocouple.c
+++ b/drivers/iio/temperature/maxim_thermocouple.c
@@ -45,7 +45,7 @@ static const struct iio_chan_spec max6675_channels[] = {
 			BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 13,
 			.storagebits = 16,
 			.shift = 3,
@@ -64,7 +64,7 @@ static const struct iio_chan_spec max31855_channels[] = {
 			BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 14,
 			.storagebits = 16,
 			.shift = 2,
@@ -80,7 +80,7 @@ static const struct iio_chan_spec max31855_channels[] = {
 			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 12,
 			.storagebits = 16,
 			.shift = 4,
diff --git a/drivers/iio/temperature/tmp006.c b/drivers/iio/temperature/tmp006.c
index d8d8c8936d17..1ca6273a7d9e 100644
--- a/drivers/iio/temperature/tmp006.c
+++ b/drivers/iio/temperature/tmp006.c
@@ -183,7 +183,7 @@ static const struct iio_chan_spec tmp006_channels[] = {
 		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 16,
 			.storagebits = 16,
 			.endianness = IIO_BE,
@@ -196,7 +196,7 @@ static const struct iio_chan_spec tmp006_channels[] = {
 		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 		.scan_index = 1,
 		.scan_type = {
-			.sign = 's',
+			.format = 's',
 			.realbits = 14,
 			.storagebits = 16,
 			.shift = TMP006_TAMBIENT_SHIFT,
diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h
index f9ae5cdd884f..10a85626854e 100644
--- a/include/linux/iio/common/st_sensors.h
+++ b/include/linux/iio/common/st_sensors.h
@@ -61,7 +61,7 @@
 	.channel2 = ch2, \
 	.address = addr, \
 	.scan_type = { \
-		.sign = s, \
+		.format = s, \
 		.realbits = rbits, \
 		.shift = sbits - rbits, \
 		.storagebits = sbits, \
diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
index a9ecff191bd9..7e41dd92b06a 100644
--- a/include/linux/iio/iio.h
+++ b/include/linux/iio/iio.h
@@ -178,7 +178,7 @@ struct iio_event_spec {
 
 /**
  * struct iio_scan_type - specification for channel data format in buffer
- * @sign:		's' or 'u' to specify signed or unsigned
+ * @format:		(signed or unsigned) integer, or floating point
  * @realbits:		Number of valid bits of data
  * @storagebits:	Realbits + padding
  * @shift:		Shift right by this before masking out realbits.
@@ -189,7 +189,7 @@ struct iio_event_spec {
  * @endianness:		little or big endian
  */
 struct iio_scan_type {
-	char	sign;
+	char	format;
 	u8	realbits;
 	u8	storagebits;
 	u8	shift;
@@ -332,7 +332,7 @@ static inline bool iio_channel_has_available(const struct iio_chan_spec *chan,
 	.channel = -1,							\
 	.scan_index = _si,						\
 	.scan_type = {							\
-		.sign = 's',						\
+		.format = 's',						\
 		.realbits = 64,					\
 		.storagebits = 64,					\
 		},							\
diff --git a/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h
index bfb6df68e6c9..c4c178799859 100644
--- a/include/linux/iio/imu/adis.h
+++ b/include/linux/iio/imu/adis.h
@@ -468,7 +468,7 @@ int adis_single_conversion(struct iio_dev *indio_dev,
 	.address = (addr), \
 	.scan_index = (si), \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.realbits = (bits), \
 		.storagebits = 16, \
 		.endianness = IIO_BE, \
@@ -492,7 +492,7 @@ int adis_single_conversion(struct iio_dev *indio_dev,
 	.address = (addr), \
 	.scan_index = (si), \
 	.scan_type = { \
-		.sign = 'u', \
+		.format = 'u', \
 		.realbits = (bits), \
 		.storagebits = 16, \
 		.endianness = IIO_BE, \
@@ -510,7 +510,7 @@ int adis_single_conversion(struct iio_dev *indio_dev,
 	.address = (addr), \
 	.scan_index = (si), \
 	.scan_type = { \
-		.sign = 's', \
+		.format = 's', \
 		.realbits = (bits), \
 		.storagebits = 16, \
 		.endianness = IIO_BE, \
-- 
2.39.5


^ permalink raw reply related

* Re: [PATCH v2] HID: playstation: Center initial joystick axes to prevent spurious events
From: Guenter Roeck @ 2026-02-24 23:34 UTC (permalink / raw)
  To: Siarhei Vishniakou
  Cc: Jiri Kosina, Benjamin Tissoires, Roderick Colenbrander,
	linux-input, linux-kernel
In-Reply-To: <CAKF84v0eVCSM7L-EvtmoquN87sSS0GA1yX-ewGyzr-hqO7tAGA@mail.gmail.com>

On 2/24/26 14:44, Siarhei Vishniakou wrote:
> вт, 24 февр. 2026 г. в 13:10, Guenter Roeck <linux@roeck-us.net>:
>>
>> On Tue, Nov 11, 2025 at 03:45:19PM -0800, Siarhei Vishniakou wrote:
>>> When a new PlayStation gamepad (DualShock 4 or DualSense) is initialized,
>>> the input subsystem sets the default value for its absolute axes (e.g.,
>>> ABS_X, ABS_Y) to 0.
>>>
>>> However, the hardware's actual neutral/resting state for these joysticks
>>> is 128 (0x80). This creates a mismatch.
>>>
>>> When the first HID report arrives from the device, the driver sees the
>>> resting value of 128. The kernel compares this to its initial state of 0
>>> and incorrectly interprets this as a delta (0 -> 128). Consequently, it
>>> generates EV_ABS events for this initial, non-existent movement.
>>>
>>> This behavior can fail userspace 'sanity check' tests (e.g., in
>>> Android CTS) that correctly assert no motion events should be generated
>>> from a device that is already at rest.
>>>
>>> This patch fixes the issue by explicitly setting the initial value of the
>>> main joystick axes (e.g., ABS_X, ABS_Y, ABS_RX, ABS_RY) to 128 (0x80)
>>> in the common ps_gamepad_create() function.
>>>
>>> This aligns the kernel's initial state with the hardware's expected
>>> neutral state, ensuring that the first report (at 128) produces no
>>> delta and thus, no spurious event.
>>>
>>> Signed-off-by: Siarhei Vishniakou <svv@google.com>
>>> Reviewed-by: Benjamin Tissoires <bentiss@kernel.org>
>>> ---
>>>   drivers/hid/hid-playstation.c | 5 +++++
>>>   1 file changed, 5 insertions(+)
>>>
>>> diff --git a/drivers/hid/hid-playstation.c b/drivers/hid/hid-playstation.c
>>> index 1468fb11e39d..a145b5ea4405 100644
>>> --- a/drivers/hid/hid-playstation.c
>>> +++ b/drivers/hid/hid-playstation.c
>>> @@ -718,11 +718,16 @@ static struct input_dev *ps_gamepad_create(struct hid_device *hdev,
>>>        if (IS_ERR(gamepad))
>>>                return ERR_CAST(gamepad);
>>>
>>> +     /* Set initial resting state for joysticks to 128 (center) */
>>>        input_set_abs_params(gamepad, ABS_X, 0, 255, 0, 0);
>>> +     gamepad->absinfo[ABS_X].value = 128;
>>
>> input_set_abs_params() can fail to allocate absinfo. If that happens,
>> this will crash. AI suggests setting the value with input_abs_set_val()
>> to ensure that the value is checked before dereferencing.
>>
>> Guenter
>>
>>>        input_set_abs_params(gamepad, ABS_Y, 0, 255, 0, 0);
>>> +     gamepad->absinfo[ABS_Y].value = 128;
>>>        input_set_abs_params(gamepad, ABS_Z, 0, 255, 0, 0);
>>>        input_set_abs_params(gamepad, ABS_RX, 0, 255, 0, 0);
>>> +     gamepad->absinfo[ABS_RX].value = 128;
>>>        input_set_abs_params(gamepad, ABS_RY, 0, 255, 0, 0);
>>> +     gamepad->absinfo[ABS_RY].value = 128;
>>>        input_set_abs_params(gamepad, ABS_RZ, 0, 255, 0, 0);
>>>
>>>        input_set_abs_params(gamepad, ABS_HAT0X, -1, 1, 0, 0);
>>> --
>>> 2.51.2.1041.gc1ab5b90ca-goo
> 
> The function `input_set_abs_params` is ill-formed. If this call can
> fail, then it should return some kind of error result instead of void.
> In addition, the function name doesn't suggest that it's going to be
> doing any allocations.
> So the (short-term) fix should be something like this:
> 
> /* Set initial resting state for joysticks to 128 (center) */
> input_set_abs_params(gamepad, ABS_X, 0, 255, 0, 0);
> +   if (gamepad->absinfo == NULL) {
> +       // input_set_abs_params allocates "absinfo" struct, which could fail.
> +       return ERR_CAST(gamepad);
> +   }
> 

That function is called about 870+ times.

> A better long-term option would be to change the signature of
> input_set_abs_params to return a bool, or to add an explicit
> allocation step (looking at code search, there aren't too many places
> using this API today, but this might break 3-rd party stuff).
> 
> Curious to hear maintainers' opinions on this.

The same would apply to the following macro.

static inline void input_abs_set_##_suffix(struct input_dev *dev,       \
                                            unsigned int axis, int val)  \
{                                                                       \
         input_alloc_absinfo(dev);                                       \
         if (dev->absinfo)                                               \
                 dev->absinfo[axis]._item = val;                         \
}

which is called some 170 times with no error check.

Overall, input_abs_set_val() and input_alloc_absinfo() are widely used
in the kernel. Changing that would be monumental. While I agree that the
current code is less than perfect, I think the immediate fix should be
to avoid the crash and use the same mechanism that is used by all other
drivers.

Of course, I am not the maintainer, so that is just my personal opinion.

Thanks,
Guenter


^ permalink raw reply

* Re: [PATCH v2 4/5] input: drv260x: Fix unbalanced regulator_disable() call
From: Dmitry Torokhov @ 2026-02-24 22:45 UTC (permalink / raw)
  To: Yauhen Kharuzhy; +Cc: linux-input, linux-kernel, Hans de Goede
In-Reply-To: <aZbg2w2lIahy_sM9@jekhomev>

On Thu, Feb 19, 2026 at 12:11:47PM +0200, Yauhen Kharuzhy wrote:
> On Wed, Feb 18, 2026 at 06:43:30PM -0800, Dmitry Torokhov wrote:
> > Hi Yauhen,
> > 
> > On Sun, Feb 15, 2026 at 04:14:34PM +0200, Yauhen Kharuzhy wrote:
> > > +static void drv260x_remove(struct i2c_client *client)
> > > +{
> > > +	struct drv260x_data *haptics = i2c_get_clientdata(client);
> > > +
> > > +	regulator_disable(haptics->regulator);
> > >  }
> > 
> > This will result in power being shut off the first thing during
> > unbinding, which is too early.
> > 
> > I switched this to devm_add_action_or_reset() and applied.
> 
> Do you mean that, in this case, regulator_disable() may be called before any
> devm_* registered actions? Good point, thanks.
> 

Yes, all devm* actions are run after remove() completes.

Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH v2] HID: playstation: Center initial joystick axes to prevent spurious events
From: Siarhei Vishniakou @ 2026-02-24 22:44 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: Jiri Kosina, Benjamin Tissoires, Roderick Colenbrander,
	linux-input, linux-kernel
In-Reply-To: <fcaa494a-43ba-410e-ac2b-162f5b4814bc@roeck-us.net>

вт, 24 февр. 2026 г. в 13:10, Guenter Roeck <linux@roeck-us.net>:
>
> On Tue, Nov 11, 2025 at 03:45:19PM -0800, Siarhei Vishniakou wrote:
> > When a new PlayStation gamepad (DualShock 4 or DualSense) is initialized,
> > the input subsystem sets the default value for its absolute axes (e.g.,
> > ABS_X, ABS_Y) to 0.
> >
> > However, the hardware's actual neutral/resting state for these joysticks
> > is 128 (0x80). This creates a mismatch.
> >
> > When the first HID report arrives from the device, the driver sees the
> > resting value of 128. The kernel compares this to its initial state of 0
> > and incorrectly interprets this as a delta (0 -> 128). Consequently, it
> > generates EV_ABS events for this initial, non-existent movement.
> >
> > This behavior can fail userspace 'sanity check' tests (e.g., in
> > Android CTS) that correctly assert no motion events should be generated
> > from a device that is already at rest.
> >
> > This patch fixes the issue by explicitly setting the initial value of the
> > main joystick axes (e.g., ABS_X, ABS_Y, ABS_RX, ABS_RY) to 128 (0x80)
> > in the common ps_gamepad_create() function.
> >
> > This aligns the kernel's initial state with the hardware's expected
> > neutral state, ensuring that the first report (at 128) produces no
> > delta and thus, no spurious event.
> >
> > Signed-off-by: Siarhei Vishniakou <svv@google.com>
> > Reviewed-by: Benjamin Tissoires <bentiss@kernel.org>
> > ---
> >  drivers/hid/hid-playstation.c | 5 +++++
> >  1 file changed, 5 insertions(+)
> >
> > diff --git a/drivers/hid/hid-playstation.c b/drivers/hid/hid-playstation.c
> > index 1468fb11e39d..a145b5ea4405 100644
> > --- a/drivers/hid/hid-playstation.c
> > +++ b/drivers/hid/hid-playstation.c
> > @@ -718,11 +718,16 @@ static struct input_dev *ps_gamepad_create(struct hid_device *hdev,
> >       if (IS_ERR(gamepad))
> >               return ERR_CAST(gamepad);
> >
> > +     /* Set initial resting state for joysticks to 128 (center) */
> >       input_set_abs_params(gamepad, ABS_X, 0, 255, 0, 0);
> > +     gamepad->absinfo[ABS_X].value = 128;
>
> input_set_abs_params() can fail to allocate absinfo. If that happens,
> this will crash. AI suggests setting the value with input_abs_set_val()
> to ensure that the value is checked before dereferencing.
>
> Guenter
>
> >       input_set_abs_params(gamepad, ABS_Y, 0, 255, 0, 0);
> > +     gamepad->absinfo[ABS_Y].value = 128;
> >       input_set_abs_params(gamepad, ABS_Z, 0, 255, 0, 0);
> >       input_set_abs_params(gamepad, ABS_RX, 0, 255, 0, 0);
> > +     gamepad->absinfo[ABS_RX].value = 128;
> >       input_set_abs_params(gamepad, ABS_RY, 0, 255, 0, 0);
> > +     gamepad->absinfo[ABS_RY].value = 128;
> >       input_set_abs_params(gamepad, ABS_RZ, 0, 255, 0, 0);
> >
> >       input_set_abs_params(gamepad, ABS_HAT0X, -1, 1, 0, 0);
> > --
> > 2.51.2.1041.gc1ab5b90ca-goo

The function `input_set_abs_params` is ill-formed. If this call can
fail, then it should return some kind of error result instead of void.
In addition, the function name doesn't suggest that it's going to be
doing any allocations.
So the (short-term) fix should be something like this:

/* Set initial resting state for joysticks to 128 (center) */
input_set_abs_params(gamepad, ABS_X, 0, 255, 0, 0);
+   if (gamepad->absinfo == NULL) {
+       // input_set_abs_params allocates "absinfo" struct, which could fail.
+       return ERR_CAST(gamepad);
+   }

A better long-term option would be to change the signature of
input_set_abs_params to return a bool, or to add an explicit
allocation step (looking at code search, there aren't too many places
using this API today, but this might break 3-rd party stuff).

Curious to hear maintainers' opinions on this.

^ permalink raw reply

* Re: [PATCH 2/2] input: misc: add driver for max16150
From: Dmitry Torokhov @ 2026-02-24 22:42 UTC (permalink / raw)
  To: marcpaolo.sosa
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-input,
	devicetree, linux-kernel
In-Reply-To: <20260223-max16150-v1-2-38e2a4f0d0f1@analog.com>

Hi Marc,

On Mon, Feb 23, 2026 at 07:03:40PM +0800, Marc Paolo Sosa via B4 Relay wrote:
> From: Marc Paolo Sosa <marcpaolo.sosa@analog.com>
> 
> MAX16150/MAX16169 nanoPower Pushbutton On/Off Controller
> 
> Signed-off-by: Marc Paolo Sosa <marcpaolo.sosa@analog.com>
> ---
>  drivers/input/misc/Kconfig    |   9 +++
>  drivers/input/misc/Makefile   |   1 +
>  drivers/input/misc/max16150.c | 161 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 171 insertions(+)
> 
> diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
> index 94a753fcb64f..a31d3d2a7fd6 100644
> --- a/drivers/input/misc/Kconfig
> +++ b/drivers/input/misc/Kconfig
> @@ -178,6 +178,15 @@ config INPUT_E3X0_BUTTON
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called e3x0_button.
>  
> +config INPUT_MAX16150_PWRBUTTON
> +	tristate "MAX16150/MAX16169 Pushbutton driver"
> +	help
> +	  Say Y here if you want to enable power key reporting via
> +	  MAX16150/MAX16169 nanoPower Pushbutton On/Off Controller.
> +
> +	  To compile this driver as a module, choose M here. The module will
> +	  be called max16150.
> +
>  config INPUT_PCSPKR
>  	tristate "PC Speaker support"
>  	depends on PCSPKR_PLATFORM
> diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
> index 415fc4e2918b..c2c1c45f2df6 100644
> --- a/drivers/input/misc/Makefile
> +++ b/drivers/input/misc/Makefile
> @@ -52,6 +52,7 @@ obj-$(CONFIG_INPUT_IQS7222)		+= iqs7222.o
>  obj-$(CONFIG_INPUT_KEYSPAN_REMOTE)	+= keyspan_remote.o
>  obj-$(CONFIG_INPUT_KXTJ9)		+= kxtj9.o
>  obj-$(CONFIG_INPUT_M68K_BEEP)		+= m68kspkr.o
> +obj-$(CONFIG_INPUT_MAX16150_PWRBUTTON)	+= max16150.o
>  obj-$(CONFIG_INPUT_MAX7360_ROTARY)	+= max7360-rotary.o
>  obj-$(CONFIG_INPUT_MAX77650_ONKEY)	+= max77650-onkey.o
>  obj-$(CONFIG_INPUT_MAX77693_HAPTIC)	+= max77693-haptic.o
> diff --git a/drivers/input/misc/max16150.c b/drivers/input/misc/max16150.c
> new file mode 100644
> index 000000000000..ae353b926afc
> --- /dev/null
> +++ b/drivers/input/misc/max16150.c
> @@ -0,0 +1,161 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Analog Devices MAX16150/MAX16169 Pushbutton Driver
> + *
> + * Copyright 2025 Analog Devices Inc.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/init.h>
> +#include <linux/input.h>
> +#include <linux/interrupt.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/kernel.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/platform_device.h>
> +#include <linux/property.h>
> +
> +#define MAX16150_LONG_INTERRUPT 120000000
> +
> +struct max16150_chip_info {
> +	bool has_clr_gpio;
> +};
> +
> +struct max16150_device {
> +	struct input_dev *input;
> +	struct gpio_desc *gpiod;
> +	struct gpio_desc *clr_gpiod;
> +	const struct max16150_chip_info *chip_info;
> +	u64 low, high, duration;

I do not think you need to store "high" and "duration", just "press"
time. I also do not think you need nanosecond resilution, jiffies will
do.

> +	unsigned int keycode;
> +};
> +
> +static irqreturn_t max16150_irq_handler(int irq, void *_max16150)
> +{
> +	struct max16150_device *max16150 = _max16150;
> +	int value;
> +
> +	value = gpiod_get_value(max16150->gpiod);
> +
> +	if (!value) {
> +		max16150->low = ktime_get_ns();
> +		return IRQ_HANDLED;
> +	}
> +
> +	max16150->high = ktime_get_ns();
> +	if (max16150->low) {
> +		max16150->duration = max16150->high - max16150->low;
> +
> +		if (max16150->duration > MAX16150_LONG_INTERRUPT) {

time_after() is probably what you need here.

> +			gpiod_set_value(max16150->clr_gpiod, 1);
> +			input_report_key(max16150->input, max16150->keycode, 1);
> +			input_sync(max16150->input);

Why is press not reported right away?

> +			input_report_key(max16150->input, max16150->keycode, 0);
> +			input_sync(max16150->input);
> +		}
> +
> +		max16150->low = 0;
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static const struct max16150_chip_info max16150_variant_a = {
> +	.has_clr_gpio = true,
> +};
> +
> +static const struct max16150_chip_info max16150_variant_b = {
> +	.has_clr_gpio = false,
> +};
> +
> +static int max16150_probe(struct platform_device *pdev)
> +{
> +	const struct max16150_chip_info *chip_info;
> +	struct max16150_device *max16150;
> +	struct device *dev = &pdev->dev;
> +	int err, irq, ret;

Why do you need both err and ret?

> +	u32 keycode;
> +
> +	chip_info = device_get_match_data(dev);
> +	if (!chip_info)
> +		return -EINVAL;
> +
> +	max16150 = devm_kzalloc(dev, sizeof(*max16150), GFP_KERNEL);
> +	if (!max16150)
> +		return -ENOMEM;
> +
> +	max16150->chip_info = chip_info;
> +
> +	max16150->input = devm_input_allocate_device(dev);
> +	if (!max16150->input)
> +		return -ENOMEM;
> +
> +	max16150->input->name = "MAX16150 Pushbutton";
> +	max16150->input->phys = "max16150/input0";
> +	max16150->input->id.bustype = BUS_HOST;
> +
> +	keycode = KEY_POWER;
> +	ret = device_property_read_u32(dev, "linux,code", &keycode);

	err = ...

> +	if (ret)
> +		return dev_err_probe(dev, ret, "Failed to get keycode\n");
> +
> +	max16150->keycode = keycode;
> +
> +	input_set_capability(max16150->input, EV_KEY, max16150->keycode);
> +
> +	max16150->gpiod = devm_gpiod_get(dev, "interrupt", GPIOD_IN);
> +	if (IS_ERR(max16150->gpiod))
> +		return dev_err_probe(dev, PTR_ERR(max16150->gpiod),
> +				     "Failed to get interrupt GPIO\n");
> +
> +	if (chip_info->has_clr_gpio) {
> +		max16150->clr_gpiod = devm_gpiod_get(dev, "clr", GPIOD_OUT_HIGH);
> +		if (IS_ERR(max16150->clr_gpiod))
> +			return dev_err_probe(dev, PTR_ERR(max16150->clr_gpiod),
> +					     "Failed to get clr GPIO\n");
> +
> +		if (!max16150->clr_gpiod)


How would we end up here? You are using devm_gpiod_get() which will
never return NULL GPIO descriptor.

> +			return dev_err_probe(dev, -ENODEV,
> +						 "clr GPIO is mandatory\n");
> +
> +		if (max16150->clr_gpiod) {
> +			fsleep(1000);
> +			gpiod_set_value(max16150->clr_gpiod, 0);
> +		}
> +	}
> +
> +	irq = gpiod_to_irq(max16150->gpiod);
> +	if (irq < 0)
> +		return dev_err_probe(dev, irq,
> +				     "MAX16150: Failed to map GPIO to IRQ");

As Rob said in DT binding review use interrupts property and separate
IRQ and GPIO handling.

> +
> +	err = devm_request_irq(dev, irq, max16150_irq_handler,
> +			       IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
> +			       "max16150_irq", max16150);
> +	if (err)
> +		return err;
> +
> +	return input_register_device(max16150->input);

	err = input_register_device(...);
	if (err)
		return err;
	
	return 0;

> +}
> +
> +static const struct of_device_id max16150_of_match[] = {
> +	{ .compatible = "adi,max16150a", .data = &max16150_variant_a },
> +	{ .compatible = "adi,max16150b", .data = &max16150_variant_b },
> +	{ .compatible = "adi,max16169a", .data = &max16150_variant_a },
> +	{ .compatible = "adi,max16169b", .data = &max16150_variant_b },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, max16150_of_match);
> +
> +static struct platform_driver max16150_driver = {
> +	.probe  = max16150_probe,
> +	.driver = {
> +		.name = "max16150",
> +		.of_match_table = max16150_of_match,
> +	},
> +};
> +module_platform_driver(max16150_driver);
> +
> +MODULE_AUTHOR("Marc Paolo Sosa <marcpaolo.sosa@analog.com>");
> +MODULE_DESCRIPTION("MAX16150/MAX16169 Pushbutton Driver");
> +MODULE_LICENSE("GPL");

Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH v2 1/2] dt-bindings: input: add GPIO charlieplex keypad
From: Rob Herring @ 2026-02-24 22:36 UTC (permalink / raw)
  To: Hugo Villeneuve
  Cc: hvilleneuve, dmitry.torokhov, krzk+dt, conor+dt, linux-input,
	devicetree, linux-kernel
In-Reply-To: <20260224173247.65ac1b195ff8bab4e8af3163@hugovil.com>

On Tue, Feb 24, 2026 at 4:32 PM Hugo Villeneuve <hugo@hugovil.com> wrote:
>
> On Tue, 24 Feb 2026 15:06:40 -0600
> Rob Herring <robh@kernel.org> wrote:
>
> > On Tue, Feb 24, 2026 at 2:40 PM Hugo Villeneuve <hugo@hugovil.com> wrote:
> > >
> > > Hi Rob,
> > >
> > > On Mon, 23 Feb 2026 17:23:33 -0600
> > > Rob Herring <robh@kernel.org> wrote:
> > >
> > > > On Mon, Feb 23, 2026 at 12:47 PM Hugo Villeneuve <hugo@hugovil.com> wrote:
> > > > >
> > > > > Hi Rob,
> > > > >
> > > > > On Mon, 23 Feb 2026 11:57:06 -0600
> > > > > Rob Herring <robh@kernel.org> wrote:
> > > > >
> > > > > > On Fri, Feb 13, 2026 at 12:14:25PM -0500, Hugo Villeneuve wrote:
> > > > > > > From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
> > > > > > >
> > > > > > > Add DT bindings for GPIO charlieplex keypad.
> > > > > > >
> > > > > > > Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
> > > > > > > ---
> > > > > > >  .../input/gpio-charlieplex-keypad.yaml        | 82 +++++++++++++++++++
> > > > > > >  1 file changed, 82 insertions(+)
> > > > > > >  create mode 100644 Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml
> > > > > > >
> > > > > > > diff --git a/Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml b/Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml
> > > > > > > new file mode 100644
> > > > > > > index 0000000000000..1672491a75a85
> > > > > > > --- /dev/null
> > > > > > > +++ b/Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml
> > > > > > > @@ -0,0 +1,82 @@
> > > > > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > > > > > +%YAML 1.2
> > > > > > > +---
> > > > > > > +
> > > > > > > +$id: http://devicetree.org/schemas/input/gpio-charlieplex-keypad.yaml#
> > > > > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > > > > +
> > > > > > > +title: GPIO charlieplex keypad
> > > > > > > +
> > > > > > > +maintainers:
> > > > > > > +  - Hugo Villeneuve <hvilleneuve@dimonoff.com>
> > > > > > > +
> > > > > > > +description:
> > > > > > > +  The charlieplex keypad supports N^2)-N different key combinations (where N is
> > > > > > > +  the number of lines). Key presses and releases are detected by configuring
> > > > > > > +  only one line as output at a time, and reading other line states. This process
> > > > > > > +  is repeated for each line.
> > > > > > > +  This mechanism doesn't allow to detect simultaneous key presses.
> > > > > > > +
> > > > > > > +allOf:
> > > > > > > +  - $ref: input.yaml#
> > > > > > > +  - $ref: /schemas/input/matrix-keymap.yaml#
> > > > > > > +
> > > > > > > +properties:
> > > > > > > +  compatible:
> > > > > > > +    const: gpio-charlieplex-keypad
> > > > > > > +
> > > > > > > +  autorepeat: true
> > > > > > > +
> > > > > > > +  line-scan-delay-us:
> > > > > > > +    description:
> > > > > > > +      Delay, measured in microseconds, that is needed
> > > > > > > +      before we can scan keypad after activating one line.
> > > > > > > +    default: 0
> > > > > >
> > > > > > Isn't this the same as "col-scan-delay-us" in gpio-matrix-keypad.yaml?
> > > > > > If so, move it to matrix-keymap.yaml to re-use it here.
> > > > >
> > > > > It is used in a similar fashion, but for charlieplex keyboard, there is
> > > > > no concept of "rows" and "columns". There are only
> > > > > lines, which are all equivalent in functionality.
> > > > >
> > > > > > If not, there's a bunch of other scan delay properties just from
> > > > > > grepping "delay" in the input bindings. Surely we can define something
> > > > > > common.
> > > > >
> > > > > Most of those delays refer to something quite different than what
> > > > > "col-scan-delay-us" or "line-scan-delay-us" are used for (it is a delay
> > > > > that we wait when activating a GPIO before we can safely/reliably read
> > > > > other GPIOs connected thru its circuitry).
> > > > >
> > > > > Maybe "col-scan-delay-us" and "line-scan-delay-us" could be
> > > > > combined into a common "line-scan-delay-us" ("line" is more generic
> > > > > than column), and defined in matrix-keymap.yaml.
> > > >
> > > > What about "scan-delay-us"? I would assume all the scan delay
> > > > properties are just the delay after changing the outputs to reading
> > > > the inputs.
> > >
> > > They are for gpio-matrix-keypad.yaml and this binding, but not for
> > > others. Most scan delay properties refer to the period or
> > > interval between successive scans.
> > >
> > > So for my binding, "settling-time-us" would be more accurate and a
> > > better property name (it is also used in adc.yaml).
> >
> > Let's go with that.
>
> Ok, will do.
>
> >
> > >
> > > Looking into a common place to define this new property, I stumbled
> > > upon gpio-delay.yaml, so maybe I do not need this new property at all
> > > and simply define a gpio-delay node if needed (and add it to this
> > > binding example)?
> > >
> > > I tested this and it works, although it requires a patch to the
> > > gpio-aggregator driver, because for now it respect the delay only
> > > when changing the output value, not when switching between input and
> > > output like I do in my driver.
> > >
> > > With my patch, it works ok.
> >
> > I would not use gpio-delay here.
>
> Ok.
>
> I also observed that debounce-delay-ms is re-defined by a few bindings,
> including mine. I assume that I could move all these identical
> definitions to input.yaml and reduce duplication (in a separate patch,
> of course).

Yes, that would be good.

> While testing that, I found an odd situation: if I reference these four
> dummy (undefined anywhere) properties in the gpio-matrix-keypad
> binding, I am expecting four warnings when validating it. However I get
> just three:
>
> ==================
> diff --git
> a/Documentation/devicetree/bindings/input/gpio-matrix-keypad.yaml
> b/Documentation/devicetree/bindings/input/gpio-matrix-keypad.yaml index
> 20b5371fa21c..733458bf4d13 100644
> --- a/Documentation/devicetree/bindings/input/gpio-matrix-keypad.yaml
> +++ b/Documentation/devicetree/bindings/input/gpio-matrix-keypad.yaml
> @@ -36,7 +36,10 @@ properties:
>
>    linux,keymap: true
>
> +  bogus1-delay-ms: true
> +  bogus2-delay-ms-bogus2: true
> +  bogus3-my-property: true
> +  bogus4: true
>
>    linux,no-autorepeat:
>      type: boolean
> ==================
>
> Validation result:
>
> ...
>   SCHEMA  Documentation/devicetree/bindings/processed-schema.json
> ...
> ...input/gpio-matrix-keypad.yaml:
>   bogus2-delay-ms-bogus2: missing type definition
> ...input/gpio-matrix-keypad.yaml:
>   bogus3-my-property: missing type definition
> ...input/gpio-matrix-keypad.yaml:
>   bogus4: missing type definition
>
> any idea why?

Properties with a unit suffix like "-ms" always have a type hence why
they don't ever define a type.

Rob

^ permalink raw reply

* Re: [PATCH v2 1/2] dt-bindings: input: add GPIO charlieplex keypad
From: Hugo Villeneuve @ 2026-02-24 22:32 UTC (permalink / raw)
  To: Rob Herring
  Cc: hvilleneuve, dmitry.torokhov, krzk+dt, conor+dt, linux-input,
	devicetree, linux-kernel
In-Reply-To: <CAL_JsqJtwM33G4qdzpnp6nNtc+tNr6VOKvTB8y6Xv04GTKxymA@mail.gmail.com>

On Tue, 24 Feb 2026 15:06:40 -0600
Rob Herring <robh@kernel.org> wrote:

> On Tue, Feb 24, 2026 at 2:40 PM Hugo Villeneuve <hugo@hugovil.com> wrote:
> >
> > Hi Rob,
> >
> > On Mon, 23 Feb 2026 17:23:33 -0600
> > Rob Herring <robh@kernel.org> wrote:
> >
> > > On Mon, Feb 23, 2026 at 12:47 PM Hugo Villeneuve <hugo@hugovil.com> wrote:
> > > >
> > > > Hi Rob,
> > > >
> > > > On Mon, 23 Feb 2026 11:57:06 -0600
> > > > Rob Herring <robh@kernel.org> wrote:
> > > >
> > > > > On Fri, Feb 13, 2026 at 12:14:25PM -0500, Hugo Villeneuve wrote:
> > > > > > From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
> > > > > >
> > > > > > Add DT bindings for GPIO charlieplex keypad.
> > > > > >
> > > > > > Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
> > > > > > ---
> > > > > >  .../input/gpio-charlieplex-keypad.yaml        | 82 +++++++++++++++++++
> > > > > >  1 file changed, 82 insertions(+)
> > > > > >  create mode 100644 Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml
> > > > > >
> > > > > > diff --git a/Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml b/Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml
> > > > > > new file mode 100644
> > > > > > index 0000000000000..1672491a75a85
> > > > > > --- /dev/null
> > > > > > +++ b/Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml
> > > > > > @@ -0,0 +1,82 @@
> > > > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > > > > +%YAML 1.2
> > > > > > +---
> > > > > > +
> > > > > > +$id: http://devicetree.org/schemas/input/gpio-charlieplex-keypad.yaml#
> > > > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > > > +
> > > > > > +title: GPIO charlieplex keypad
> > > > > > +
> > > > > > +maintainers:
> > > > > > +  - Hugo Villeneuve <hvilleneuve@dimonoff.com>
> > > > > > +
> > > > > > +description:
> > > > > > +  The charlieplex keypad supports N^2)-N different key combinations (where N is
> > > > > > +  the number of lines). Key presses and releases are detected by configuring
> > > > > > +  only one line as output at a time, and reading other line states. This process
> > > > > > +  is repeated for each line.
> > > > > > +  This mechanism doesn't allow to detect simultaneous key presses.
> > > > > > +
> > > > > > +allOf:
> > > > > > +  - $ref: input.yaml#
> > > > > > +  - $ref: /schemas/input/matrix-keymap.yaml#
> > > > > > +
> > > > > > +properties:
> > > > > > +  compatible:
> > > > > > +    const: gpio-charlieplex-keypad
> > > > > > +
> > > > > > +  autorepeat: true
> > > > > > +
> > > > > > +  line-scan-delay-us:
> > > > > > +    description:
> > > > > > +      Delay, measured in microseconds, that is needed
> > > > > > +      before we can scan keypad after activating one line.
> > > > > > +    default: 0
> > > > >
> > > > > Isn't this the same as "col-scan-delay-us" in gpio-matrix-keypad.yaml?
> > > > > If so, move it to matrix-keymap.yaml to re-use it here.
> > > >
> > > > It is used in a similar fashion, but for charlieplex keyboard, there is
> > > > no concept of "rows" and "columns". There are only
> > > > lines, which are all equivalent in functionality.
> > > >
> > > > > If not, there's a bunch of other scan delay properties just from
> > > > > grepping "delay" in the input bindings. Surely we can define something
> > > > > common.
> > > >
> > > > Most of those delays refer to something quite different than what
> > > > "col-scan-delay-us" or "line-scan-delay-us" are used for (it is a delay
> > > > that we wait when activating a GPIO before we can safely/reliably read
> > > > other GPIOs connected thru its circuitry).
> > > >
> > > > Maybe "col-scan-delay-us" and "line-scan-delay-us" could be
> > > > combined into a common "line-scan-delay-us" ("line" is more generic
> > > > than column), and defined in matrix-keymap.yaml.
> > >
> > > What about "scan-delay-us"? I would assume all the scan delay
> > > properties are just the delay after changing the outputs to reading
> > > the inputs.
> >
> > They are for gpio-matrix-keypad.yaml and this binding, but not for
> > others. Most scan delay properties refer to the period or
> > interval between successive scans.
> >
> > So for my binding, "settling-time-us" would be more accurate and a
> > better property name (it is also used in adc.yaml).
> 
> Let's go with that.

Ok, will do.

> 
> >
> > Looking into a common place to define this new property, I stumbled
> > upon gpio-delay.yaml, so maybe I do not need this new property at all
> > and simply define a gpio-delay node if needed (and add it to this
> > binding example)?
> >
> > I tested this and it works, although it requires a patch to the
> > gpio-aggregator driver, because for now it respect the delay only
> > when changing the output value, not when switching between input and
> > output like I do in my driver.
> >
> > With my patch, it works ok.
> 
> I would not use gpio-delay here.

Ok.

I also observed that debounce-delay-ms is re-defined by a few bindings,
including mine. I assume that I could move all these identical
definitions to input.yaml and reduce duplication (in a separate patch,
of course).

While testing that, I found an odd situation: if I reference these four
dummy (undefined anywhere) properties in the gpio-matrix-keypad
binding, I am expecting four warnings when validating it. However I get
just three:

==================
diff --git
a/Documentation/devicetree/bindings/input/gpio-matrix-keypad.yaml
b/Documentation/devicetree/bindings/input/gpio-matrix-keypad.yaml index
20b5371fa21c..733458bf4d13 100644
--- a/Documentation/devicetree/bindings/input/gpio-matrix-keypad.yaml
+++ b/Documentation/devicetree/bindings/input/gpio-matrix-keypad.yaml
@@ -36,7 +36,10 @@ properties:
 
   linux,keymap: true
 
+  bogus1-delay-ms: true
+  bogus2-delay-ms-bogus2: true
+  bogus3-my-property: true
+  bogus4: true
 
   linux,no-autorepeat:
     type: boolean
==================

Validation result:

...
  SCHEMA  Documentation/devicetree/bindings/processed-schema.json
...
...input/gpio-matrix-keypad.yaml:
  bogus2-delay-ms-bogus2: missing type definition
...input/gpio-matrix-keypad.yaml:
  bogus3-my-property: missing type definition
...input/gpio-matrix-keypad.yaml:
  bogus4: missing type definition

any idea why?

Thank you,
Hugo.

-- 
Hugo Villeneuve

^ permalink raw reply

* Re: [PATCH v2] HID: playstation: Center initial joystick axes to prevent spurious events
From: Guenter Roeck @ 2026-02-24 21:10 UTC (permalink / raw)
  To: Siarhei Vishniakou
  Cc: Jiri Kosina, Benjamin Tissoires, Roderick Colenbrander,
	linux-input, linux-kernel
In-Reply-To: <20251111234519.369652-1-svv@google.com>

On Tue, Nov 11, 2025 at 03:45:19PM -0800, Siarhei Vishniakou wrote:
> When a new PlayStation gamepad (DualShock 4 or DualSense) is initialized,
> the input subsystem sets the default value for its absolute axes (e.g.,
> ABS_X, ABS_Y) to 0.
> 
> However, the hardware's actual neutral/resting state for these joysticks
> is 128 (0x80). This creates a mismatch.
> 
> When the first HID report arrives from the device, the driver sees the
> resting value of 128. The kernel compares this to its initial state of 0
> and incorrectly interprets this as a delta (0 -> 128). Consequently, it
> generates EV_ABS events for this initial, non-existent movement.
> 
> This behavior can fail userspace 'sanity check' tests (e.g., in
> Android CTS) that correctly assert no motion events should be generated
> from a device that is already at rest.
> 
> This patch fixes the issue by explicitly setting the initial value of the
> main joystick axes (e.g., ABS_X, ABS_Y, ABS_RX, ABS_RY) to 128 (0x80)
> in the common ps_gamepad_create() function.
> 
> This aligns the kernel's initial state with the hardware's expected
> neutral state, ensuring that the first report (at 128) produces no
> delta and thus, no spurious event.
> 
> Signed-off-by: Siarhei Vishniakou <svv@google.com>
> Reviewed-by: Benjamin Tissoires <bentiss@kernel.org>
> ---
>  drivers/hid/hid-playstation.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/hid/hid-playstation.c b/drivers/hid/hid-playstation.c
> index 1468fb11e39d..a145b5ea4405 100644
> --- a/drivers/hid/hid-playstation.c
> +++ b/drivers/hid/hid-playstation.c
> @@ -718,11 +718,16 @@ static struct input_dev *ps_gamepad_create(struct hid_device *hdev,
>  	if (IS_ERR(gamepad))
>  		return ERR_CAST(gamepad);
>  
> +	/* Set initial resting state for joysticks to 128 (center) */
>  	input_set_abs_params(gamepad, ABS_X, 0, 255, 0, 0);
> +	gamepad->absinfo[ABS_X].value = 128;

input_set_abs_params() can fail to allocate absinfo. If that happens,
this will crash. AI suggests setting the value with input_abs_set_val()
to ensure that the value is checked before dereferencing.

Guenter

>  	input_set_abs_params(gamepad, ABS_Y, 0, 255, 0, 0);
> +	gamepad->absinfo[ABS_Y].value = 128;
>  	input_set_abs_params(gamepad, ABS_Z, 0, 255, 0, 0);
>  	input_set_abs_params(gamepad, ABS_RX, 0, 255, 0, 0);
> +	gamepad->absinfo[ABS_RX].value = 128;
>  	input_set_abs_params(gamepad, ABS_RY, 0, 255, 0, 0);
> +	gamepad->absinfo[ABS_RY].value = 128;
>  	input_set_abs_params(gamepad, ABS_RZ, 0, 255, 0, 0);
>  
>  	input_set_abs_params(gamepad, ABS_HAT0X, -1, 1, 0, 0);
> -- 
> 2.51.2.1041.gc1ab5b90ca-goo

^ permalink raw reply

* Re: [PATCH v2 1/2] dt-bindings: input: add GPIO charlieplex keypad
From: Rob Herring @ 2026-02-24 21:06 UTC (permalink / raw)
  To: Hugo Villeneuve
  Cc: hvilleneuve, dmitry.torokhov, krzk+dt, conor+dt, linux-input,
	devicetree, linux-kernel
In-Reply-To: <20260224154027.0f81b1aa13fe779776e6d58f@hugovil.com>

On Tue, Feb 24, 2026 at 2:40 PM Hugo Villeneuve <hugo@hugovil.com> wrote:
>
> Hi Rob,
>
> On Mon, 23 Feb 2026 17:23:33 -0600
> Rob Herring <robh@kernel.org> wrote:
>
> > On Mon, Feb 23, 2026 at 12:47 PM Hugo Villeneuve <hugo@hugovil.com> wrote:
> > >
> > > Hi Rob,
> > >
> > > On Mon, 23 Feb 2026 11:57:06 -0600
> > > Rob Herring <robh@kernel.org> wrote:
> > >
> > > > On Fri, Feb 13, 2026 at 12:14:25PM -0500, Hugo Villeneuve wrote:
> > > > > From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
> > > > >
> > > > > Add DT bindings for GPIO charlieplex keypad.
> > > > >
> > > > > Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
> > > > > ---
> > > > >  .../input/gpio-charlieplex-keypad.yaml        | 82 +++++++++++++++++++
> > > > >  1 file changed, 82 insertions(+)
> > > > >  create mode 100644 Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml
> > > > >
> > > > > diff --git a/Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml b/Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml
> > > > > new file mode 100644
> > > > > index 0000000000000..1672491a75a85
> > > > > --- /dev/null
> > > > > +++ b/Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml
> > > > > @@ -0,0 +1,82 @@
> > > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > > > +%YAML 1.2
> > > > > +---
> > > > > +
> > > > > +$id: http://devicetree.org/schemas/input/gpio-charlieplex-keypad.yaml#
> > > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > > +
> > > > > +title: GPIO charlieplex keypad
> > > > > +
> > > > > +maintainers:
> > > > > +  - Hugo Villeneuve <hvilleneuve@dimonoff.com>
> > > > > +
> > > > > +description:
> > > > > +  The charlieplex keypad supports N^2)-N different key combinations (where N is
> > > > > +  the number of lines). Key presses and releases are detected by configuring
> > > > > +  only one line as output at a time, and reading other line states. This process
> > > > > +  is repeated for each line.
> > > > > +  This mechanism doesn't allow to detect simultaneous key presses.
> > > > > +
> > > > > +allOf:
> > > > > +  - $ref: input.yaml#
> > > > > +  - $ref: /schemas/input/matrix-keymap.yaml#
> > > > > +
> > > > > +properties:
> > > > > +  compatible:
> > > > > +    const: gpio-charlieplex-keypad
> > > > > +
> > > > > +  autorepeat: true
> > > > > +
> > > > > +  line-scan-delay-us:
> > > > > +    description:
> > > > > +      Delay, measured in microseconds, that is needed
> > > > > +      before we can scan keypad after activating one line.
> > > > > +    default: 0
> > > >
> > > > Isn't this the same as "col-scan-delay-us" in gpio-matrix-keypad.yaml?
> > > > If so, move it to matrix-keymap.yaml to re-use it here.
> > >
> > > It is used in a similar fashion, but for charlieplex keyboard, there is
> > > no concept of "rows" and "columns". There are only
> > > lines, which are all equivalent in functionality.
> > >
> > > > If not, there's a bunch of other scan delay properties just from
> > > > grepping "delay" in the input bindings. Surely we can define something
> > > > common.
> > >
> > > Most of those delays refer to something quite different than what
> > > "col-scan-delay-us" or "line-scan-delay-us" are used for (it is a delay
> > > that we wait when activating a GPIO before we can safely/reliably read
> > > other GPIOs connected thru its circuitry).
> > >
> > > Maybe "col-scan-delay-us" and "line-scan-delay-us" could be
> > > combined into a common "line-scan-delay-us" ("line" is more generic
> > > than column), and defined in matrix-keymap.yaml.
> >
> > What about "scan-delay-us"? I would assume all the scan delay
> > properties are just the delay after changing the outputs to reading
> > the inputs.
>
> They are for gpio-matrix-keypad.yaml and this binding, but not for
> others. Most scan delay properties refer to the period or
> interval between successive scans.
>
> So for my binding, "settling-time-us" would be more accurate and a
> better property name (it is also used in adc.yaml).

Let's go with that.

>
> Looking into a common place to define this new property, I stumbled
> upon gpio-delay.yaml, so maybe I do not need this new property at all
> and simply define a gpio-delay node if needed (and add it to this
> binding example)?
>
> I tested this and it works, although it requires a patch to the
> gpio-aggregator driver, because for now it respect the delay only
> when changing the output value, not when switching between input and
> output like I do in my driver.
>
> With my patch, it works ok.

I would not use gpio-delay here.

Rob

^ 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