lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20250825121632.605b50a2@jic23-huawei>
Date: Mon, 25 Aug 2025 12:16:32 +0100
From: Jonathan Cameron <jic23@...nel.org>
To: Marilene Andrade Garcia <marilene.agarcia@...il.com>
Cc: linux-iio@...r.kernel.org, linux-kernel@...r.kernel.org,
 devicetree@...r.kernel.org, David Lechner <dlechner@...libre.com>, Nuno
 Sá <nuno.sa@...log.com>, Andy Shevchenko <andy@...nel.org>,
 Lars-Peter Clausen <lars@...afoo.de>, Michael Hennerich
 <Michael.Hennerich@...log.com>, Rob Herring <robh@...nel.org>, Krzysztof
 Kozlowski <krzk+dt@...nel.org>, Conor Dooley <conor+dt@...nel.org>, Marcelo
 Schmitt <marcelo.schmitt1@...il.com>, Marcelo Schmitt
 <Marcelo.Schmitt@...log.com>, Ceclan Dumitru <dumitru.ceclan@...log.com>,
 Jonathan Santos <Jonathan.Santos@...log.com>, Dragos Bogdan
 <dragos.bogdan@...log.com>
Subject: Re: [PATCH v1 2/2] iio: adc: Add basic support for MAX14001

On Thu, 21 Aug 2025 10:39:07 -0300
Marilene Andrade Garcia <marilene.agarcia@...il.com> wrote:

> The MAX14001/MAX14002 are configurable, isolated 10-bit ADCs for
> multi-range binary inputs. Besides the ADC readings, the MAX14001/MAX14002
> offers more features, like a binary comparator, a filtered reading that
> can provide the average of the last 2, 4, or 8 ADC readings, and an inrush
> comparator that triggers the inrush current. There is also a fault feature
> that can diagnose seven possible fault conditions. And an option to select
> an external or internal ADC voltage reference.
> 
> Add basic support for MAX14001/MAX14002 with the following features:
> - Raw ADC reading.
> - Filtered ADC average reading with the default configuration.
> 
> Signed-off-by: Marilene Andrade Garcia <marilene.agarcia@...il.com>

Given the discussion on the cover letter, perhaps this will need to be
merged with the earlier set. I'll do a quick review anyway!

Fairly minor comments inline. This is in a pretty good state for a v1.

Thanks,

Jonathan


> ---
>  MAINTAINERS                |   1 +
>  drivers/iio/adc/Kconfig    |  10 ++
>  drivers/iio/adc/Makefile   |   1 +
>  drivers/iio/adc/max14001.c | 213 +++++++++++++++++++++++++++++++++++++
>  4 files changed, 225 insertions(+)
>  create mode 100644 drivers/iio/adc/max14001.c

> diff --git a/drivers/iio/adc/max14001.c b/drivers/iio/adc/max14001.c
> new file mode 100644
> index 000000000000..fb79f3b81e0c
> --- /dev/null
> +++ b/drivers/iio/adc/max14001.c
> @@ -0,0 +1,213 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * MAX14001/MAX14002 SPI ADC driver
> + *
> + * Copyright (c) 2025 Marilene Andrade Garcia <marilene.agarcia@...il.com>
> + *
> + * Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/MAX14001-MAX14002.pdf
> + */
> +
> +#include <asm/unaligned.h>

As per build bot this doesn't work on modern kernels.  linux/unaligned.

> +#include <linux/bitfield.h>
> +#include <linux/bitrev.h>
> +#include <linux/module.h>

various headers missing. Please follow approximate include what you use principles.
There are some headers that are obviously going to be included by another one
because they cannot stand alone, so for those you can include just the parent.
E.g. mutex.h not mutex_types.h but in most other cases all includes with definitions
that are used in this file should be here.

