From: Rodrigo Alencar via B4 Relay <devnull+rodrigo.alencar.analog.com@kernel.org>
To: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
Stefan Popa <stefan.popa@analog.com>,
Jonathan Cameron <jic23@cam.ac.uk>,
Greg Kroah-Hartman <gregkh@suse.de>,
Michael Auchter <michael.auchter@ni.com>,
Jonathan Cameron <jic23@kernel.org>
Cc: Lars-Peter Clausen <lars@metafoo.de>,
Michael Hennerich <Michael.Hennerich@analog.com>,
Jonathan Cameron <jic23@kernel.org>,
David Lechner <dlechner@baylibre.com>,
Andy Shevchenko <andy@kernel.org>,
Rodrigo Alencar <rodrigo.alencar@analog.com>
Subject: [PATCH 05/10] iio: dac: ad5686: fix ref bit initialization for single-channel parts
Date: Sun, 26 Apr 2026 09:38:06 +0100 [thread overview]
Message-ID: <20260426-ad5686-fixes-v1-5-7c946a77794e@analog.com> (raw)
In-Reply-To: <20260426-ad5686-fixes-v1-0-7c946a77794e@analog.com>
From: Rodrigo Alencar <rodrigo.alencar@analog.com>
For single-channel parts the control register is used to enable the
internal voltage reference and perform powerdown control. The reference
enable bit position was ignored when writing the register at the probe
function (!!val was used). This patch adds a control_sync() function that
properly consumes the mask definitions with FIELD_PREP(). As further
cleanup, the created functions and definitions are also used in
ad5686_write_dac_powerdown(). Some local variables ended up being unused
(so removed) and st->use_internal_vref is initialized earlier in probe,
because it is also applicable to the AD5686_REGMAP case.
Fixes: be1b24d24541 ("iio:dac:ad5686: Add AD5691R/AD5692R/AD5693/AD5693R support")
Signed-off-by: Rodrigo Alencar <rodrigo.alencar@analog.com>
---
drivers/iio/dac/ad5686.c | 89 ++++++++++++++++++++++++++++--------------------
drivers/iio/dac/ad5686.h | 3 +-
2 files changed, 54 insertions(+), 38 deletions(-)
diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c
index e67faef91164..843e425f656f 100644
--- a/drivers/iio/dac/ad5686.c
+++ b/drivers/iio/dac/ad5686.c
@@ -6,11 +6,13 @@
*/
#include <linux/array_size.h>
+#include <linux/bitfield.h>
#include <linux/err.h>
#include <linux/export.h>
#include <linux/module.h>
#include <linux/regulator/consumer.h>
#include <linux/sysfs.h>
+#include <linux/wordpart.h>
#include "ad5686.h"
@@ -20,6 +22,24 @@ static const char * const ad5686_powerdown_modes[] = {
"three_state"
};
+static int ad5310_control_sync(struct ad5686_state *st)
+{
+ unsigned int pd_val = st->pwr_down_mask & st->pwr_down_mode;
+
+ return st->write(st, AD5686_CMD_CONTROL_REG, 0,
+ FIELD_PREP(AD5310_PD_MSK, pd_val) |
+ FIELD_PREP(AD5310_REF_BIT_MSK, st->use_internal_vref ? 0 : 1));
+}
+
+static int ad5683_control_sync(struct ad5686_state *st)
+{
+ unsigned int pd_val = st->pwr_down_mask & st->pwr_down_mode;
+
+ return st->write(st, AD5686_CMD_CONTROL_REG, 0,
+ FIELD_PREP(AD5683_PD_MSK, pd_val) |
+ FIELD_PREP(AD5683_REF_BIT_MSK, st->use_internal_vref ? 0 : 1));
+}
+
static int ad5686_get_powerdown_mode(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan)
{
@@ -65,8 +85,8 @@ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev,
bool readin;
int ret;
struct ad5686_state *st = iio_priv(indio_dev);
- unsigned int val, ref_bit_msk;
- u8 shift, address = 0;
+ unsigned int val;
+ u8 address;
ret = kstrtobool(buf, &readin);
if (ret)
@@ -79,32 +99,34 @@ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev,
switch (st->chip_info->regmap_type) {
case AD5310_REGMAP:
- shift = 9;
- ref_bit_msk = AD5310_REF_BIT_MSK;
+ ret = ad5310_control_sync(st);
+ if (ret)
+ return ret;
break;
case AD5683_REGMAP:
- shift = 13;
- ref_bit_msk = AD5683_REF_BIT_MSK;
+ ret = ad5683_control_sync(st);
+ if (ret)
+ return ret;
break;
case AD5686_REGMAP:
- shift = 0;
- ref_bit_msk = 0;
/* AD5674R/AD5679R have 16 channels and 2 powerdown registers */
- if (chan->channel > 0x7)
+ val = st->pwr_down_mask & st->pwr_down_mode;
+ if (chan->channel > 0x7) {
address = 0x8;
+ val = upper_16_bits(val);
+ } else {
+ address = 0x0;
+ val = lower_16_bits(val);
+ }
+ ret = st->write(st, AD5686_CMD_POWERDOWN_DAC, address, val);
+ if (ret)
+ return ret;
break;
default:
return -EINVAL;
}
- val = ((st->pwr_down_mask & st->pwr_down_mode) << shift);
- if (!st->use_internal_vref)
- val |= ref_bit_msk;
-
- ret = st->write(st, AD5686_CMD_POWERDOWN_DAC,
- address, val >> (address * 2));
-
- return ret ? ret : len;
+ return len;
}
static int ad5686_read_raw(struct iio_dev *indio_dev,
@@ -416,11 +438,8 @@ int ad5686_probe(struct device *dev,
const char *name, ad5686_write_func write,
ad5686_read_func read)
{
- struct ad5686_state *st;
struct iio_dev *indio_dev;
- unsigned int val, ref_bit_msk;
- bool has_external_vref;
- u8 cmd;
+ struct ad5686_state *st;
int ret, i;
indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
@@ -438,8 +457,8 @@ int ad5686_probe(struct device *dev,
if (ret < 0 && ret != -ENODEV)
return ret;
- has_external_vref = ret != -ENODEV;
- st->vref_mv = has_external_vref ? ret / 1000 : st->chip_info->int_vref_mv;
+ st->use_internal_vref = ret == -ENODEV;
+ st->vref_mv = st->use_internal_vref ? st->chip_info->int_vref_mv : ret / 1000;
/* Set all the power down mode for all channels to 1K pulldown */
for (i = 0; i < st->chip_info->num_channels; i++)
@@ -457,29 +476,25 @@ int ad5686_probe(struct device *dev,
switch (st->chip_info->regmap_type) {
case AD5310_REGMAP:
- cmd = AD5686_CMD_CONTROL_REG;
- ref_bit_msk = AD5310_REF_BIT_MSK;
- st->use_internal_vref = !has_external_vref;
+ ret = ad5310_control_sync(st);
+ if (ret)
+ return ret;
break;
case AD5683_REGMAP:
- cmd = AD5686_CMD_CONTROL_REG;
- ref_bit_msk = AD5683_REF_BIT_MSK;
- st->use_internal_vref = !has_external_vref;
+ ret = ad5683_control_sync(st);
+ if (ret)
+ return ret;
break;
case AD5686_REGMAP:
- cmd = AD5686_CMD_INTERNAL_REFER_SETUP;
- ref_bit_msk = 0;
+ ret = st->write(st, AD5686_CMD_INTERNAL_REFER_SETUP, 0,
+ st->use_internal_vref ? 0 : 1);
+ if (ret)
+ return ret;
break;
default:
return -EINVAL;
}
- val = (has_external_vref | ref_bit_msk);
-
- ret = st->write(st, cmd, 0, !!val);
- if (ret)
- return ret;
-
return devm_iio_device_register(dev, indio_dev);
}
EXPORT_SYMBOL_NS_GPL(ad5686_probe, "IIO_AD5686");
diff --git a/drivers/iio/dac/ad5686.h b/drivers/iio/dac/ad5686.h
index 6e3552c92e4b..7004d0d1d97a 100644
--- a/drivers/iio/dac/ad5686.h
+++ b/drivers/iio/dac/ad5686.h
@@ -44,8 +44,9 @@
#define AD5686_CMD_READBACK_ENABLE_V2 0x5
#define AD5310_REF_BIT_MSK BIT(8)
+#define AD5310_PD_MSK GENMASK(10, 9)
#define AD5683_REF_BIT_MSK BIT(12)
-
+#define AD5683_PD_MSK GENMASK(14, 13)
enum ad5686_regmap_type {
AD5310_REGMAP,
--
2.43.0
next prev parent reply other threads:[~2026-04-26 8:38 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-26 8:38 [PATCH 00/10] Fixes and cleanups for the AD5686 IIO driver Rodrigo Alencar via B4 Relay
2026-04-26 8:38 ` [PATCH 01/10] iio: dac: ad5686: refactor include headers Rodrigo Alencar via B4 Relay
2026-04-26 13:29 ` Jonathan Cameron
2026-04-26 8:38 ` [PATCH 02/10] iio: dac: ad5686: remove redundant register definition Rodrigo Alencar via B4 Relay
2026-04-26 13:32 ` Jonathan Cameron
2026-04-26 13:38 ` Jonathan Cameron
2026-04-27 10:09 ` Rodrigo Alencar
2026-04-27 10:25 ` Jonathan Cameron
2026-04-26 8:38 ` [PATCH 03/10] iio: dac: ad5686: drop enum id Rodrigo Alencar via B4 Relay
2026-04-26 13:35 ` Jonathan Cameron
2026-04-26 8:38 ` [PATCH 04/10] iio: dac: ad5686: add of_match table to the spi driver Rodrigo Alencar via B4 Relay
2026-04-26 13:37 ` Jonathan Cameron
2026-04-26 8:38 ` Rodrigo Alencar via B4 Relay [this message]
2026-04-26 13:44 ` [PATCH 05/10] iio: dac: ad5686: fix ref bit initialization for single-channel parts Jonathan Cameron
2026-04-26 8:38 ` [PATCH 06/10] iio: dac: ad5686: acquire lock when doing powerdown control Rodrigo Alencar via B4 Relay
2026-04-26 13:47 ` Jonathan Cameron
2026-04-26 8:38 ` [PATCH 07/10] iio: dac: ad5686: fix powerdown control on dual-channel devices Rodrigo Alencar via B4 Relay
2026-04-26 13:48 ` Jonathan Cameron
2026-04-26 8:38 ` [PATCH 08/10] iio: dac: ad5686: fix input raw value check Rodrigo Alencar via B4 Relay
2026-04-26 13:49 ` Jonathan Cameron
2026-04-26 8:38 ` [PATCH 09/10] iio: dac: ad5686: cleanup doc header of local structs Rodrigo Alencar via B4 Relay
2026-04-26 8:38 ` [PATCH 10/10] iio: dac: ad5686: create bus ops struct Rodrigo Alencar via B4 Relay
2026-04-26 13:50 ` 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=20260426-ad5686-fixes-v1-5-7c946a77794e@analog.com \
--to=devnull+rodrigo.alencar.analog.com@kernel.org \
--cc=Michael.Hennerich@analog.com \
--cc=andy@kernel.org \
--cc=dlechner@baylibre.com \
--cc=gregkh@suse.de \
--cc=jic23@cam.ac.uk \
--cc=jic23@kernel.org \
--cc=lars@metafoo.de \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=michael.auchter@ni.com \
--cc=rodrigo.alencar@analog.com \
--cc=stefan.popa@analog.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®