public inbox for linux-arm-kernel@lists.infradead.org
 help / color / mirror / Atom feed
From: Andy Shevchenko <andriy.shevchenko@intel.com>
To: rva333@protonmail.com
Cc: "Jonathan Cameron" <jic23@kernel.org>,
	"David Lechner" <dlechner@baylibre.com>,
	"Nuno Sá" <nuno.sa@analog.com>,
	"Andy Shevchenko" <andy@kernel.org>,
	"Rob Herring" <robh@kernel.org>,
	"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
	"Conor Dooley" <conor+dt@kernel.org>,
	"Matthias Brugger" <matthias.bgg@gmail.com>,
	"AngeloGioacchino Del Regno"
	<angelogioacchino.delregno@collabora.com>,
	"Srinivas Kandagatla" <srini@kernel.org>,
	"Rafael J. Wysocki" <rafael@kernel.org>,
	"Daniel Lezcano" <daniel.lezcano@kernel.org>,
	"Zhang Rui" <rui.zhang@intel.com>,
	"Lukasz Luba" <lukasz.luba@arm.com>, "Lee Jones" <lee@kernel.org>,
	linux-iio@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-mediatek@lists.infradead.org, linux-pm@vger.kernel.org,
	"Ben Grisdale" <bengris32@protonmail.ch>
Subject: Re: [PATCH 04/13] iio: adc: mediatek: add mt6323 PMIC AUXADC driver
Date: Tue, 5 May 2026 10:53:19 +0300	[thread overview]
Message-ID: <afmh70niEmjl53g9@ashevche-desk.local> (raw)
In-Reply-To: <20260504-mt6323-v1-4-799b58b355ff@protonmail.com>

On Mon, May 04, 2026 at 09:24:56PM +0300, Roman Vivchar via B4 Relay wrote:

> The mt6323 AUXADC is a 15-bit ADC used for system monitoring. This driver
> provides support for reading various channels including battery and
> charger voltages, battery and chip temperature, current sensing and
> accessory detection.
> 
> Add a driver for the AUXADC found in the MediaTek mt6323 PMIC.

...

> +#include <linux/bitfield.h>
> +#include <linux/bits.h>
> +#include <linux/cleanup.h>
> +#include <linux/delay.h>
> +#include <linux/iio/iio.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/property.h>
> +#include <linux/regmap.h>
> +#include <linux/types.h>

Follow IWYU. At least stringify.h is missing.

...

> +#define MTK_PMIC_IIO_CHAN(_name, _idx, _ch_type) \
> +	{ .type = _ch_type,                              \
> +	  .indexed = 1,                                  \
> +	  .channel = _idx,                               \
> +	  .address = _idx,                               \
> +	  .datasheet_name = __stringify(_name),          \
> +	  .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
> +				BIT(IIO_CHAN_INFO_SCALE) }

Make {} each to occupy a single line.

...

> +/**
> + * struct mt6323_auxadc - Main driver structure
> + * @dev:           Device pointer
> + * @regmap:        Regmap from PWRAP
> + * @lock:          Mutex to serialize AUXADC reading vs configuration

 *
 * ...put struct decription here... See below why.
 *

> + */
> +struct mt6323_auxadc {
> +	struct device *dev;
> +	struct regmap *regmap;

Do you need both? Are they different? (I mean that regmap may be derived from
device and vice versa depending on the case.)

Ok, it seems the dev is the current platform device, while regmap comes from
parent->parent to it (2 levels up!). This needs a good comment in the struct
description explaining the hierarchy.

> +	struct mutex lock;
> +};

...

