Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <o.rempel@pengutronix.de>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Oleksij Rempel and committed by
Jonathan Cameron
a7180136 9e4e86a6

+21 -34
+21 -34
drivers/iio/dac/ds4424.c
··· 5 5 * Copyright (C) 2017 Maxim Integrated 6 6 */ 7 7 8 + #include <linux/bits.h> 8 9 #include <linux/kernel.h> 9 10 #include <linux/module.h> 10 11 #include <linux/i2c.h> ··· 19 18 #define DS4422_MAX_DAC_CHANNELS 2 20 19 #define DS4424_MAX_DAC_CHANNELS 4 21 20 21 + #define DS4424_DAC_MASK GENMASK(6, 0) 22 + #define DS4424_DAC_SOURCE BIT(7) 23 + 22 24 #define DS4424_DAC_ADDR(chan) ((chan) + 0xf8) 23 - #define DS4424_SOURCE_I 1 24 - #define DS4424_SINK_I 0 25 25 26 26 #define DS4424_CHANNEL(chan) { \ 27 27 .type = IIO_CURRENT, \ ··· 31 29 .channel = chan, \ 32 30 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 33 31 } 34 - 35 - /* 36 - * DS4424 DAC control register 8 bits 37 - * [7] 0: to sink; 1: to source 38 - * [6:0] steps to sink/source 39 - * bit[7] looks like a sign bit, but the value of the register is 40 - * not a two's complement code considering the bit[6:0] is a absolute 41 - * distance from the zero point. 42 - */ 43 - union ds4424_raw_data { 44 - struct { 45 - u8 dx:7; 46 - u8 source_bit:1; 47 - }; 48 - u8 bits; 49 - }; 50 32 51 33 enum ds4424_device_ids { 52 34 ID_DS4422, ··· 93 107 struct iio_chan_spec const *chan, 94 108 int *val, int *val2, long mask) 95 109 { 96 - union ds4424_raw_data raw; 97 - int ret; 110 + int ret, regval; 98 111 99 112 switch (mask) { 100 113 case IIO_CHAN_INFO_RAW: 101 - ret = ds4424_get_value(indio_dev, val, chan->channel); 114 + ret = ds4424_get_value(indio_dev, &regval, chan->channel); 102 115 if (ret < 0) { 103 116 pr_err("%s : ds4424_get_value returned %d\n", 104 117 __func__, ret); 105 118 return ret; 106 119 } 107 - raw.bits = *val; 108 - *val = raw.dx; 109 - if (raw.source_bit == DS4424_SINK_I) 120 + 121 + *val = regval & DS4424_DAC_MASK; 122 + if (!(regval & DS4424_DAC_SOURCE)) 110 123 *val = -*val; 124 + 111 125 return IIO_VAL_INT; 112 126 113 127 default: ··· 119 133 struct iio_chan_spec const *chan, 120 134 int val, int val2, long mask) 121 135 { 122 - union ds4424_raw_data raw; 136 + unsigned int abs_val; 123 137 124 138 if (val2 != 0) 125 139 return -EINVAL; 126 140 127 141 switch (mask) { 128 142 case IIO_CHAN_INFO_RAW: 129 - if (val <= S8_MIN || val > S8_MAX) 143 + abs_val = abs(val); 144 + if (abs_val > DS4424_DAC_MASK) 130 145 return -EINVAL; 131 146 132 - if (val > 0) { 133 - raw.source_bit = DS4424_SOURCE_I; 134 - raw.dx = val; 135 - } else { 136 - raw.source_bit = DS4424_SINK_I; 137 - raw.dx = -val; 138 - } 147 + /* 148 + * Currents exiting the IC (Source) are positive. 0 is a valid 149 + * value for no current flow; the direction bit (Source vs Sink) 150 + * is treated as don't-care by the hardware at 0. 151 + */ 152 + if (val > 0) 153 + abs_val |= DS4424_DAC_SOURCE; 139 154 140 - return ds4424_set_value(indio_dev, raw.bits, chan); 155 + return ds4424_set_value(indio_dev, abs_val, chan); 141 156 142 157 default: 143 158 return -EINVAL;