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

iio: max31856: add support for configuring the HW averaging

This sensor can perform samples averaging in hardware, but currently the
driver leaves this setting alone (default is no averaging).

This patch binds this HW setting to the "oversampling_ratio" IIO attribute
and allows the user to set the averaging as desired (the HW supports
averaging of 2, 5, 8 or 16 samples; in-between values are rounded up).

Cc: Hartmut Knaack <knaack.h@gmx.de>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Patrick Havelange <patrick.havelange@essensium.com>
Cc: Matt Weber <matthew.weber@rockwellcollins.com>
Cc: Matt Ranostay <matt.ranostay@konsulko.com>
Cc: Chuhong Yuan <hslester96@gmail.com>
Cc: Daniel Gomez <dagmcr@gmail.com>
Cc: linux-iio@vger.kernel.org
Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Andrea Merello and committed by
Jonathan Cameron
57a4274c 3f6bba19

+43
+43
drivers/iio/temperature/max31856.c
··· 12 12 #include <linux/spi/spi.h> 13 13 #include <linux/iio/iio.h> 14 14 #include <linux/iio/sysfs.h> 15 + #include <linux/util_macros.h> 15 16 #include <dt-bindings/iio/temperature/thermocouple.h> 16 17 /* 17 18 * The MSB of the register value determines whether the following byte will ··· 25 24 #define MAX31856_CR0_OCFAULT BIT(4) 26 25 #define MAX31856_CR0_OCFAULT_MASK GENMASK(5, 4) 27 26 #define MAX31856_CR0_FILTER_50HZ BIT(0) 27 + #define MAX31856_AVERAGING_MASK GENMASK(6, 4) 28 + #define MAX31856_AVERAGING_SHIFT 4 28 29 #define MAX31856_TC_TYPE_MASK GENMASK(3, 0) 29 30 #define MAX31856_FAULT_OVUV BIT(1) 30 31 #define MAX31856_FAULT_OPEN BIT(0) ··· 54 51 .type = IIO_TEMP, 55 52 .info_mask_separate = 56 53 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), 54 + .info_mask_shared_by_type = 55 + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) 57 56 }, 58 57 { /* Cold Junction Temperature */ 59 58 .type = IIO_TEMP, ··· 63 58 .modified = 1, 64 59 .info_mask_separate = 65 60 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), 61 + .info_mask_shared_by_type = 62 + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) 66 63 }, 67 64 }; 68 65 ··· 72 65 struct spi_device *spi; 73 66 u32 thermocouple_type; 74 67 bool filter_50hz; 68 + int averaging; 75 69 }; 76 70 77 71 static int max31856_read(struct max31856_data *data, u8 reg, ··· 117 109 118 110 reg_cr1_val &= ~MAX31856_TC_TYPE_MASK; 119 111 reg_cr1_val |= data->thermocouple_type; 112 + 113 + reg_cr1_val &= ~MAX31856_AVERAGING_MASK; 114 + reg_cr1_val |= data->averaging << MAX31856_AVERAGING_SHIFT; 115 + 120 116 ret = max31856_write(data, MAX31856_CR1_REG, reg_cr1_val); 121 117 if (ret) 122 118 return ret; ··· 229 217 return IIO_VAL_INT_PLUS_MICRO; 230 218 } 231 219 break; 220 + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: 221 + *val = 1 << data->averaging; 222 + return IIO_VAL_INT; 232 223 default: 233 224 ret = -EINVAL; 234 225 break; 235 226 } 236 227 237 228 return ret; 229 + } 230 + 231 + static int max31856_write_raw(struct iio_dev *indio_dev, 232 + struct iio_chan_spec const *chan, 233 + int val, int val2, long mask) 234 + { 235 + struct max31856_data *data = iio_priv(indio_dev); 236 + int msb; 237 + 238 + switch (mask) { 239 + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: 240 + if (val > 16 || val < 1) 241 + return -EINVAL; 242 + msb = fls(val) - 1; 243 + /* Round up to next 2pow if needed */ 244 + if (BIT(msb) < val) 245 + msb++; 246 + 247 + data->averaging = msb; 248 + max31856_init(data); 249 + break; 250 + 251 + default: 252 + return -EINVAL; 253 + } 254 + 255 + return 0; 238 256 } 239 257 240 258 static ssize_t show_fault(struct device *dev, u8 faultbit, char *buf) ··· 355 313 356 314 static const struct iio_info max31856_info = { 357 315 .read_raw = max31856_read_raw, 316 + .write_raw = max31856_write_raw, 358 317 .attrs = &max31856_group, 359 318 }; 360 319