> +static int mt6323_auxadc_check_if_stuck(struct mt6323_auxadc *auxadc)
> +{
> +	int i, ret;

Why is 'i' signed?

> +	u32 val;
> +
> +	for (i = 0; i < 50; i++) {

Magic 50 and the whole thing is reinvention of something from iopoll.h.

> +		ret = regmap_read(auxadc->regmap, MT6323_AUXADC_CON19, &val);
> +		if (ret)
> +			return ret;
> +
> +		if (FIELD_GET(AUXADC_DECI_GDLY_MASK, val)) {
> +			ret = regmap_read(auxadc->regmap, MT6323_AUXADC_ADC19,
> +					  &val);
> +			if (ret)
> +				return ret;
> +
> +			if (!FIELD_GET(AUXADC_ADC19_BUSY_MASK, val)) {
> +				ret = regmap_update_bits(

Bad indentation, there is a room for parameter on the previous line.

> +					auxadc->regmap, MT6323_AUXADC_CON19,
> +					FIELD_PREP(AUXADC_DECI_GDLY_MASK, 3),
> +					0x0);
> +				if (ret)
> +					return ret;
> +			}
> +		} else {
> +			return 0;
> +		}
> +
> +		fsleep(10);
> +	}
> +
> +	return -ETIMEDOUT;
> +}

TL;DR: Find a suitable macro in iopoll.h and use it.

...

> +static int mt6323_auxadc_request(struct mt6323_auxadc *auxadc,
> +				 unsigned long channel)
> +{
> +	int ret;
> +	u32 pmic_val, adc_val;
> +
> +	if (channel < 9) {
> +		ret = regmap_update_bits(auxadc->regmap, MT6323_AUXADC_CON11,
> +					 AUXADC_VBUF_EN, AUXADC_VBUF_EN);
> +		if (ret)
> +			return ret;
> +
> +		ret = regmap_read(auxadc->regmap, MT6323_AUXADC_CON22,
> +				  &pmic_val);
> +		if (ret)
> +			return ret;
> +
> +		adc_val = FIELD_GET(AUXADC_LOW_CHANNEL_MASK, pmic_val);
> +		adc_val &= ~BIT(channel);

We also have FIELD_MODIFY(). Use it in all cases where appropriate.

> +		ret = regmap_update_bits(auxadc->regmap, MT6323_AUXADC_CON22,
> +					 AUXADC_LOW_CHANNEL_MASK, adc_val);
> +		if (ret)
> +			return ret;
> +
> +		ret = regmap_read(auxadc->regmap, MT6323_AUXADC_CON22,
> +				  &pmic_val);
> +		if (ret)
> +			return ret;
> +
> +		adc_val = FIELD_GET(AUXADC_LOW_CHANNEL_MASK, pmic_val);
> +		adc_val |= BIT(channel);
> +
> +		ret = regmap_update_bits(auxadc->regmap, MT6323_AUXADC_CON22,
> +					 AUXADC_LOW_CHANNEL_MASK, adc_val);

> +

Stray blank line.

> +	} else {

Redundant 'else' as this may be returned directly. So, refactor each branch to
a helper and use this as a small wrapper.

	if (channel < 9)
		return ...helper_for_chan_<_9...;

	return ...otherwise...;

> +		ret = regmap_read(auxadc->regmap, MT6323_AUXADC_CON23,
> +				  &pmic_val);
> +		if (ret)
> +			return ret;
> +
> +		adc_val = FIELD_GET(AUXADC_AUDIO_CHANNEL_MASK, pmic_val);
> +		adc_val &= ~BIT(channel - 9);
> +
> +		ret = regmap_update_bits(auxadc->regmap, MT6323_AUXADC_CON23,
> +					 AUXADC_AUDIO_CHANNEL_MASK, adc_val);
> +		if (ret)
> +			return ret;
> +
> +		ret = regmap_read(auxadc->regmap, MT6323_AUXADC_CON23,
> +				  &pmic_val);
> +		if (ret)
> +			return ret;
> +
> +		adc_val = FIELD_GET(AUXADC_AUDIO_CHANNEL_MASK, pmic_val);
> +		adc_val |= BIT(channel - 9);
> +
> +		ret = regmap_update_bits(auxadc->regmap, MT6323_AUXADC_CON23,
> +					 AUXADC_AUDIO_CHANNEL_MASK, adc_val);
> +	}
> +
> +	return ret;
> +}

...

