From: Oleksij Rempel Date: Tue, 10 Feb 2026 13:50:59 +0000 (+0100) Subject: iio: dac: ds4424: refactor raw access to use bitwise operations X-Git-Tag: v7.1-rc1~17^2~120^2~26 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a718013647dcd5aca14c9a8856e1dab694e846ae;p=thirdparty%2Fkernel%2Fstable.git iio: dac: ds4424: refactor raw access to use bitwise operations Refactor the raw access logic to use standard GENMASK() and BIT() macros. Use abs() for magnitude calculation to simplify the logic and make the data flow clearer. Signed-off-by: Oleksij Rempel Reviewed-by: Andy Shevchenko Signed-off-by: Jonathan Cameron --- diff --git a/drivers/iio/dac/ds4424.c b/drivers/iio/dac/ds4424.c index c61868f2de316..c15eb7b5eb960 100644 --- a/drivers/iio/dac/ds4424.c +++ b/drivers/iio/dac/ds4424.c @@ -5,6 +5,7 @@ * Copyright (C) 2017 Maxim Integrated */ +#include #include #include #include @@ -18,9 +19,10 @@ #define DS4422_MAX_DAC_CHANNELS 2 #define DS4424_MAX_DAC_CHANNELS 4 +#define DS4424_DAC_MASK GENMASK(6, 0) +#define DS4424_DAC_SOURCE BIT(7) + #define DS4424_DAC_ADDR(chan) ((chan) + 0xf8) -#define DS4424_SOURCE_I 1 -#define DS4424_SINK_I 0 #define DS4424_CHANNEL(chan) { \ .type = IIO_CURRENT, \ @@ -30,22 +32,6 @@ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ } -/* - * DS4424 DAC control register 8 bits - * [7] 0: to sink; 1: to source - * [6:0] steps to sink/source - * bit[7] looks like a sign bit, but the value of the register is - * not a two's complement code considering the bit[6:0] is a absolute - * distance from the zero point. - */ -union ds4424_raw_data { - struct { - u8 dx:7; - u8 source_bit:1; - }; - u8 bits; -}; - enum ds4424_device_ids { ID_DS4422, ID_DS4424, @@ -107,21 +93,21 @@ static int ds4424_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) { - union ds4424_raw_data raw; - int ret; + int ret, regval; switch (mask) { case IIO_CHAN_INFO_RAW: - ret = ds4424_get_value(indio_dev, val, chan->channel); + ret = ds4424_get_value(indio_dev, ®val, chan->channel); if (ret < 0) { pr_err("%s : ds4424_get_value returned %d\n", __func__, ret); return ret; } - raw.bits = *val; - *val = raw.dx; - if (raw.source_bit == DS4424_SINK_I) + + *val = regval & DS4424_DAC_MASK; + if (!(regval & DS4424_DAC_SOURCE)) *val = -*val; + return IIO_VAL_INT; default: @@ -133,25 +119,26 @@ static int ds4424_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask) { - union ds4424_raw_data raw; + unsigned int abs_val; if (val2 != 0) return -EINVAL; switch (mask) { case IIO_CHAN_INFO_RAW: - if (val <= S8_MIN || val > S8_MAX) + abs_val = abs(val); + if (abs_val > DS4424_DAC_MASK) return -EINVAL; - if (val > 0) { - raw.source_bit = DS4424_SOURCE_I; - raw.dx = val; - } else { - raw.source_bit = DS4424_SINK_I; - raw.dx = -val; - } + /* + * Currents exiting the IC (Source) are positive. 0 is a valid + * value for no current flow; the direction bit (Source vs Sink) + * is treated as don't-care by the hardware at 0. + */ + if (val > 0) + abs_val |= DS4424_DAC_SOURCE; - return ds4424_set_value(indio_dev, raw.bits, chan); + return ds4424_set_value(indio_dev, abs_val, chan); default: return -EINVAL;