> +#include <linux/spi/spi.h>
> +#include <linux/iio/iio.h>
> +#include <linux/regulator/consumer.h>
> +
> +/* MAX14001 registers definition */
> +#define MAX14001_REG_ADC				0x00
> +#define MAX14001_REG_FADC				0x01
> +#define MAX14001_REG_FLAGS				0x02
> +#define MAX14001_REG_FLTEN				0x03
> +#define MAX14001_REG_THL				0x04
> +#define MAX14001_REG_THU				0x05
> +#define MAX14001_REG_INRR				0x06
> +#define MAX14001_REG_INRT				0x07
> +#define MAX14001_REG_INRP				0x08
> +#define MAX14001_REG_CFG				0x09
> +#define MAX14001_REG_ENBL				0x0A
> +#define MAX14001_REG_ACT				0x0B
> +#define MAX14001_REG_WEN				0x0C
> +
> +/* MAX14001 CONTROL values*/

Missing space before */

They are going in the WR field below I'd rename that MASK_W
then you can just 1 and 0 with their boolean meaning and
not bother with these defines.

> +#define MAX14001_REG_WRITE				0x1
> +#define MAX14001_REG_READ				0x0
> +
> +/* MAX14001 MASKS */
The comment isn't very useful.  Masks of what?  These seems to be
SPI message related.  Also no point in prefixing comments
with MAX14001 when the naming makes that clear.


> +#define MAX14001_MASK_ADDR				GENMASK(15, 11)
> +#define MAX14001_MASK_WR				BIT(10)
> +#define MAX14001_MASK_DATA				GENMASK(9, 0)
> +
> +enum max14001_chip_model {
> +	max14001,
> +	max14002,
> +};
> +
> +struct max14001_chip_info {
> +	const char *name;
> +};
> +
> +struct max14001_state {
> +	const struct max14001_chip_info *chip_info;
> +	struct spi_device *spi;
> +	int vref_mv;
> +
> +	__be16 rx_buffer __aligned(IIO_DMA_MINALIGN);
> +	__be16 tx_buffer;

I'd add a comment on these to mention they are also bit
reversed after we've flipped the bytes to be in the right order.

> +};
> +
> +static struct max14001_chip_info max14001_chip_info_tbl[] = {
> +	[max14001] = {
> +		.name = "max14001",
> +	},
> +	[max14002] = {
> +		.name = "max14002",
> +	},
> +};
> +
> +static int max14001_spi_read(struct max14001_state *st, u16 reg, int *val)

The register map is large enough I'd consider using a custom regmap
as then we can take advantage of caching and the field manipulation
functions that we get from regmap.

> +{
> +	struct spi_transfer xfer[] = {
> +		{
> +			.tx_buf = &st->tx_buffer,
> +			.len = sizeof(st->tx_buffer),
> +			.cs_change = 1,
> +		},
> +		{
> +			.rx_buf = &st->rx_buffer,
> +			.len = sizeof(st->rx_buffer),
> +		},
> +	};
> +	int ret;
> +

No locking? Given use of shared buffers I would suggest you need
a mutex here, the bus lock won't be enough.

> +	st->tx_buffer = FIELD_PREP(MAX14001_MASK_ADDR, reg) |
> +			FIELD_PREP(MAX14001_MASK_WR, MAX14001_REG_READ);
> +	st->tx_buffer = bitrev16(st->tx_buffer);
> +
> +	ret = spi_sync_transfer(st->spi, xfer, ARRAY_SIZE(xfer));
> +	if (ret < 0)
> +		return ret;
> +
> +	st->rx_buffer = bitrev16(be16_to_cpu(st->rx_buffer));
> +	*val = FIELD_GET(MAX14001_MASK_DATA, st->rx_buffer);
> +
> +	return 0;
> +}


> +static const struct spi_device_id max14001_id_table[] = {
> +	{ "max14001", (kernel_ulong_t)&max14001_chip_info_tbl[max14001] },
> +	{ "max14002", (kernel_ulong_t)&max14001_chip_info_tbl[max14002] },
> +	{}

Trivial but for consistency
	{ }

which is the preferred style in IIO.  There isn't any general agreement
across the kernel so I picked a choice at random a while back as any choice
is better than a mix like we have here.

> +};
> +MODULE_DEVICE_TABLE(spi, max14001_id_table);
> +
> +static const struct of_device_id max14001_of_match[] = {
> +	{ .compatible = "adi,max14001",
> +	  .data = &max14001_chip_info_tbl[max14001], },
> +	{ .compatible = "adi,max14002",
> +	  .data = &max14001_chip_info_tbl[max14002], },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, max14001_of_match);


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