> +static int mt6323_auxadc_read(struct mt6323_auxadc *auxadc,
> +			      const struct iio_chan_spec *chan, int *out)
> +{
> +	int ret;
> +	u32 reg = mt6323_auxadc_channel_to_reg(chan->address);
> +	u32 val;
> +
> +	ret = regmap_read_poll_timeout(auxadc->regmap, reg, val,
> +				       (val & AUXADC_RDY_MASK), 1000, 100000);

Redundant parentheses, also use multipliers from time.h

	struct regmap *map = ... // use this trick elsewhere as well

	ret = regmap_read_poll_timeout(map, reg, val, val & AUXADC_RDY_MASK,
				       1 * USEC_PER_MSEC, 100 * USEC_PER_MSEC);

> +	if (ret)
> +		return ret;
> +
> +	*out = FIELD_GET(AUXADC_DATA_MASK, val);
> +
> +	return 0;
> +}

...

> +static int mt6323_auxadc_read_raw(struct iio_dev *indio_dev,
> +				  const struct iio_chan_spec *chan, int *val,
> +				  int *val2, long mask)
> +{
> +	struct mt6323_auxadc *auxadc = iio_priv(indio_dev);
> +	int ret, mult = 1;
> +
> +	if (mask == IIO_CHAN_INFO_RAW) {
> +		scoped_guard(mutex, &auxadc->lock)
> +		{

Why? It's not a switch-case, the guard()() should be fine.

> +			ret = mt6323_auxadc_check_if_stuck(auxadc);
> +			if (ret)
> +				return ret;
> +
> +			ret = mt6323_auxadc_request(auxadc, chan->address);
> +			if (ret)
> +				return ret;
> +
> +			usleep_range(300, 500);

We have fsleep().

> +			ret = mt6323_auxadc_read(auxadc, chan, val);
> +			if (ret)
> +				return ret;
> +			return IIO_VAL_INT;
> +		}
> +	} else if (mask == IIO_CHAN_INFO_SCALE) {
> +		if (chan->channel == MT6323_AUXADC_ISENSE ||
> +		    chan->address == MT6323_AUXADC_BATSNS)
> +			mult = 4;
> +
> +		*val = mult * 1800;
> +		*val2 = 32768;
> +
> +		return IIO_VAL_FRACTIONAL;
> +	} else
> +		return -EINVAL;
> +}

...

> +	ret = regmap_update_bits(auxadc->regmap, MT6323_AUXADC_CON10,
> +				 AUXADC_TRIM_CH2 | AUXADC_TRIM_CH4 |
> +					 AUXADC_TRIM_CH5 | AUXADC_TRIM_CH6,
> +				 AUXADC_TRIM_CH2 | AUXADC_TRIM_CH4 |
> +					 AUXADC_TRIM_CH5 | AUXADC_TRIM_CH6);
> +	if (ret)
> +		return ret;

We have _set_bits()/_clear_bits()/_assign_bits() of regmap API. Use them here
and in many other cases in this driver (and probably in the entire series.
I'm not going to comment each of the cases.

...

> +static int mt6323_auxadc_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct mt6323_auxadc *auxadc;
> +	struct iio_dev *iio;
> +	struct regmap *regmap;
> +	int ret;
> +
> +	/* mfd->pwrap regmap */
> +	regmap = dev_get_regmap(dev->parent->parent, NULL);
> +	if (!regmap)
> +		return dev_err_probe(dev, -ENODEV, "failed to get regmap\n");
> +
> +	iio = devm_iio_device_alloc(dev, sizeof(*auxadc));
> +	if (!iio)
> +		return -ENOMEM;
> +
> +	auxadc = iio_priv(iio);
> +	auxadc->regmap = regmap;
> +	auxadc->dev = dev;

> +	mutex_init(&auxadc->lock);

devm.

> +	ret = mt6323_auxadc_init(auxadc);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "failed to initialize auxadc\n");
> +
> +	iio->name = "mt6323-auxadc";
> +	iio->info = &mt6323_auxadc_iio_info;
> +	iio->modes = INDIO_DIRECT_MODE;
> +	iio->channels = mt6323_auxadc_channels;
> +	iio->num_channels = ARRAY_SIZE(mt6323_auxadc_channels);
> +
> +	ret = devm_iio_device_register(dev, iio);
> +	if (ret)

