]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
iio: dac: ds4424: refactor raw access to use bitwise operations
authorOleksij Rempel <o.rempel@pengutronix.de>
Tue, 10 Feb 2026 13:50:59 +0000 (14:50 +0100)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Sun, 22 Mar 2026 12:38:30 +0000 (12:38 +0000)
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 <o.rempel@pengutronix.de>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/dac/ds4424.c

index c61868f2de316c4623feddec0dba304a784dbef4..c15eb7b5eb96017f98334c65e4bd72c094b5e2a5 100644 (file)
@@ -5,6 +5,7 @@
  * Copyright (C) 2017 Maxim Integrated
  */
 
+#include <linux/bits.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/i2c.h>
 #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, \
        .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, &regval, 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;