All of lore.kernel.org
 help / color / mirror / Atom feed
From: Joshua Crofts <joshua.crofts1@gmail.com>
To: Marcin Bis <marcin@bis-linux.com>
Cc: linux-iio@vger.kernel.org
Subject: Re: [PATCH 1/2] iio: dac: ad5337: Add driver for the AD5337 DAC
Date: Fri, 12 Jun 2026 16:20:22 +0200	[thread overview]
Message-ID: <20260612162022.00003e66@gmail.com> (raw)
In-Reply-To: <20260612133125.196208-1-marcin@bis-linux.com>

On Fri, 12 Jun 2026 15:31:21 +0200
Marcin Bis <marcin@bis-linux.com> wrote:

> Add driver for the AD5337 dual 8-bit I2C voltage-output DAC.
> This part uses the pointer-byte protocol and is not compatible with
> the AD5337R nanoDAC+ driver (adi,ad5337r).
> 
> Signed-off-by: Marcin Bis <marcin@bis-linux.com>
> ---
>  MAINTAINERS              |   5 ++
>  drivers/iio/dac/Kconfig  |  12 ++-
>  drivers/iio/dac/Makefile |   1 +
>  drivers/iio/dac/ad5337.c | 159 +++++++++++++++++++++++++++++++++++++++
>  4 files changed, 176 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/iio/dac/ad5337.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index e035a3be797c..614589b6efa4 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -438,6 +438,11 @@ W:	http://wiki.analog.com/AD5398
>  W:	https://ez.analog.com/linux-software-drivers
>  F:	drivers/regulator/ad5398.c
>  
> +AD5337  ANALOG DEVICES INC AD5337 DAC DRIVER
> +M:	Marcin Bis <marcin@bis-linux.com>
> +S:	Maintained
> +F:	drivers/iio/dac/ad5337.c

Once you reorder your patches, this should go into the (first)
dt-binding patch.

> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Analog Devices AD5337 I2C DAC driver
> + *
> + * Copyright 2017 Marcin Bis <marcin@bis-linux.com>
> + */
> +
> +#include <linux/i2c.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/regulator/consumer.h>

You're definitely missing array_size.h, types.h, mod_devicetable.h
and err.h.

> +#include <linux/iio/iio.h>
> +
> +#define AD5337_NUM_CHANNELS	2
> +#define AD5337_RESOLUTION	8
> +/*
> + * AD5338 - 10bit, AD5339 - 12bit
> + */

This comment can just be on one line.

> +
> +#define AD5337_PTR_DAC_A	0x01
> +#define AD5337_PTR_DAC_B	0x02
> +
> +struct ad5337_state {
> +	struct i2c_client *client;
> +	struct mutex lock;

Add a comment on why you need a mutex.

> +	unsigned int vref_mv;
> +	u8 cache[AD5337_NUM_CHANNELS];
> +};
> +
> +static int ad5337_write_dac(struct ad5337_state *st, int channel, u8 value)
> +{
> +	u8 buf[3];
> +	int ret;
> +
> +	if (channel)
> +		buf[0] = AD5337_PTR_DAC_B;
> +	else
> +		buf[0] = AD5337_PTR_DAC_A;
> +
> +	/* PD1=0, PD0=0, CLR=1, LDAC=0, D[7:4] */
> +	buf[1] = 0x20 | (value >> 4);
> +	buf[2] = (value & 0x0f) << 4;

You should definitely use FIELD_GET/FIELD_PREP macros from the 
<linux/bitfield.h> header, it improves readability by a lot!

Also, use macros instead of just defining magic numbers like this.

> +
> +	ret = i2c_master_send(st->client, buf, 3);

Use sizeof(buf) instead of just hardcoding the size.

> +
> +	return (ret < 0) ? ret : (ret == 3 ? 0 : -EIO);

I'd definitely abandon using a terniary operator and just break it into
if statements, on first glance this is really hard to read.

> +}
> +
> +static int ad5337_read_raw(struct iio_dev *indio_dev,
> +			   struct iio_chan_spec const *chan,
> +			   int *val, int *val2, long mask)
> +{
> +	struct ad5337_state *st = iio_priv(indio_dev);
> +
> +	switch (mask) {
> +	case IIO_CHAN_INFO_RAW:
> +		*val = st->cache[chan->channel];
> +		return IIO_VAL_INT;
> +	case IIO_CHAN_INFO_SCALE:
> +		*val = st->vref_mv;
> +		*val2 = AD5337_RESOLUTION;
> +		return IIO_VAL_FRACTIONAL_LOG2;
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static int ad5337_write_raw(struct iio_dev *indio_dev,
> +			    struct iio_chan_spec const *chan,
> +			    int val, int val2, long mask)
> +{
> +	struct ad5337_state *st = iio_priv(indio_dev);
> +	int ret;
> +
> +	if (mask != IIO_CHAN_INFO_RAW)
> +		return -EINVAL;
> +
> +	if (val < 0 || val > ((1 << AD5337_RESOLUTION) - 1))
> +		return -EINVAL;
> +
> +	mutex_lock(&st->lock);

Consider using the guard(mutex)() macro from cleanup.h, it saves lines
and prevents future developers from accidentally forgetting to release
locks (don't forget to add the header as well though)!

> +	ret = ad5337_write_dac(st, chan->channel, val);
> +	if (!ret)
> +		st->cache[chan->channel] = val;
> +	mutex_unlock(&st->lock);
> +
> +	return ret;
> +}
> +
> +static const struct iio_info ad5337_info = {
> +	.read_raw = ad5337_read_raw,
> +	.write_raw = ad5337_write_raw,
> +};
> +
> +#define AD5337_CHANNEL(_chan) {						\

A very tiny nitpick, but you don't need to align your backslashes when defining
a macro.

> +	.type = IIO_VOLTAGE,						\
> +	.indexed = 1,							\
> +	.output = 1,							\
> +	.channel = (_chan),						\
> +	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),			\
> +	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),		\
> +}
> +
> +static const struct iio_chan_spec ad5337_channels[] = {
> +	AD5337_CHANNEL(0),
> +	AD5337_CHANNEL(1),
> +};
> +
> +static int ad5337_probe(struct i2c_client *client)
> +{
> +	struct ad5337_state *st;
> +	struct iio_dev *indio_dev;

Very much a nit, but swap these lines.

> +	int ret;
> +
> +	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
> +		return -ENODEV;
> +
> +	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
> +	if (!indio_dev)
> +		return -ENOMEM;
> +
> +	st = iio_priv(indio_dev);
> +	st->client = client;
> +	mutex_init(&st->lock);

Use devm_mutex_init().

> +
> +	ret = devm_regulator_get_enable_read_voltage(&client->dev, "vcc");
> +	if (ret < 0 && ret != -ENODEV)
> +		return ret;

Return dev_err_probe() here.

> +
> +	st->vref_mv = ret > 0 ? ret / 1000 : 3300;

More magic numbers. If you're converting units, consider using
macros from <linux/units.h>.

-- 
Kind regards

CJD

  parent reply	other threads:[~2026-06-12 14:20 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-12 13:31 [PATCH 1/2] iio: dac: ad5337: Add driver for the AD5337 DAC Marcin Bis
2026-06-12 13:31 ` [PATCH 2/2] dt-bindings: iio: dac: adi,ad5337: add dt-bindings Marcin Bis
2026-06-12 13:58   ` Joshua Crofts
2026-06-12 17:09   ` Jonathan Cameron
2026-06-12 14:20 ` Joshua Crofts [this message]
2026-06-12 17:27 ` [PATCH 1/2] iio: dac: ad5337: Add driver for the AD5337 DAC Jonathan Cameron

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=20260612162022.00003e66@gmail.com \
    --to=joshua.crofts1@gmail.com \
    --cc=linux-iio@vger.kernel.org \
    --cc=marcin@bis-linux.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.