> +		return dev_err_probe(dev, ret,
> +				     "failed to register iio device\n");

One line

> +	return 0;
> +}

...

> +static const struct of_device_id mt6323_auxadc_of_match[] = {
> +	{ .compatible = "mediatek,mt6323-auxadc" },
> +	{}


IIRC we use { } (with space) in IIO for the terminator entry in ID tables.

> +};

-- 
With Best Regards,
Andy Shevchenko




  reply	other threads:[~2026-05-05  7:53 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-04 18:24 [PATCH 00/13] add AUXADC, EFUSE and thermal drivers for the MediaTek mt6323 PMIC Roman Vivchar via B4 Relay
2026-05-04 18:24 ` [PATCH 01/13] dt-bindings: iio: adc: add mt6323 PMIC AUXADC Roman Vivchar via B4 Relay
2026-05-04 18:24 ` [PATCH 02/13] dt-bindings: nvmem: add mt6323 PMIC EFUSE Roman Vivchar via B4 Relay
2026-05-04 18:24 ` [PATCH 03/13] dt-bindings: thermal: add mt6323 PMIC thermal Roman Vivchar via B4 Relay
2026-05-04 19:41   ` Rob Herring (Arm)
2026-05-05 14:05   ` Rob Herring
2026-05-04 18:24 ` [PATCH 04/13] iio: adc: mediatek: add mt6323 PMIC AUXADC driver Roman Vivchar via B4 Relay
2026-05-05  7:53   ` Andy Shevchenko [this message]
2026-05-04 18:24 ` [PATCH 05/13] nvmem: add mt6323 PMIC EFUSE driver Roman Vivchar via B4 Relay
2026-05-05  7:59   ` Andy Shevchenko
2026-05-05 16:24     ` Roman Vivchar
2026-05-04 18:24 ` [PATCH 06/13] thermal: mediatek: add pmic thermal support Roman Vivchar via B4 Relay
2026-05-05  8:16   ` Andy Shevchenko
2026-05-04 18:24 ` [PATCH 07/13] mfd: mt6397-core: add mt6323 AUXADC support Roman Vivchar via B4 Relay
2026-05-04 18:25 ` [PATCH 08/13] mfd: mt6397-core: add support for mt6323 efuse Roman Vivchar via B4 Relay
2026-05-04 18:25 ` [PATCH 09/13] mfd: mt6397-core: add support for mt6323 thermal Roman Vivchar via B4 Relay
2026-05-04 18:25 ` [PATCH 10/13] ARM: dts: mediatek: mt6323: add support for AUXADC Roman Vivchar via B4 Relay
2026-05-04 18:25 ` [PATCH 11/13] ARM: dts: mediatek: mt6323: add support for EFUSE Roman Vivchar via B4 Relay
2026-05-04 18:25 ` [PATCH 12/13] ARM: dts: mediatek: mt6323: add support for thermal Roman Vivchar via B4 Relay
2026-05-04 18:25 ` [PATCH 13/13] MAINTAINERS: add mt6323 drivers maintainer Roman Vivchar via B4 Relay

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=afmh70niEmjl53g9@ashevche-desk.local \
    --to=andriy.shevchenko@intel.com \
    --cc=andy@kernel.org \
    --cc=angelogioacchino.delregno@collabora.com \
    --cc=bengris32@protonmail.ch \
    --cc=conor+dt@kernel.org \
    --cc=daniel.lezcano@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dlechner@baylibre.com \
    --cc=jic23@kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=lee@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=lukasz.luba@arm.com \
    --cc=matthias.bgg@gmail.com \
    --cc=nuno.sa@analog.com \
    --cc=rafael@kernel.org \
    --cc=robh@kernel.org \
    --cc=rui.zhang@intel.com \
    --cc=rva333@protonmail.com \
    --cc=srini@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox