All supported drivers currently implicitly use two's complement mode.
Make this clear by declaring two's complement in the default
output mode. Calibration mode uses offset binary, so change the output
mode only when running the calibration or other test mode.
Signed-off-by: Tomas Melin <tomas.melin@vaisala.com>
---
drivers/iio/adc/ad9467.c | 33 +++++++++++++++++++++++++--------
1 file changed, 25 insertions(+), 8 deletions(-)
diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c
index 59c3fa3bcc9b0b8b36b78c3b54fd7977cae23496..60fc3361b2689a4c38287c613ef93fe00338e5fa 100644
--- a/drivers/iio/adc/ad9467.c
+++ b/drivers/iio/adc/ad9467.c
@@ -72,6 +72,7 @@
#define AN877_ADC_OUTPUT_MODE_OFFSET_BINARY 0x0
#define AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT 0x1
#define AN877_ADC_OUTPUT_MODE_GRAY_CODE 0x2
+#define AN877_ADC_OUTPUT_MODE_MASK GENMASK(1, 0)
/* AN877_ADC_REG_OUTPUT_PHASE */
#define AN877_ADC_OUTPUT_EVEN_ODD_MODE_EN 0x20
@@ -85,7 +86,7 @@
*/
#define CHIPID_AD9211 0x06
-#define AD9211_DEF_OUTPUT_MODE 0x00
+#define AD9211_DEF_OUTPUT_MODE 0x01
#define AD9211_REG_VREF_MASK GENMASK(4, 0)
/*
@@ -93,7 +94,7 @@
*/
#define CHIPID_AD9265 0x64
-#define AD9265_DEF_OUTPUT_MODE 0x40
+#define AD9265_DEF_OUTPUT_MODE 0x41
#define AD9265_REG_VREF_MASK 0xC0
/*
@@ -101,7 +102,7 @@
*/
#define CHIPID_AD9434 0x6A
-#define AD9434_DEF_OUTPUT_MODE 0x00
+#define AD9434_DEF_OUTPUT_MODE 0x01
#define AD9434_REG_VREF_MASK 0xC0
/*
@@ -109,7 +110,7 @@
*/
#define CHIPID_AD9467 0x50
-#define AD9467_DEF_OUTPUT_MODE 0x08
+#define AD9467_DEF_OUTPUT_MODE 0x09
#define AD9467_REG_VREF_MASK 0x0F
/*
@@ -117,6 +118,7 @@
*/
#define CHIPID_AD9643 0x82
+#define AD9643_DEF_OUTPUT_MODE 0x01
#define AD9643_REG_VREF_MASK 0x1F
/*
@@ -124,6 +126,7 @@
*/
#define CHIPID_AD9652 0xC1
+#define AD9652_DEF_OUTPUT_MODE 0x01
#define AD9652_REG_VREF_MASK 0xC0
/*
@@ -131,6 +134,7 @@
*/
#define CHIPID_AD9649 0x6F
+#define AD9649_DEF_OUTPUT_MODE 0x01
#define AD9649_TEST_POINTS 8
#define AD9647_MAX_TEST_POINTS 32
@@ -461,6 +465,7 @@ static const struct ad9467_chip_info ad9643_chip_tbl = {
.test_mask = BIT(AN877_ADC_TESTMODE_RAMP) |
GENMASK(AN877_ADC_TESTMODE_MIXED_BIT_FREQUENCY, AN877_ADC_TESTMODE_OFF),
.test_mask_len = AN877_ADC_TESTMODE_RAMP + 1,
+ .default_output_mode = AD9643_DEF_OUTPUT_MODE,
.vref_mask = AD9643_REG_VREF_MASK,
.has_dco = true,
.has_dco_invert = true,
@@ -479,6 +484,7 @@ static const struct ad9467_chip_info ad9649_chip_tbl = {
.test_mask = GENMASK(AN877_ADC_TESTMODE_MIXED_BIT_FREQUENCY,
AN877_ADC_TESTMODE_OFF),
.test_mask_len = AN877_ADC_TESTMODE_MIXED_BIT_FREQUENCY + 1,
+ .default_output_mode = AD9649_DEF_OUTPUT_MODE,
.has_dco = true,
.has_dco_invert = true,
.dco_en = AN877_ADC_DCO_DELAY_ENABLE,
@@ -496,6 +502,7 @@ static const struct ad9467_chip_info ad9652_chip_tbl = {
.test_mask = GENMASK(AN877_ADC_TESTMODE_ONE_ZERO_TOGGLE,
AN877_ADC_TESTMODE_OFF),
.test_mask_len = AN877_ADC_TESTMODE_ONE_ZERO_TOGGLE + 1,
+ .default_output_mode = AD9652_DEF_OUTPUT_MODE,
.vref_mask = AD9652_REG_VREF_MASK,
.has_dco = true,
};
@@ -671,10 +678,14 @@ static int ad9467_backend_testmode_off(struct ad9467_state *st,
static int ad9647_calibrate_prepare(struct ad9467_state *st)
{
+ unsigned int cmode;
unsigned int c;
int ret;
- ret = ad9467_outputmode_set(st, st->info->default_output_mode);
+ cmode = (st->info->default_output_mode & ~AN877_ADC_OUTPUT_MODE_MASK) |
+ FIELD_PREP(AN877_ADC_OUTPUT_MODE_MASK,
+ AN877_ADC_OUTPUT_MODE_OFFSET_BINARY);
+ ret = ad9467_outputmode_set(st, cmode);
if (ret)
return ret;
@@ -778,7 +789,7 @@ static int ad9647_calibrate_stop(struct ad9467_state *st)
return ret;
}
- mode = st->info->default_output_mode | AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT;
+ mode = st->info->default_output_mode;
return ad9467_outputmode_set(st, mode);
}
@@ -1174,12 +1185,18 @@ static ssize_t ad9467_chan_test_mode_write(struct file *file,
if (ret)
return ret;
- out_mode = st->info->default_output_mode | AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT;
+ out_mode = st->info->default_output_mode;
ret = ad9467_outputmode_set(st, out_mode);
if (ret)
return ret;
} else {
- ret = ad9467_outputmode_set(st, st->info->default_output_mode);
+ unsigned int cmode;
+
+ cmode = (st->info->default_output_mode &
+ ~AN877_ADC_OUTPUT_MODE_MASK) |
+ FIELD_PREP(AN877_ADC_OUTPUT_MODE_MASK,
+ AN877_ADC_OUTPUT_MODE_OFFSET_BINARY);
+ ret = ad9467_outputmode_set(st, cmode);
if (ret)
return ret;
--
2.47.3
Hi Tomas,
kernel test robot noticed the following build errors:
[auto build test ERROR on a7b10f0963c651a6406d958a5f64b9c5594f84da]
url: https://github.com/intel-lab-lkp/linux/commits/Tomas-Melin/iio-adc-ad9467-include-two-s-complement-in-default-mode/20251216-233841
base: a7b10f0963c651a6406d958a5f64b9c5594f84da
patch link: https://lore.kernel.org/r/20251216-b4-ad9467-optional-backend-v1-1-83e61531ef4d%40vaisala.com
patch subject: [PATCH 1/2] iio: adc: ad9467: include two's complement in default mode
config: sh-allmodconfig (https://download.01.org/0day-ci/archive/20251220/202512201109.STBoyjad-lkp@intel.com/config)
compiler: sh4-linux-gcc (GCC) 15.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251220/202512201109.STBoyjad-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202512201109.STBoyjad-lkp@intel.com/
All errors (new ones prefixed by >>):
drivers/iio/adc/ad9467.c: In function 'ad9647_calibrate_prepare':
>> drivers/iio/adc/ad9467.c:686:17: error: implicit declaration of function 'FIELD_PREP' [-Wimplicit-function-declaration]
686 | FIELD_PREP(AN877_ADC_OUTPUT_MODE_MASK,
| ^~~~~~~~~~
vim +/FIELD_PREP +686 drivers/iio/adc/ad9467.c
678
679 static int ad9647_calibrate_prepare(struct ad9467_state *st)
680 {
681 unsigned int cmode;
682 unsigned int c;
683 int ret;
684
685 cmode = (st->info->default_output_mode & ~AN877_ADC_OUTPUT_MODE_MASK) |
> 686 FIELD_PREP(AN877_ADC_OUTPUT_MODE_MASK,
687 AN877_ADC_OUTPUT_MODE_OFFSET_BINARY);
688 ret = ad9467_outputmode_set(st, cmode);
689 if (ret)
690 return ret;
691
692 for (c = 0; c < st->info->num_channels; c++) {
693 ret = ad9467_testmode_set(st, c, AN877_ADC_TESTMODE_PN9_SEQ);
694 if (ret)
695 return ret;
696
697 ret = ad9467_backend_testmode_on(st, c,
698 IIO_BACKEND_ADI_PRBS_9A);
699 if (ret)
700 return ret;
701 }
702
703 return 0;
704 }
705
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Hi Tomas,
kernel test robot noticed the following build errors:
[auto build test ERROR on a7b10f0963c651a6406d958a5f64b9c5594f84da]
url: https://github.com/intel-lab-lkp/linux/commits/Tomas-Melin/iio-adc-ad9467-include-two-s-complement-in-default-mode/20251216-233841
base: a7b10f0963c651a6406d958a5f64b9c5594f84da
patch link: https://lore.kernel.org/r/20251216-b4-ad9467-optional-backend-v1-1-83e61531ef4d%40vaisala.com
patch subject: [PATCH 1/2] iio: adc: ad9467: include two's complement in default mode
config: hexagon-allmodconfig (https://download.01.org/0day-ci/archive/20251220/202512201254.2FFxkibV-lkp@intel.com/config)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251220/202512201254.2FFxkibV-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202512201254.2FFxkibV-lkp@intel.com/
All errors (new ones prefixed by >>):
>> drivers/iio/adc/ad9467.c:686:3: error: call to undeclared function 'FIELD_PREP'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
686 | FIELD_PREP(AN877_ADC_OUTPUT_MODE_MASK,
| ^
drivers/iio/adc/ad9467.c:1197:4: error: call to undeclared function 'FIELD_PREP'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
1197 | FIELD_PREP(AN877_ADC_OUTPUT_MODE_MASK,
| ^
2 errors generated.
vim +/FIELD_PREP +686 drivers/iio/adc/ad9467.c
678
679 static int ad9647_calibrate_prepare(struct ad9467_state *st)
680 {
681 unsigned int cmode;
682 unsigned int c;
683 int ret;
684
685 cmode = (st->info->default_output_mode & ~AN877_ADC_OUTPUT_MODE_MASK) |
> 686 FIELD_PREP(AN877_ADC_OUTPUT_MODE_MASK,
687 AN877_ADC_OUTPUT_MODE_OFFSET_BINARY);
688 ret = ad9467_outputmode_set(st, cmode);
689 if (ret)
690 return ret;
691
692 for (c = 0; c < st->info->num_channels; c++) {
693 ret = ad9467_testmode_set(st, c, AN877_ADC_TESTMODE_PN9_SEQ);
694 if (ret)
695 return ret;
696
697 ret = ad9467_backend_testmode_on(st, c,
698 IIO_BACKEND_ADI_PRBS_9A);
699 if (ret)
700 return ret;
701 }
702
703 return 0;
704 }
705
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
On Tue, 16 Dec 2025 11:40:05 +0000
Tomas Melin <tomas.melin@vaisala.com> wrote:
> All supported drivers currently implicitly use two's complement mode.
> Make this clear by declaring two's complement in the default
> output mode. Calibration mode uses offset binary, so change the output
> mode only when running the calibration or other test mode.
>
> Signed-off-by: Tomas Melin <tomas.melin@vaisala.com>
A few comments inline, along with the obvious build error fix
from the bot report of including linux/bitfield.h
> ---
> drivers/iio/adc/ad9467.c | 33 +++++++++++++++++++++++++--------
> 1 file changed, 25 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c
> index 59c3fa3bcc9b0b8b36b78c3b54fd7977cae23496..60fc3361b2689a4c38287c613ef93fe00338e5fa 100644
> --- a/drivers/iio/adc/ad9467.c
> +++ b/drivers/iio/adc/ad9467.c
> @@ -671,10 +678,14 @@ static int ad9467_backend_testmode_off(struct ad9467_state *st,
>
> static int ad9647_calibrate_prepare(struct ad9467_state *st)
> {
> + unsigned int cmode;
> unsigned int c;
> int ret;
>
> - ret = ad9467_outputmode_set(st, st->info->default_output_mode);
> + cmode = (st->info->default_output_mode & ~AN877_ADC_OUTPUT_MODE_MASK) |
> + FIELD_PREP(AN877_ADC_OUTPUT_MODE_MASK,
> + AN877_ADC_OUTPUT_MODE_OFFSET_BINARY);
As below. Maybe copy then FIELD_MODIFY() the result.
> + ret = ad9467_outputmode_set(st, cmode);
> if (ret)
> return ret;
>
> @@ -778,7 +789,7 @@ static int ad9647_calibrate_stop(struct ad9467_state *st)
> return ret;
> }
>
> - mode = st->info->default_output_mode | AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT;
> + mode = st->info->default_output_mode;
> return ad9467_outputmode_set(st, mode);
> }
>
> @@ -1174,12 +1185,18 @@ static ssize_t ad9467_chan_test_mode_write(struct file *file,
> if (ret)
> return ret;
>
> - out_mode = st->info->default_output_mode | AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT;
> + out_mode = st->info->default_output_mode;
> ret = ad9467_outputmode_set(st, out_mode);
> if (ret)
> return ret;
> } else {
> - ret = ad9467_outputmode_set(st, st->info->default_output_mode);
> + unsigned int cmode;
> +
> + cmode = (st->info->default_output_mode &
> + ~AN877_ADC_OUTPUT_MODE_MASK) |
> + FIELD_PREP(AN877_ADC_OUTPUT_MODE_MASK,
> + AN877_ADC_OUTPUT_MODE_OFFSET_BINARY);
Might be cleaner as
unsigned int cmode = st->info->default_output_mode;
FIELD_MODIFY(AN877_ADC_OUTPUT_MODE_MASK, &cmode,
AN877_ADC_OUTPUT_MODE_OFFSET_BINARY);
I don't mind that much though if you prefer the original.
> + ret = ad9467_outputmode_set(st, cmode);
> if (ret)
> return ret;
>
>
On Tue, 2025-12-16 at 11:40 +0000, Tomas Melin wrote:
> All supported drivers currently implicitly use two's complement mode.
> Make this clear by declaring two's complement in the default
> output mode. Calibration mode uses offset binary, so change the output
> mode only when running the calibration or other test mode.
>
> Signed-off-by: Tomas Melin <tomas.melin@vaisala.com>
> ---
Reviewed-by: Nuno Sá <nuno.sa@analog.com>
> drivers/iio/adc/ad9467.c | 33 +++++++++++++++++++++++++--------
> 1 file changed, 25 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c
> index 59c3fa3bcc9b0b8b36b78c3b54fd7977cae23496..60fc3361b2689a4c38287c613ef93fe00338e5fa 100644
> --- a/drivers/iio/adc/ad9467.c
> +++ b/drivers/iio/adc/ad9467.c
> @@ -72,6 +72,7 @@
> #define AN877_ADC_OUTPUT_MODE_OFFSET_BINARY 0x0
> #define AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT 0x1
> #define AN877_ADC_OUTPUT_MODE_GRAY_CODE 0x2
> +#define AN877_ADC_OUTPUT_MODE_MASK GENMASK(1, 0)
>
> /* AN877_ADC_REG_OUTPUT_PHASE */
> #define AN877_ADC_OUTPUT_EVEN_ODD_MODE_EN 0x20
> @@ -85,7 +86,7 @@
> */
>
> #define CHIPID_AD9211 0x06
> -#define AD9211_DEF_OUTPUT_MODE 0x00
> +#define AD9211_DEF_OUTPUT_MODE 0x01
> #define AD9211_REG_VREF_MASK GENMASK(4, 0)
>
> /*
> @@ -93,7 +94,7 @@
> */
>
> #define CHIPID_AD9265 0x64
> -#define AD9265_DEF_OUTPUT_MODE 0x40
> +#define AD9265_DEF_OUTPUT_MODE 0x41
> #define AD9265_REG_VREF_MASK 0xC0
>
> /*
> @@ -101,7 +102,7 @@
> */
>
> #define CHIPID_AD9434 0x6A
> -#define AD9434_DEF_OUTPUT_MODE 0x00
> +#define AD9434_DEF_OUTPUT_MODE 0x01
> #define AD9434_REG_VREF_MASK 0xC0
>
> /*
> @@ -109,7 +110,7 @@
> */
>
> #define CHIPID_AD9467 0x50
> -#define AD9467_DEF_OUTPUT_MODE 0x08
> +#define AD9467_DEF_OUTPUT_MODE 0x09
> #define AD9467_REG_VREF_MASK 0x0F
>
> /*
> @@ -117,6 +118,7 @@
> */
>
> #define CHIPID_AD9643 0x82
> +#define AD9643_DEF_OUTPUT_MODE 0x01
> #define AD9643_REG_VREF_MASK 0x1F
>
> /*
> @@ -124,6 +126,7 @@
> */
>
> #define CHIPID_AD9652 0xC1
> +#define AD9652_DEF_OUTPUT_MODE 0x01
> #define AD9652_REG_VREF_MASK 0xC0
>
> /*
> @@ -131,6 +134,7 @@
> */
>
> #define CHIPID_AD9649 0x6F
> +#define AD9649_DEF_OUTPUT_MODE 0x01
> #define AD9649_TEST_POINTS 8
>
> #define AD9647_MAX_TEST_POINTS 32
> @@ -461,6 +465,7 @@ static const struct ad9467_chip_info ad9643_chip_tbl = {
> .test_mask = BIT(AN877_ADC_TESTMODE_RAMP) |
> GENMASK(AN877_ADC_TESTMODE_MIXED_BIT_FREQUENCY, AN877_ADC_TESTMODE_OFF),
> .test_mask_len = AN877_ADC_TESTMODE_RAMP + 1,
> + .default_output_mode = AD9643_DEF_OUTPUT_MODE,
> .vref_mask = AD9643_REG_VREF_MASK,
> .has_dco = true,
> .has_dco_invert = true,
> @@ -479,6 +484,7 @@ static const struct ad9467_chip_info ad9649_chip_tbl = {
> .test_mask = GENMASK(AN877_ADC_TESTMODE_MIXED_BIT_FREQUENCY,
> AN877_ADC_TESTMODE_OFF),
> .test_mask_len = AN877_ADC_TESTMODE_MIXED_BIT_FREQUENCY + 1,
> + .default_output_mode = AD9649_DEF_OUTPUT_MODE,
> .has_dco = true,
> .has_dco_invert = true,
> .dco_en = AN877_ADC_DCO_DELAY_ENABLE,
> @@ -496,6 +502,7 @@ static const struct ad9467_chip_info ad9652_chip_tbl = {
> .test_mask = GENMASK(AN877_ADC_TESTMODE_ONE_ZERO_TOGGLE,
> AN877_ADC_TESTMODE_OFF),
> .test_mask_len = AN877_ADC_TESTMODE_ONE_ZERO_TOGGLE + 1,
> + .default_output_mode = AD9652_DEF_OUTPUT_MODE,
> .vref_mask = AD9652_REG_VREF_MASK,
> .has_dco = true,
> };
> @@ -671,10 +678,14 @@ static int ad9467_backend_testmode_off(struct ad9467_state *st,
>
> static int ad9647_calibrate_prepare(struct ad9467_state *st)
> {
> + unsigned int cmode;
> unsigned int c;
> int ret;
>
> - ret = ad9467_outputmode_set(st, st->info->default_output_mode);
> + cmode = (st->info->default_output_mode & ~AN877_ADC_OUTPUT_MODE_MASK) |
> + FIELD_PREP(AN877_ADC_OUTPUT_MODE_MASK,
> + AN877_ADC_OUTPUT_MODE_OFFSET_BINARY);
> + ret = ad9467_outputmode_set(st, cmode);
> if (ret)
> return ret;
>
> @@ -778,7 +789,7 @@ static int ad9647_calibrate_stop(struct ad9467_state *st)
> return ret;
> }
>
> - mode = st->info->default_output_mode | AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT;
> + mode = st->info->default_output_mode;
> return ad9467_outputmode_set(st, mode);
> }
>
> @@ -1174,12 +1185,18 @@ static ssize_t ad9467_chan_test_mode_write(struct file *file,
> if (ret)
> return ret;
>
> - out_mode = st->info->default_output_mode | AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT;
> + out_mode = st->info->default_output_mode;
> ret = ad9467_outputmode_set(st, out_mode);
> if (ret)
> return ret;
> } else {
> - ret = ad9467_outputmode_set(st, st->info->default_output_mode);
> + unsigned int cmode;
> +
> + cmode = (st->info->default_output_mode &
> + ~AN877_ADC_OUTPUT_MODE_MASK) |
> + FIELD_PREP(AN877_ADC_OUTPUT_MODE_MASK,
> + AN877_ADC_OUTPUT_MODE_OFFSET_BINARY);
> + ret = ad9467_outputmode_set(st, cmode);
> if (ret)
> return ret;
>
© 2016 - 2026 Red Hat, Inc.