1a44ef7c4SIbrahim Tilki // SPDX-License-Identifier: GPL-2.0-only 2a44ef7c4SIbrahim Tilki /* 3a44ef7c4SIbrahim Tilki * MAX11410 SPI ADC driver 4a44ef7c4SIbrahim Tilki * 5a44ef7c4SIbrahim Tilki * Copyright 2022 Analog Devices Inc. 6a44ef7c4SIbrahim Tilki */ 7a44ef7c4SIbrahim Tilki #include <linux/bitfield.h> 8a44ef7c4SIbrahim Tilki #include <linux/delay.h> 9a44ef7c4SIbrahim Tilki #include <linux/device.h> 10a44ef7c4SIbrahim Tilki #include <linux/err.h> 11a44ef7c4SIbrahim Tilki #include <linux/interrupt.h> 12a44ef7c4SIbrahim Tilki #include <linux/kernel.h> 13a44ef7c4SIbrahim Tilki #include <linux/module.h> 14a44ef7c4SIbrahim Tilki #include <linux/regmap.h> 15a44ef7c4SIbrahim Tilki #include <linux/regulator/consumer.h> 16a44ef7c4SIbrahim Tilki #include <linux/spi/spi.h> 17a44ef7c4SIbrahim Tilki 18*591a6bc7SAndy Shevchenko #include <asm/unaligned.h> 19*591a6bc7SAndy Shevchenko 20a44ef7c4SIbrahim Tilki #include <linux/iio/buffer.h> 21a44ef7c4SIbrahim Tilki #include <linux/iio/sysfs.h> 22a44ef7c4SIbrahim Tilki #include <linux/iio/trigger.h> 23a44ef7c4SIbrahim Tilki #include <linux/iio/trigger_consumer.h> 24a44ef7c4SIbrahim Tilki #include <linux/iio/triggered_buffer.h> 25a44ef7c4SIbrahim Tilki 26a44ef7c4SIbrahim Tilki #define MAX11410_REG_CONV_START 0x01 27a44ef7c4SIbrahim Tilki #define MAX11410_CONV_TYPE_SINGLE 0x00 28a44ef7c4SIbrahim Tilki #define MAX11410_CONV_TYPE_CONTINUOUS 0x01 29a44ef7c4SIbrahim Tilki #define MAX11410_REG_CAL_START 0x03 30a44ef7c4SIbrahim Tilki #define MAX11410_CAL_START_SELF 0x00 31a44ef7c4SIbrahim Tilki #define MAX11410_CAL_START_PGA 0x01 32a44ef7c4SIbrahim Tilki #define MAX11410_REG_GPIO_CTRL(ch) ((ch) ? 0x05 : 0x04) 33a44ef7c4SIbrahim Tilki #define MAX11410_GPIO_INTRB 0xC1 34a44ef7c4SIbrahim Tilki #define MAX11410_REG_FILTER 0x08 35a44ef7c4SIbrahim Tilki #define MAX11410_FILTER_RATE_MASK GENMASK(3, 0) 36a44ef7c4SIbrahim Tilki #define MAX11410_FILTER_RATE_MAX 0x0F 37a44ef7c4SIbrahim Tilki #define MAX11410_FILTER_LINEF_MASK GENMASK(5, 4) 38a44ef7c4SIbrahim Tilki #define MAX11410_FILTER_50HZ BIT(5) 39a44ef7c4SIbrahim Tilki #define MAX11410_FILTER_60HZ BIT(4) 40a44ef7c4SIbrahim Tilki #define MAX11410_REG_CTRL 0x09 41a44ef7c4SIbrahim Tilki #define MAX11410_CTRL_REFSEL_MASK GENMASK(2, 0) 42a44ef7c4SIbrahim Tilki #define MAX11410_CTRL_VREFN_BUF_BIT BIT(3) 43a44ef7c4SIbrahim Tilki #define MAX11410_CTRL_VREFP_BUF_BIT BIT(4) 44a44ef7c4SIbrahim Tilki #define MAX11410_CTRL_FORMAT_BIT BIT(5) 45a44ef7c4SIbrahim Tilki #define MAX11410_CTRL_UNIPOLAR_BIT BIT(6) 46a44ef7c4SIbrahim Tilki #define MAX11410_REG_MUX_CTRL0 0x0B 47a44ef7c4SIbrahim Tilki #define MAX11410_REG_PGA 0x0E 48a44ef7c4SIbrahim Tilki #define MAX11410_PGA_GAIN_MASK GENMASK(2, 0) 49a44ef7c4SIbrahim Tilki #define MAX11410_PGA_SIG_PATH_MASK GENMASK(5, 4) 50a44ef7c4SIbrahim Tilki #define MAX11410_PGA_SIG_PATH_BUFFERED 0x00 51a44ef7c4SIbrahim Tilki #define MAX11410_PGA_SIG_PATH_BYPASS 0x01 52a44ef7c4SIbrahim Tilki #define MAX11410_PGA_SIG_PATH_PGA 0x02 53a44ef7c4SIbrahim Tilki #define MAX11410_REG_DATA0 0x30 54a44ef7c4SIbrahim Tilki #define MAX11410_REG_STATUS 0x38 55a44ef7c4SIbrahim Tilki #define MAX11410_STATUS_CONV_READY_BIT BIT(0) 56a44ef7c4SIbrahim Tilki #define MAX11410_STATUS_CAL_READY_BIT BIT(2) 57a44ef7c4SIbrahim Tilki 58a44ef7c4SIbrahim Tilki #define MAX11410_REFSEL_AVDD_AGND 0x03 59a44ef7c4SIbrahim Tilki #define MAX11410_REFSEL_MAX 0x06 60a44ef7c4SIbrahim Tilki #define MAX11410_SIG_PATH_MAX 0x02 61a44ef7c4SIbrahim Tilki #define MAX11410_CHANNEL_INDEX_MAX 0x0A 62a44ef7c4SIbrahim Tilki #define MAX11410_AINP_AVDD 0x0A 63a44ef7c4SIbrahim Tilki #define MAX11410_AINN_GND 0x0A 64a44ef7c4SIbrahim Tilki 65a44ef7c4SIbrahim Tilki #define MAX11410_CONVERSION_TIMEOUT_MS 2000 66a44ef7c4SIbrahim Tilki #define MAX11410_CALIB_TIMEOUT_MS 2000 67a44ef7c4SIbrahim Tilki 68a44ef7c4SIbrahim Tilki #define MAX11410_SCALE_AVAIL_SIZE 8 69a44ef7c4SIbrahim Tilki 70a44ef7c4SIbrahim Tilki enum max11410_filter { 71a44ef7c4SIbrahim Tilki MAX11410_FILTER_FIR5060, 72a44ef7c4SIbrahim Tilki MAX11410_FILTER_FIR50, 73a44ef7c4SIbrahim Tilki MAX11410_FILTER_FIR60, 74a44ef7c4SIbrahim Tilki MAX11410_FILTER_SINC4, 75a44ef7c4SIbrahim Tilki }; 76a44ef7c4SIbrahim Tilki 77a44ef7c4SIbrahim Tilki static const u8 max11410_sampling_len[] = { 78a44ef7c4SIbrahim Tilki [MAX11410_FILTER_FIR5060] = 5, 79a44ef7c4SIbrahim Tilki [MAX11410_FILTER_FIR50] = 6, 80a44ef7c4SIbrahim Tilki [MAX11410_FILTER_FIR60] = 6, 81a44ef7c4SIbrahim Tilki [MAX11410_FILTER_SINC4] = 10, 82a44ef7c4SIbrahim Tilki }; 83a44ef7c4SIbrahim Tilki 84a44ef7c4SIbrahim Tilki static const int max11410_sampling_rates[4][10][2] = { 85a44ef7c4SIbrahim Tilki [MAX11410_FILTER_FIR5060] = { 86a44ef7c4SIbrahim Tilki { 1, 100000 }, 87a44ef7c4SIbrahim Tilki { 2, 100000 }, 88a44ef7c4SIbrahim Tilki { 4, 200000 }, 89a44ef7c4SIbrahim Tilki { 8, 400000 }, 90a44ef7c4SIbrahim Tilki { 16, 800000 } 91a44ef7c4SIbrahim Tilki }, 92a44ef7c4SIbrahim Tilki [MAX11410_FILTER_FIR50] = { 93a44ef7c4SIbrahim Tilki { 1, 300000 }, 94a44ef7c4SIbrahim Tilki { 2, 700000 }, 95a44ef7c4SIbrahim Tilki { 5, 300000 }, 96a44ef7c4SIbrahim Tilki { 10, 700000 }, 97a44ef7c4SIbrahim Tilki { 21, 300000 }, 98a44ef7c4SIbrahim Tilki { 40 } 99a44ef7c4SIbrahim Tilki }, 100a44ef7c4SIbrahim Tilki [MAX11410_FILTER_FIR60] = { 101a44ef7c4SIbrahim Tilki { 1, 300000 }, 102a44ef7c4SIbrahim Tilki { 2, 700000 }, 103a44ef7c4SIbrahim Tilki { 5, 300000 }, 104a44ef7c4SIbrahim Tilki { 10, 700000 }, 105a44ef7c4SIbrahim Tilki { 21, 300000 }, 106a44ef7c4SIbrahim Tilki { 40 } 107a44ef7c4SIbrahim Tilki }, 108a44ef7c4SIbrahim Tilki [MAX11410_FILTER_SINC4] = { 109a44ef7c4SIbrahim Tilki { 4 }, 110a44ef7c4SIbrahim Tilki { 10 }, 111a44ef7c4SIbrahim Tilki { 20 }, 112a44ef7c4SIbrahim Tilki { 40 }, 113a44ef7c4SIbrahim Tilki { 60 }, 114a44ef7c4SIbrahim Tilki { 120 }, 115a44ef7c4SIbrahim Tilki { 240 }, 116a44ef7c4SIbrahim Tilki { 480 }, 117a44ef7c4SIbrahim Tilki { 960 }, 118a44ef7c4SIbrahim Tilki { 1920 } 119a44ef7c4SIbrahim Tilki } 120a44ef7c4SIbrahim Tilki }; 121a44ef7c4SIbrahim Tilki 122a44ef7c4SIbrahim Tilki struct max11410_channel_config { 123a44ef7c4SIbrahim Tilki u32 settling_time_us; 124a44ef7c4SIbrahim Tilki u32 *scale_avail; 125a44ef7c4SIbrahim Tilki u8 refsel; 126a44ef7c4SIbrahim Tilki u8 sig_path; 127a44ef7c4SIbrahim Tilki u8 gain; 128a44ef7c4SIbrahim Tilki bool bipolar; 129a44ef7c4SIbrahim Tilki bool buffered_vrefp; 130a44ef7c4SIbrahim Tilki bool buffered_vrefn; 131a44ef7c4SIbrahim Tilki }; 132a44ef7c4SIbrahim Tilki 133a44ef7c4SIbrahim Tilki struct max11410_state { 134a44ef7c4SIbrahim Tilki struct spi_device *spi_dev; 135a44ef7c4SIbrahim Tilki struct iio_trigger *trig; 136a44ef7c4SIbrahim Tilki struct completion completion; 137a44ef7c4SIbrahim Tilki struct mutex lock; /* Prevent changing channel config during sampling */ 138a44ef7c4SIbrahim Tilki struct regmap *regmap; 139a44ef7c4SIbrahim Tilki struct regulator *avdd; 140a44ef7c4SIbrahim Tilki struct regulator *vrefp[3]; 141a44ef7c4SIbrahim Tilki struct regulator *vrefn[3]; 142a44ef7c4SIbrahim Tilki struct max11410_channel_config *channels; 143a44ef7c4SIbrahim Tilki int irq; 144a44ef7c4SIbrahim Tilki struct { 145a44ef7c4SIbrahim Tilki u32 data __aligned(IIO_DMA_MINALIGN); 146a44ef7c4SIbrahim Tilki s64 ts __aligned(8); 147a44ef7c4SIbrahim Tilki } scan; 148a44ef7c4SIbrahim Tilki }; 149a44ef7c4SIbrahim Tilki 150a44ef7c4SIbrahim Tilki static const struct iio_chan_spec chanspec_template = { 151a44ef7c4SIbrahim Tilki .type = IIO_VOLTAGE, 152a44ef7c4SIbrahim Tilki .indexed = 1, 153a44ef7c4SIbrahim Tilki .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 154a44ef7c4SIbrahim Tilki BIT(IIO_CHAN_INFO_SCALE) | 155a44ef7c4SIbrahim Tilki BIT(IIO_CHAN_INFO_OFFSET), 156a44ef7c4SIbrahim Tilki .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), 157a44ef7c4SIbrahim Tilki .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), 158a44ef7c4SIbrahim Tilki .scan_type = { 159a44ef7c4SIbrahim Tilki .sign = 's', 160a44ef7c4SIbrahim Tilki .realbits = 24, 161a44ef7c4SIbrahim Tilki .storagebits = 32, 162a44ef7c4SIbrahim Tilki .endianness = IIO_LE, 163a44ef7c4SIbrahim Tilki }, 164a44ef7c4SIbrahim Tilki }; 165a44ef7c4SIbrahim Tilki 166a44ef7c4SIbrahim Tilki static unsigned int max11410_reg_size(unsigned int reg) 167a44ef7c4SIbrahim Tilki { 168a44ef7c4SIbrahim Tilki /* Registers from 0x00 to 0x10 are 1 byte, the rest are 3 bytes long. */ 169a44ef7c4SIbrahim Tilki return reg <= 0x10 ? 1 : 3; 170a44ef7c4SIbrahim Tilki } 171a44ef7c4SIbrahim Tilki 172a44ef7c4SIbrahim Tilki static int max11410_write_reg(struct max11410_state *st, unsigned int reg, 173a44ef7c4SIbrahim Tilki unsigned int val) 174a44ef7c4SIbrahim Tilki { 175a44ef7c4SIbrahim Tilki /* This driver only needs to write 8-bit registers */ 176a44ef7c4SIbrahim Tilki if (max11410_reg_size(reg) != 1) 177a44ef7c4SIbrahim Tilki return -EINVAL; 178a44ef7c4SIbrahim Tilki 179a44ef7c4SIbrahim Tilki return regmap_write(st->regmap, reg, val); 180a44ef7c4SIbrahim Tilki } 181a44ef7c4SIbrahim Tilki 182a44ef7c4SIbrahim Tilki static int max11410_read_reg(struct max11410_state *st, unsigned int reg, 183a44ef7c4SIbrahim Tilki int *val) 184a44ef7c4SIbrahim Tilki { 185a44ef7c4SIbrahim Tilki int ret; 186a44ef7c4SIbrahim Tilki 187a44ef7c4SIbrahim Tilki if (max11410_reg_size(reg) == 3) { 188a44ef7c4SIbrahim Tilki ret = regmap_bulk_read(st->regmap, reg, &st->scan.data, 3); 189a44ef7c4SIbrahim Tilki if (ret) 190a44ef7c4SIbrahim Tilki return ret; 191a44ef7c4SIbrahim Tilki 192a44ef7c4SIbrahim Tilki *val = get_unaligned_be24(&st->scan.data); 193a44ef7c4SIbrahim Tilki return 0; 194a44ef7c4SIbrahim Tilki } 195a44ef7c4SIbrahim Tilki 196a44ef7c4SIbrahim Tilki return regmap_read(st->regmap, reg, val); 197a44ef7c4SIbrahim Tilki } 198a44ef7c4SIbrahim Tilki 199a44ef7c4SIbrahim Tilki static struct regulator *max11410_get_vrefp(struct max11410_state *st, 200a44ef7c4SIbrahim Tilki u8 refsel) 201a44ef7c4SIbrahim Tilki { 202a44ef7c4SIbrahim Tilki refsel = refsel % 4; 203a44ef7c4SIbrahim Tilki if (refsel == 3) 204a44ef7c4SIbrahim Tilki return st->avdd; 205a44ef7c4SIbrahim Tilki 206a44ef7c4SIbrahim Tilki return st->vrefp[refsel]; 207a44ef7c4SIbrahim Tilki } 208a44ef7c4SIbrahim Tilki 209a44ef7c4SIbrahim Tilki static struct regulator *max11410_get_vrefn(struct max11410_state *st, 210a44ef7c4SIbrahim Tilki u8 refsel) 211a44ef7c4SIbrahim Tilki { 212a44ef7c4SIbrahim Tilki if (refsel > 2) 213a44ef7c4SIbrahim Tilki return NULL; 214a44ef7c4SIbrahim Tilki 215a44ef7c4SIbrahim Tilki return st->vrefn[refsel]; 216a44ef7c4SIbrahim Tilki } 217a44ef7c4SIbrahim Tilki 218a44ef7c4SIbrahim Tilki static const struct regmap_config regmap_config = { 219a44ef7c4SIbrahim Tilki .reg_bits = 8, 220a44ef7c4SIbrahim Tilki .val_bits = 8, 221a44ef7c4SIbrahim Tilki .max_register = 0x39, 222a44ef7c4SIbrahim Tilki }; 223a44ef7c4SIbrahim Tilki 224a44ef7c4SIbrahim Tilki static ssize_t max11410_notch_en_show(struct device *dev, 225a44ef7c4SIbrahim Tilki struct device_attribute *devattr, 226a44ef7c4SIbrahim Tilki char *buf) 227a44ef7c4SIbrahim Tilki { 228a44ef7c4SIbrahim Tilki struct iio_dev *indio_dev = dev_get_drvdata(dev); 229a44ef7c4SIbrahim Tilki struct max11410_state *state = iio_priv(indio_dev); 230a44ef7c4SIbrahim Tilki struct iio_dev_attr *iio_attr = to_iio_dev_attr(devattr); 231a44ef7c4SIbrahim Tilki unsigned int val; 232a44ef7c4SIbrahim Tilki int ret; 233a44ef7c4SIbrahim Tilki 234a44ef7c4SIbrahim Tilki ret = max11410_read_reg(state, MAX11410_REG_FILTER, &val); 235a44ef7c4SIbrahim Tilki if (ret) 236a44ef7c4SIbrahim Tilki return ret; 237a44ef7c4SIbrahim Tilki 238a44ef7c4SIbrahim Tilki switch (iio_attr->address) { 239a44ef7c4SIbrahim Tilki case 0: 240a44ef7c4SIbrahim Tilki val = !FIELD_GET(MAX11410_FILTER_50HZ, val); 241a44ef7c4SIbrahim Tilki break; 242a44ef7c4SIbrahim Tilki case 1: 243a44ef7c4SIbrahim Tilki val = !FIELD_GET(MAX11410_FILTER_60HZ, val); 244a44ef7c4SIbrahim Tilki break; 245a44ef7c4SIbrahim Tilki case 2: 246a44ef7c4SIbrahim Tilki val = FIELD_GET(MAX11410_FILTER_LINEF_MASK, val) == 3; 247a44ef7c4SIbrahim Tilki break; 248a44ef7c4SIbrahim Tilki default: 249a44ef7c4SIbrahim Tilki return -EINVAL; 250a44ef7c4SIbrahim Tilki } 251a44ef7c4SIbrahim Tilki 252a44ef7c4SIbrahim Tilki return sysfs_emit(buf, "%d\n", val); 253a44ef7c4SIbrahim Tilki } 254a44ef7c4SIbrahim Tilki 255a44ef7c4SIbrahim Tilki static ssize_t max11410_notch_en_store(struct device *dev, 256a44ef7c4SIbrahim Tilki struct device_attribute *devattr, 257a44ef7c4SIbrahim Tilki const char *buf, size_t count) 258a44ef7c4SIbrahim Tilki { 259a44ef7c4SIbrahim Tilki struct iio_dev_attr *iio_attr = to_iio_dev_attr(devattr); 260a44ef7c4SIbrahim Tilki struct iio_dev *indio_dev = dev_get_drvdata(dev); 261a44ef7c4SIbrahim Tilki struct max11410_state *state = iio_priv(indio_dev); 262a44ef7c4SIbrahim Tilki unsigned int filter_bits; 263a44ef7c4SIbrahim Tilki bool enable; 264a44ef7c4SIbrahim Tilki int ret; 265a44ef7c4SIbrahim Tilki 266a44ef7c4SIbrahim Tilki ret = kstrtobool(buf, &enable); 267a44ef7c4SIbrahim Tilki if (ret) 268a44ef7c4SIbrahim Tilki return ret; 269a44ef7c4SIbrahim Tilki 270a44ef7c4SIbrahim Tilki switch (iio_attr->address) { 271a44ef7c4SIbrahim Tilki case 0: 272a44ef7c4SIbrahim Tilki filter_bits = MAX11410_FILTER_50HZ; 273a44ef7c4SIbrahim Tilki break; 274a44ef7c4SIbrahim Tilki case 1: 275a44ef7c4SIbrahim Tilki filter_bits = MAX11410_FILTER_60HZ; 276a44ef7c4SIbrahim Tilki break; 277a44ef7c4SIbrahim Tilki case 2: 278a44ef7c4SIbrahim Tilki default: 279a44ef7c4SIbrahim Tilki filter_bits = MAX11410_FILTER_50HZ | MAX11410_FILTER_60HZ; 280a44ef7c4SIbrahim Tilki enable = !enable; 281a44ef7c4SIbrahim Tilki break; 282a44ef7c4SIbrahim Tilki } 283a44ef7c4SIbrahim Tilki 284a44ef7c4SIbrahim Tilki if (enable) 285a44ef7c4SIbrahim Tilki ret = regmap_clear_bits(state->regmap, MAX11410_REG_FILTER, 286a44ef7c4SIbrahim Tilki filter_bits); 287a44ef7c4SIbrahim Tilki else 288a44ef7c4SIbrahim Tilki ret = regmap_set_bits(state->regmap, MAX11410_REG_FILTER, 289a44ef7c4SIbrahim Tilki filter_bits); 290a44ef7c4SIbrahim Tilki 291a44ef7c4SIbrahim Tilki if (ret) 292a44ef7c4SIbrahim Tilki return ret; 293a44ef7c4SIbrahim Tilki 294a44ef7c4SIbrahim Tilki return count; 295a44ef7c4SIbrahim Tilki } 296a44ef7c4SIbrahim Tilki 297a44ef7c4SIbrahim Tilki static ssize_t in_voltage_filter2_notch_center_show(struct device *dev, 298a44ef7c4SIbrahim Tilki struct device_attribute *devattr, 299a44ef7c4SIbrahim Tilki char *buf) 300a44ef7c4SIbrahim Tilki { 301a44ef7c4SIbrahim Tilki struct iio_dev *indio_dev = dev_get_drvdata(dev); 302a44ef7c4SIbrahim Tilki struct max11410_state *state = iio_priv(indio_dev); 303a44ef7c4SIbrahim Tilki int ret, reg, rate, filter; 304a44ef7c4SIbrahim Tilki 305a44ef7c4SIbrahim Tilki ret = regmap_read(state->regmap, MAX11410_REG_FILTER, ®); 306a44ef7c4SIbrahim Tilki if (ret) 307a44ef7c4SIbrahim Tilki return ret; 308a44ef7c4SIbrahim Tilki 309a44ef7c4SIbrahim Tilki rate = FIELD_GET(MAX11410_FILTER_RATE_MASK, reg); 310a44ef7c4SIbrahim Tilki rate = clamp_val(rate, 0, 311a44ef7c4SIbrahim Tilki max11410_sampling_len[MAX11410_FILTER_SINC4] - 1); 312a44ef7c4SIbrahim Tilki filter = max11410_sampling_rates[MAX11410_FILTER_SINC4][rate][0]; 313a44ef7c4SIbrahim Tilki 314a44ef7c4SIbrahim Tilki return sysfs_emit(buf, "%d\n", filter); 315a44ef7c4SIbrahim Tilki } 316a44ef7c4SIbrahim Tilki 317a44ef7c4SIbrahim Tilki static IIO_CONST_ATTR(in_voltage_filter0_notch_center, "50"); 318a44ef7c4SIbrahim Tilki static IIO_CONST_ATTR(in_voltage_filter1_notch_center, "60"); 319a44ef7c4SIbrahim Tilki static IIO_DEVICE_ATTR_RO(in_voltage_filter2_notch_center, 2); 320a44ef7c4SIbrahim Tilki 321a44ef7c4SIbrahim Tilki static IIO_DEVICE_ATTR(in_voltage_filter0_notch_en, 0644, 322a44ef7c4SIbrahim Tilki max11410_notch_en_show, max11410_notch_en_store, 0); 323a44ef7c4SIbrahim Tilki static IIO_DEVICE_ATTR(in_voltage_filter1_notch_en, 0644, 324a44ef7c4SIbrahim Tilki max11410_notch_en_show, max11410_notch_en_store, 1); 325a44ef7c4SIbrahim Tilki static IIO_DEVICE_ATTR(in_voltage_filter2_notch_en, 0644, 326a44ef7c4SIbrahim Tilki max11410_notch_en_show, max11410_notch_en_store, 2); 327a44ef7c4SIbrahim Tilki 328a44ef7c4SIbrahim Tilki static struct attribute *max11410_attributes[] = { 329a44ef7c4SIbrahim Tilki &iio_const_attr_in_voltage_filter0_notch_center.dev_attr.attr, 330a44ef7c4SIbrahim Tilki &iio_const_attr_in_voltage_filter1_notch_center.dev_attr.attr, 331a44ef7c4SIbrahim Tilki &iio_dev_attr_in_voltage_filter2_notch_center.dev_attr.attr, 332a44ef7c4SIbrahim Tilki &iio_dev_attr_in_voltage_filter0_notch_en.dev_attr.attr, 333a44ef7c4SIbrahim Tilki &iio_dev_attr_in_voltage_filter1_notch_en.dev_attr.attr, 334a44ef7c4SIbrahim Tilki &iio_dev_attr_in_voltage_filter2_notch_en.dev_attr.attr, 335a44ef7c4SIbrahim Tilki NULL 336a44ef7c4SIbrahim Tilki }; 337a44ef7c4SIbrahim Tilki 338a44ef7c4SIbrahim Tilki static const struct attribute_group max11410_attribute_group = { 339a44ef7c4SIbrahim Tilki .attrs = max11410_attributes, 340a44ef7c4SIbrahim Tilki }; 341a44ef7c4SIbrahim Tilki 342a44ef7c4SIbrahim Tilki static int max11410_set_input_mux(struct max11410_state *st, u8 ainp, u8 ainn) 343a44ef7c4SIbrahim Tilki { 344a44ef7c4SIbrahim Tilki if (ainp > MAX11410_CHANNEL_INDEX_MAX || 345a44ef7c4SIbrahim Tilki ainn > MAX11410_CHANNEL_INDEX_MAX) 346a44ef7c4SIbrahim Tilki return -EINVAL; 347a44ef7c4SIbrahim Tilki 348a44ef7c4SIbrahim Tilki return max11410_write_reg(st, MAX11410_REG_MUX_CTRL0, 349a44ef7c4SIbrahim Tilki (ainp << 4) | ainn); 350a44ef7c4SIbrahim Tilki } 351a44ef7c4SIbrahim Tilki 352a44ef7c4SIbrahim Tilki static int max11410_configure_channel(struct max11410_state *st, 353a44ef7c4SIbrahim Tilki struct iio_chan_spec const *chan) 354a44ef7c4SIbrahim Tilki { 355a44ef7c4SIbrahim Tilki struct max11410_channel_config cfg = st->channels[chan->address]; 356a44ef7c4SIbrahim Tilki unsigned int regval; 357a44ef7c4SIbrahim Tilki int ret; 358a44ef7c4SIbrahim Tilki 359a44ef7c4SIbrahim Tilki if (chan->differential) 360a44ef7c4SIbrahim Tilki ret = max11410_set_input_mux(st, chan->channel, chan->channel2); 361a44ef7c4SIbrahim Tilki else 362a44ef7c4SIbrahim Tilki ret = max11410_set_input_mux(st, chan->channel, 363a44ef7c4SIbrahim Tilki MAX11410_AINN_GND); 364a44ef7c4SIbrahim Tilki 365a44ef7c4SIbrahim Tilki if (ret) 366a44ef7c4SIbrahim Tilki return ret; 367a44ef7c4SIbrahim Tilki 368a44ef7c4SIbrahim Tilki regval = FIELD_PREP(MAX11410_CTRL_VREFP_BUF_BIT, cfg.buffered_vrefp) | 369a44ef7c4SIbrahim Tilki FIELD_PREP(MAX11410_CTRL_VREFN_BUF_BIT, cfg.buffered_vrefn) | 370a44ef7c4SIbrahim Tilki FIELD_PREP(MAX11410_CTRL_REFSEL_MASK, cfg.refsel) | 371a44ef7c4SIbrahim Tilki FIELD_PREP(MAX11410_CTRL_UNIPOLAR_BIT, cfg.bipolar ? 0 : 1); 372a44ef7c4SIbrahim Tilki ret = regmap_update_bits(st->regmap, MAX11410_REG_CTRL, 373a44ef7c4SIbrahim Tilki MAX11410_CTRL_REFSEL_MASK | 37499b43a15SIbrahim Tilki MAX11410_CTRL_VREFP_BUF_BIT | 375a44ef7c4SIbrahim Tilki MAX11410_CTRL_VREFN_BUF_BIT | 376a44ef7c4SIbrahim Tilki MAX11410_CTRL_UNIPOLAR_BIT, regval); 377a44ef7c4SIbrahim Tilki if (ret) 378a44ef7c4SIbrahim Tilki return ret; 379a44ef7c4SIbrahim Tilki 380a44ef7c4SIbrahim Tilki regval = FIELD_PREP(MAX11410_PGA_SIG_PATH_MASK, cfg.sig_path) | 381a44ef7c4SIbrahim Tilki FIELD_PREP(MAX11410_PGA_GAIN_MASK, cfg.gain); 382a44ef7c4SIbrahim Tilki ret = regmap_write(st->regmap, MAX11410_REG_PGA, regval); 383a44ef7c4SIbrahim Tilki if (ret) 384a44ef7c4SIbrahim Tilki return ret; 385a44ef7c4SIbrahim Tilki 386a44ef7c4SIbrahim Tilki if (cfg.settling_time_us) 387a44ef7c4SIbrahim Tilki fsleep(cfg.settling_time_us); 388a44ef7c4SIbrahim Tilki 389a44ef7c4SIbrahim Tilki return 0; 390a44ef7c4SIbrahim Tilki } 391a44ef7c4SIbrahim Tilki 392a44ef7c4SIbrahim Tilki static int max11410_sample(struct max11410_state *st, int *sample_raw, 393a44ef7c4SIbrahim Tilki struct iio_chan_spec const *chan) 394a44ef7c4SIbrahim Tilki { 395a44ef7c4SIbrahim Tilki int val, ret; 396a44ef7c4SIbrahim Tilki 397a44ef7c4SIbrahim Tilki ret = max11410_configure_channel(st, chan); 398a44ef7c4SIbrahim Tilki if (ret) 399a44ef7c4SIbrahim Tilki return ret; 400a44ef7c4SIbrahim Tilki 401a44ef7c4SIbrahim Tilki if (st->irq > 0) 402a44ef7c4SIbrahim Tilki reinit_completion(&st->completion); 403a44ef7c4SIbrahim Tilki 404a44ef7c4SIbrahim Tilki /* Start Conversion */ 405a44ef7c4SIbrahim Tilki ret = max11410_write_reg(st, MAX11410_REG_CONV_START, 406a44ef7c4SIbrahim Tilki MAX11410_CONV_TYPE_SINGLE); 407a44ef7c4SIbrahim Tilki if (ret) 408a44ef7c4SIbrahim Tilki return ret; 409a44ef7c4SIbrahim Tilki 410a44ef7c4SIbrahim Tilki if (st->irq > 0) { 411a44ef7c4SIbrahim Tilki /* Wait for an interrupt. */ 412a44ef7c4SIbrahim Tilki ret = wait_for_completion_timeout(&st->completion, 413a44ef7c4SIbrahim Tilki msecs_to_jiffies(MAX11410_CONVERSION_TIMEOUT_MS)); 414a44ef7c4SIbrahim Tilki if (!ret) 415a44ef7c4SIbrahim Tilki return -ETIMEDOUT; 416a44ef7c4SIbrahim Tilki } else { 417a44ef7c4SIbrahim Tilki /* Wait for status register Conversion Ready flag */ 418a44ef7c4SIbrahim Tilki ret = read_poll_timeout(max11410_read_reg, ret, 419a44ef7c4SIbrahim Tilki ret || (val & MAX11410_STATUS_CONV_READY_BIT), 420a44ef7c4SIbrahim Tilki 5000, MAX11410_CONVERSION_TIMEOUT_MS * 1000, 421a44ef7c4SIbrahim Tilki true, st, MAX11410_REG_STATUS, &val); 422a44ef7c4SIbrahim Tilki if (ret) 423a44ef7c4SIbrahim Tilki return ret; 424a44ef7c4SIbrahim Tilki } 425a44ef7c4SIbrahim Tilki 426a44ef7c4SIbrahim Tilki /* Read ADC Data */ 427a44ef7c4SIbrahim Tilki return max11410_read_reg(st, MAX11410_REG_DATA0, sample_raw); 428a44ef7c4SIbrahim Tilki } 429a44ef7c4SIbrahim Tilki 430a44ef7c4SIbrahim Tilki static int max11410_get_scale(struct max11410_state *state, 431a44ef7c4SIbrahim Tilki struct max11410_channel_config cfg) 432a44ef7c4SIbrahim Tilki { 433a44ef7c4SIbrahim Tilki struct regulator *vrefp, *vrefn; 434a44ef7c4SIbrahim Tilki int scale; 435a44ef7c4SIbrahim Tilki 436a44ef7c4SIbrahim Tilki vrefp = max11410_get_vrefp(state, cfg.refsel); 437a44ef7c4SIbrahim Tilki 438a44ef7c4SIbrahim Tilki scale = regulator_get_voltage(vrefp) / 1000; 439a44ef7c4SIbrahim Tilki vrefn = max11410_get_vrefn(state, cfg.refsel); 440a44ef7c4SIbrahim Tilki if (vrefn) 441a44ef7c4SIbrahim Tilki scale -= regulator_get_voltage(vrefn) / 1000; 442a44ef7c4SIbrahim Tilki 443a44ef7c4SIbrahim Tilki if (cfg.bipolar) 444a44ef7c4SIbrahim Tilki scale *= 2; 445a44ef7c4SIbrahim Tilki 446a44ef7c4SIbrahim Tilki return scale >> cfg.gain; 447a44ef7c4SIbrahim Tilki } 448a44ef7c4SIbrahim Tilki 449a44ef7c4SIbrahim Tilki static int max11410_read_raw(struct iio_dev *indio_dev, 450a44ef7c4SIbrahim Tilki struct iio_chan_spec const *chan, 451a44ef7c4SIbrahim Tilki int *val, int *val2, long info) 452a44ef7c4SIbrahim Tilki { 453a44ef7c4SIbrahim Tilki struct max11410_state *state = iio_priv(indio_dev); 454a44ef7c4SIbrahim Tilki struct max11410_channel_config cfg = state->channels[chan->address]; 455a44ef7c4SIbrahim Tilki int ret, reg_val, filter, rate; 456a44ef7c4SIbrahim Tilki 457a44ef7c4SIbrahim Tilki switch (info) { 458a44ef7c4SIbrahim Tilki case IIO_CHAN_INFO_SCALE: 459a44ef7c4SIbrahim Tilki *val = max11410_get_scale(state, cfg); 460a44ef7c4SIbrahim Tilki *val2 = chan->scan_type.realbits; 461a44ef7c4SIbrahim Tilki return IIO_VAL_FRACTIONAL_LOG2; 462a44ef7c4SIbrahim Tilki case IIO_CHAN_INFO_OFFSET: 463a44ef7c4SIbrahim Tilki if (cfg.bipolar) 464a44ef7c4SIbrahim Tilki *val = -BIT(chan->scan_type.realbits - 1); 465a44ef7c4SIbrahim Tilki else 466a44ef7c4SIbrahim Tilki *val = 0; 467a44ef7c4SIbrahim Tilki 468a44ef7c4SIbrahim Tilki return IIO_VAL_INT; 469a44ef7c4SIbrahim Tilki case IIO_CHAN_INFO_RAW: 470a44ef7c4SIbrahim Tilki ret = iio_device_claim_direct_mode(indio_dev); 471a44ef7c4SIbrahim Tilki if (ret) 472a44ef7c4SIbrahim Tilki return ret; 473a44ef7c4SIbrahim Tilki 474a44ef7c4SIbrahim Tilki mutex_lock(&state->lock); 475a44ef7c4SIbrahim Tilki 476a44ef7c4SIbrahim Tilki ret = max11410_sample(state, ®_val, chan); 477a44ef7c4SIbrahim Tilki 478a44ef7c4SIbrahim Tilki mutex_unlock(&state->lock); 479a44ef7c4SIbrahim Tilki 480a44ef7c4SIbrahim Tilki iio_device_release_direct_mode(indio_dev); 481a44ef7c4SIbrahim Tilki 482a44ef7c4SIbrahim Tilki if (ret) 483a44ef7c4SIbrahim Tilki return ret; 484a44ef7c4SIbrahim Tilki 485a44ef7c4SIbrahim Tilki *val = reg_val; 486a44ef7c4SIbrahim Tilki 487a44ef7c4SIbrahim Tilki return IIO_VAL_INT; 488a44ef7c4SIbrahim Tilki case IIO_CHAN_INFO_SAMP_FREQ: 489a44ef7c4SIbrahim Tilki ret = regmap_read(state->regmap, MAX11410_REG_FILTER, ®_val); 490a44ef7c4SIbrahim Tilki if (ret) 491a44ef7c4SIbrahim Tilki return ret; 492a44ef7c4SIbrahim Tilki 493a44ef7c4SIbrahim Tilki filter = FIELD_GET(MAX11410_FILTER_LINEF_MASK, reg_val); 494a44ef7c4SIbrahim Tilki rate = reg_val & MAX11410_FILTER_RATE_MASK; 495a44ef7c4SIbrahim Tilki if (rate >= max11410_sampling_len[filter]) 496a44ef7c4SIbrahim Tilki rate = max11410_sampling_len[filter] - 1; 497a44ef7c4SIbrahim Tilki 498a44ef7c4SIbrahim Tilki *val = max11410_sampling_rates[filter][rate][0]; 499a44ef7c4SIbrahim Tilki *val2 = max11410_sampling_rates[filter][rate][1]; 500a44ef7c4SIbrahim Tilki 501a44ef7c4SIbrahim Tilki return IIO_VAL_INT_PLUS_MICRO; 502a44ef7c4SIbrahim Tilki } 503a44ef7c4SIbrahim Tilki return -EINVAL; 504a44ef7c4SIbrahim Tilki } 505a44ef7c4SIbrahim Tilki 506a44ef7c4SIbrahim Tilki static int max11410_write_raw(struct iio_dev *indio_dev, 507a44ef7c4SIbrahim Tilki struct iio_chan_spec const *chan, 508a44ef7c4SIbrahim Tilki int val, int val2, long mask) 509a44ef7c4SIbrahim Tilki { 510a44ef7c4SIbrahim Tilki struct max11410_state *st = iio_priv(indio_dev); 511a44ef7c4SIbrahim Tilki int i, ret, reg_val, filter, gain; 512a44ef7c4SIbrahim Tilki u32 *scale_avail; 513a44ef7c4SIbrahim Tilki 514a44ef7c4SIbrahim Tilki switch (mask) { 515a44ef7c4SIbrahim Tilki case IIO_CHAN_INFO_SCALE: 516a44ef7c4SIbrahim Tilki scale_avail = st->channels[chan->address].scale_avail; 517a44ef7c4SIbrahim Tilki if (!scale_avail) 518a44ef7c4SIbrahim Tilki return -EOPNOTSUPP; 519a44ef7c4SIbrahim Tilki 520a44ef7c4SIbrahim Tilki /* Accept values in range 0.000001 <= scale < 1.000000 */ 521a44ef7c4SIbrahim Tilki if (val != 0 || val2 == 0) 522a44ef7c4SIbrahim Tilki return -EINVAL; 523a44ef7c4SIbrahim Tilki 524a44ef7c4SIbrahim Tilki ret = iio_device_claim_direct_mode(indio_dev); 525a44ef7c4SIbrahim Tilki if (ret) 526a44ef7c4SIbrahim Tilki return ret; 527a44ef7c4SIbrahim Tilki 528a44ef7c4SIbrahim Tilki /* Convert from INT_PLUS_MICRO to FRACTIONAL_LOG2 */ 529a44ef7c4SIbrahim Tilki val2 = val2 * DIV_ROUND_CLOSEST(BIT(24), 1000000); 530a44ef7c4SIbrahim Tilki val2 = DIV_ROUND_CLOSEST(scale_avail[0], val2); 531a44ef7c4SIbrahim Tilki gain = order_base_2(val2); 532a44ef7c4SIbrahim Tilki 533a44ef7c4SIbrahim Tilki st->channels[chan->address].gain = clamp_val(gain, 0, 7); 534a44ef7c4SIbrahim Tilki 535a44ef7c4SIbrahim Tilki iio_device_release_direct_mode(indio_dev); 536a44ef7c4SIbrahim Tilki 537a44ef7c4SIbrahim Tilki return 0; 538a44ef7c4SIbrahim Tilki case IIO_CHAN_INFO_SAMP_FREQ: 539a44ef7c4SIbrahim Tilki ret = iio_device_claim_direct_mode(indio_dev); 540a44ef7c4SIbrahim Tilki if (ret) 541a44ef7c4SIbrahim Tilki return ret; 542a44ef7c4SIbrahim Tilki 543a44ef7c4SIbrahim Tilki mutex_lock(&st->lock); 544a44ef7c4SIbrahim Tilki 545a44ef7c4SIbrahim Tilki ret = regmap_read(st->regmap, MAX11410_REG_FILTER, ®_val); 546a44ef7c4SIbrahim Tilki if (ret) 547a44ef7c4SIbrahim Tilki goto out; 548a44ef7c4SIbrahim Tilki 549a44ef7c4SIbrahim Tilki filter = FIELD_GET(MAX11410_FILTER_LINEF_MASK, reg_val); 550a44ef7c4SIbrahim Tilki 551a44ef7c4SIbrahim Tilki for (i = 0; i < max11410_sampling_len[filter]; ++i) { 552a44ef7c4SIbrahim Tilki if (val == max11410_sampling_rates[filter][i][0] && 553a44ef7c4SIbrahim Tilki val2 == max11410_sampling_rates[filter][i][1]) 554a44ef7c4SIbrahim Tilki break; 555a44ef7c4SIbrahim Tilki } 556a44ef7c4SIbrahim Tilki if (i == max11410_sampling_len[filter]) { 557a44ef7c4SIbrahim Tilki ret = -EINVAL; 558a44ef7c4SIbrahim Tilki goto out; 559a44ef7c4SIbrahim Tilki } 560a44ef7c4SIbrahim Tilki 561a44ef7c4SIbrahim Tilki ret = regmap_write_bits(st->regmap, MAX11410_REG_FILTER, 562a44ef7c4SIbrahim Tilki MAX11410_FILTER_RATE_MASK, i); 563a44ef7c4SIbrahim Tilki 564a44ef7c4SIbrahim Tilki out: 565a44ef7c4SIbrahim Tilki mutex_unlock(&st->lock); 566a44ef7c4SIbrahim Tilki iio_device_release_direct_mode(indio_dev); 567a44ef7c4SIbrahim Tilki 568a44ef7c4SIbrahim Tilki return ret; 569a44ef7c4SIbrahim Tilki default: 570a44ef7c4SIbrahim Tilki return -EINVAL; 571a44ef7c4SIbrahim Tilki } 572a44ef7c4SIbrahim Tilki } 573a44ef7c4SIbrahim Tilki 574a44ef7c4SIbrahim Tilki static int max11410_read_avail(struct iio_dev *indio_dev, 575a44ef7c4SIbrahim Tilki struct iio_chan_spec const *chan, 576a44ef7c4SIbrahim Tilki const int **vals, int *type, int *length, 577a44ef7c4SIbrahim Tilki long info) 578a44ef7c4SIbrahim Tilki { 579a44ef7c4SIbrahim Tilki struct max11410_state *st = iio_priv(indio_dev); 580a44ef7c4SIbrahim Tilki struct max11410_channel_config cfg; 581a44ef7c4SIbrahim Tilki int ret, reg_val, filter; 582a44ef7c4SIbrahim Tilki 583a44ef7c4SIbrahim Tilki switch (info) { 584a44ef7c4SIbrahim Tilki case IIO_CHAN_INFO_SAMP_FREQ: 585a44ef7c4SIbrahim Tilki ret = regmap_read(st->regmap, MAX11410_REG_FILTER, ®_val); 586a44ef7c4SIbrahim Tilki if (ret) 587a44ef7c4SIbrahim Tilki return ret; 588a44ef7c4SIbrahim Tilki 589a44ef7c4SIbrahim Tilki filter = FIELD_GET(MAX11410_FILTER_LINEF_MASK, reg_val); 590a44ef7c4SIbrahim Tilki 591a44ef7c4SIbrahim Tilki *vals = (const int *)max11410_sampling_rates[filter]; 592a44ef7c4SIbrahim Tilki *length = max11410_sampling_len[filter] * 2; 593a44ef7c4SIbrahim Tilki *type = IIO_VAL_INT_PLUS_MICRO; 594a44ef7c4SIbrahim Tilki 595a44ef7c4SIbrahim Tilki return IIO_AVAIL_LIST; 596a44ef7c4SIbrahim Tilki case IIO_CHAN_INFO_SCALE: 597a44ef7c4SIbrahim Tilki cfg = st->channels[chan->address]; 598a44ef7c4SIbrahim Tilki 599a44ef7c4SIbrahim Tilki if (!cfg.scale_avail) 600a44ef7c4SIbrahim Tilki return -EINVAL; 601a44ef7c4SIbrahim Tilki 602a44ef7c4SIbrahim Tilki *vals = cfg.scale_avail; 603a44ef7c4SIbrahim Tilki *length = MAX11410_SCALE_AVAIL_SIZE * 2; 604a44ef7c4SIbrahim Tilki *type = IIO_VAL_FRACTIONAL_LOG2; 605a44ef7c4SIbrahim Tilki 606a44ef7c4SIbrahim Tilki return IIO_AVAIL_LIST; 607a44ef7c4SIbrahim Tilki } 608a44ef7c4SIbrahim Tilki return -EINVAL; 609a44ef7c4SIbrahim Tilki } 610a44ef7c4SIbrahim Tilki 611a44ef7c4SIbrahim Tilki static const struct iio_info max11410_info = { 612a44ef7c4SIbrahim Tilki .read_raw = max11410_read_raw, 613a44ef7c4SIbrahim Tilki .write_raw = max11410_write_raw, 614a44ef7c4SIbrahim Tilki .read_avail = max11410_read_avail, 615a44ef7c4SIbrahim Tilki .attrs = &max11410_attribute_group, 616a44ef7c4SIbrahim Tilki }; 617a44ef7c4SIbrahim Tilki 618a44ef7c4SIbrahim Tilki static irqreturn_t max11410_trigger_handler(int irq, void *p) 619a44ef7c4SIbrahim Tilki { 620a44ef7c4SIbrahim Tilki struct iio_poll_func *pf = p; 621a44ef7c4SIbrahim Tilki struct iio_dev *indio_dev = pf->indio_dev; 622a44ef7c4SIbrahim Tilki struct max11410_state *st = iio_priv(indio_dev); 623a44ef7c4SIbrahim Tilki int ret; 624a44ef7c4SIbrahim Tilki 625a44ef7c4SIbrahim Tilki ret = max11410_read_reg(st, MAX11410_REG_DATA0, &st->scan.data); 626a44ef7c4SIbrahim Tilki if (ret) { 627a44ef7c4SIbrahim Tilki dev_err(&indio_dev->dev, "cannot read data\n"); 628a44ef7c4SIbrahim Tilki goto out; 629a44ef7c4SIbrahim Tilki } 630a44ef7c4SIbrahim Tilki 631a44ef7c4SIbrahim Tilki iio_push_to_buffers_with_timestamp(indio_dev, &st->scan, 632a44ef7c4SIbrahim Tilki iio_get_time_ns(indio_dev)); 633a44ef7c4SIbrahim Tilki 634a44ef7c4SIbrahim Tilki out: 635a44ef7c4SIbrahim Tilki iio_trigger_notify_done(indio_dev->trig); 636a44ef7c4SIbrahim Tilki 637a44ef7c4SIbrahim Tilki return IRQ_HANDLED; 638a44ef7c4SIbrahim Tilki } 639a44ef7c4SIbrahim Tilki 640a44ef7c4SIbrahim Tilki static int max11410_buffer_postenable(struct iio_dev *indio_dev) 641a44ef7c4SIbrahim Tilki { 642a44ef7c4SIbrahim Tilki struct max11410_state *st = iio_priv(indio_dev); 643a44ef7c4SIbrahim Tilki int scan_ch, ret; 644a44ef7c4SIbrahim Tilki 645a44ef7c4SIbrahim Tilki scan_ch = ffs(*indio_dev->active_scan_mask) - 1; 646a44ef7c4SIbrahim Tilki 647a44ef7c4SIbrahim Tilki ret = max11410_configure_channel(st, &indio_dev->channels[scan_ch]); 648a44ef7c4SIbrahim Tilki if (ret) 649a44ef7c4SIbrahim Tilki return ret; 650a44ef7c4SIbrahim Tilki 651a44ef7c4SIbrahim Tilki /* Start continuous conversion. */ 652a44ef7c4SIbrahim Tilki return max11410_write_reg(st, MAX11410_REG_CONV_START, 653a44ef7c4SIbrahim Tilki MAX11410_CONV_TYPE_CONTINUOUS); 654a44ef7c4SIbrahim Tilki } 655a44ef7c4SIbrahim Tilki 656a44ef7c4SIbrahim Tilki static int max11410_buffer_predisable(struct iio_dev *indio_dev) 657a44ef7c4SIbrahim Tilki { 658a44ef7c4SIbrahim Tilki struct max11410_state *st = iio_priv(indio_dev); 659a44ef7c4SIbrahim Tilki 660a44ef7c4SIbrahim Tilki /* Stop continuous conversion. */ 661a44ef7c4SIbrahim Tilki return max11410_write_reg(st, MAX11410_REG_CONV_START, 662a44ef7c4SIbrahim Tilki MAX11410_CONV_TYPE_SINGLE); 663a44ef7c4SIbrahim Tilki } 664a44ef7c4SIbrahim Tilki 665a44ef7c4SIbrahim Tilki static const struct iio_buffer_setup_ops max11410_buffer_ops = { 666a44ef7c4SIbrahim Tilki .postenable = &max11410_buffer_postenable, 667a44ef7c4SIbrahim Tilki .predisable = &max11410_buffer_predisable, 668a44ef7c4SIbrahim Tilki .validate_scan_mask = &iio_validate_scan_mask_onehot, 669a44ef7c4SIbrahim Tilki }; 670a44ef7c4SIbrahim Tilki 671a44ef7c4SIbrahim Tilki static const struct iio_trigger_ops max11410_trigger_ops = { 672a44ef7c4SIbrahim Tilki .validate_device = iio_trigger_validate_own_device, 673a44ef7c4SIbrahim Tilki }; 674a44ef7c4SIbrahim Tilki 675a44ef7c4SIbrahim Tilki static irqreturn_t max11410_interrupt(int irq, void *dev_id) 676a44ef7c4SIbrahim Tilki { 677a44ef7c4SIbrahim Tilki struct iio_dev *indio_dev = dev_id; 678a44ef7c4SIbrahim Tilki struct max11410_state *st = iio_priv(indio_dev); 679a44ef7c4SIbrahim Tilki 680a44ef7c4SIbrahim Tilki if (iio_buffer_enabled(indio_dev)) 681a44ef7c4SIbrahim Tilki iio_trigger_poll_chained(st->trig); 682a44ef7c4SIbrahim Tilki else 683a44ef7c4SIbrahim Tilki complete(&st->completion); 684a44ef7c4SIbrahim Tilki 685a44ef7c4SIbrahim Tilki return IRQ_HANDLED; 686a44ef7c4SIbrahim Tilki }; 687a44ef7c4SIbrahim Tilki 688a44ef7c4SIbrahim Tilki static int max11410_parse_channels(struct max11410_state *st, 689a44ef7c4SIbrahim Tilki struct iio_dev *indio_dev) 690a44ef7c4SIbrahim Tilki { 691a44ef7c4SIbrahim Tilki struct iio_chan_spec chanspec = chanspec_template; 692a44ef7c4SIbrahim Tilki struct device *dev = &st->spi_dev->dev; 693a44ef7c4SIbrahim Tilki struct max11410_channel_config *cfg; 694a44ef7c4SIbrahim Tilki struct iio_chan_spec *channels; 695a44ef7c4SIbrahim Tilki struct fwnode_handle *child; 696a44ef7c4SIbrahim Tilki u32 reference, sig_path; 697a44ef7c4SIbrahim Tilki const char *node_name; 698a44ef7c4SIbrahim Tilki u32 inputs[2], scale; 699a44ef7c4SIbrahim Tilki unsigned int num_ch; 700a44ef7c4SIbrahim Tilki int chan_idx = 0; 701a44ef7c4SIbrahim Tilki int ret, i; 702a44ef7c4SIbrahim Tilki 703a44ef7c4SIbrahim Tilki num_ch = device_get_child_node_count(dev); 704a44ef7c4SIbrahim Tilki if (num_ch == 0) 705a44ef7c4SIbrahim Tilki return dev_err_probe(&indio_dev->dev, -ENODEV, 706a44ef7c4SIbrahim Tilki "FW has no channels defined\n"); 707a44ef7c4SIbrahim Tilki 708a44ef7c4SIbrahim Tilki /* Reserve space for soft timestamp channel */ 709a44ef7c4SIbrahim Tilki num_ch++; 710a44ef7c4SIbrahim Tilki channels = devm_kcalloc(dev, num_ch, sizeof(*channels), GFP_KERNEL); 711a44ef7c4SIbrahim Tilki if (!channels) 712a44ef7c4SIbrahim Tilki return -ENOMEM; 713a44ef7c4SIbrahim Tilki 714a44ef7c4SIbrahim Tilki st->channels = devm_kcalloc(dev, num_ch, sizeof(*st->channels), 715a44ef7c4SIbrahim Tilki GFP_KERNEL); 716a44ef7c4SIbrahim Tilki if (!st->channels) 717a44ef7c4SIbrahim Tilki return -ENOMEM; 718a44ef7c4SIbrahim Tilki 719a44ef7c4SIbrahim Tilki device_for_each_child_node(dev, child) { 720a44ef7c4SIbrahim Tilki node_name = fwnode_get_name(child); 721a44ef7c4SIbrahim Tilki if (fwnode_property_present(child, "diff-channels")) { 722a44ef7c4SIbrahim Tilki ret = fwnode_property_read_u32_array(child, 723a44ef7c4SIbrahim Tilki "diff-channels", 724a44ef7c4SIbrahim Tilki inputs, 725a44ef7c4SIbrahim Tilki ARRAY_SIZE(inputs)); 726a44ef7c4SIbrahim Tilki 727a44ef7c4SIbrahim Tilki chanspec.differential = 1; 728a44ef7c4SIbrahim Tilki } else { 729a44ef7c4SIbrahim Tilki ret = fwnode_property_read_u32(child, "reg", &inputs[0]); 730a44ef7c4SIbrahim Tilki 731a44ef7c4SIbrahim Tilki inputs[1] = 0; 732a44ef7c4SIbrahim Tilki chanspec.differential = 0; 733a44ef7c4SIbrahim Tilki } 734a44ef7c4SIbrahim Tilki if (ret) { 735a44ef7c4SIbrahim Tilki fwnode_handle_put(child); 736a44ef7c4SIbrahim Tilki return ret; 737a44ef7c4SIbrahim Tilki } 738a44ef7c4SIbrahim Tilki 739a44ef7c4SIbrahim Tilki if (inputs[0] > MAX11410_CHANNEL_INDEX_MAX || 740a44ef7c4SIbrahim Tilki inputs[1] > MAX11410_CHANNEL_INDEX_MAX) { 741a44ef7c4SIbrahim Tilki fwnode_handle_put(child); 742a44ef7c4SIbrahim Tilki return dev_err_probe(&indio_dev->dev, -EINVAL, 743a44ef7c4SIbrahim Tilki "Invalid channel index for %s, should be less than %d\n", 744a44ef7c4SIbrahim Tilki node_name, 745a44ef7c4SIbrahim Tilki MAX11410_CHANNEL_INDEX_MAX + 1); 746a44ef7c4SIbrahim Tilki } 747a44ef7c4SIbrahim Tilki 748a44ef7c4SIbrahim Tilki cfg = &st->channels[chan_idx]; 749a44ef7c4SIbrahim Tilki 750a44ef7c4SIbrahim Tilki reference = MAX11410_REFSEL_AVDD_AGND; 751a44ef7c4SIbrahim Tilki fwnode_property_read_u32(child, "adi,reference", &reference); 752a44ef7c4SIbrahim Tilki if (reference > MAX11410_REFSEL_MAX) { 753a44ef7c4SIbrahim Tilki fwnode_handle_put(child); 754a44ef7c4SIbrahim Tilki return dev_err_probe(&indio_dev->dev, -EINVAL, 755a44ef7c4SIbrahim Tilki "Invalid adi,reference value for %s, should be less than %d.\n", 756a44ef7c4SIbrahim Tilki node_name, MAX11410_REFSEL_MAX + 1); 757a44ef7c4SIbrahim Tilki } 758a44ef7c4SIbrahim Tilki 759a44ef7c4SIbrahim Tilki if (!max11410_get_vrefp(st, reference) || 760a44ef7c4SIbrahim Tilki (!max11410_get_vrefn(st, reference) && reference <= 2)) { 761a44ef7c4SIbrahim Tilki fwnode_handle_put(child); 762a44ef7c4SIbrahim Tilki return dev_err_probe(&indio_dev->dev, -EINVAL, 763a44ef7c4SIbrahim Tilki "Invalid VREF configuration for %s, either specify corresponding VREF regulators or change adi,reference property.\n", 764a44ef7c4SIbrahim Tilki node_name); 765a44ef7c4SIbrahim Tilki } 766a44ef7c4SIbrahim Tilki 767a44ef7c4SIbrahim Tilki sig_path = MAX11410_PGA_SIG_PATH_BUFFERED; 768a44ef7c4SIbrahim Tilki fwnode_property_read_u32(child, "adi,input-mode", &sig_path); 769a44ef7c4SIbrahim Tilki if (sig_path > MAX11410_SIG_PATH_MAX) { 770a44ef7c4SIbrahim Tilki fwnode_handle_put(child); 771a44ef7c4SIbrahim Tilki return dev_err_probe(&indio_dev->dev, -EINVAL, 772a44ef7c4SIbrahim Tilki "Invalid adi,input-mode value for %s, should be less than %d.\n", 773a44ef7c4SIbrahim Tilki node_name, MAX11410_SIG_PATH_MAX + 1); 774a44ef7c4SIbrahim Tilki } 775a44ef7c4SIbrahim Tilki 776a44ef7c4SIbrahim Tilki fwnode_property_read_u32(child, "settling-time-us", 777a44ef7c4SIbrahim Tilki &cfg->settling_time_us); 778a44ef7c4SIbrahim Tilki cfg->bipolar = fwnode_property_read_bool(child, "bipolar"); 779a44ef7c4SIbrahim Tilki cfg->buffered_vrefp = fwnode_property_read_bool(child, "adi,buffered-vrefp"); 780a44ef7c4SIbrahim Tilki cfg->buffered_vrefn = fwnode_property_read_bool(child, "adi,buffered-vrefn"); 781a44ef7c4SIbrahim Tilki cfg->refsel = reference; 782a44ef7c4SIbrahim Tilki cfg->sig_path = sig_path; 783a44ef7c4SIbrahim Tilki cfg->gain = 0; 784a44ef7c4SIbrahim Tilki 785a44ef7c4SIbrahim Tilki /* Enable scale_available property if input mode is PGA */ 786a44ef7c4SIbrahim Tilki if (sig_path == MAX11410_PGA_SIG_PATH_PGA) { 787a44ef7c4SIbrahim Tilki __set_bit(IIO_CHAN_INFO_SCALE, 788a44ef7c4SIbrahim Tilki &chanspec.info_mask_separate_available); 789a44ef7c4SIbrahim Tilki cfg->scale_avail = devm_kcalloc(dev, MAX11410_SCALE_AVAIL_SIZE * 2, 790a44ef7c4SIbrahim Tilki sizeof(*cfg->scale_avail), 791a44ef7c4SIbrahim Tilki GFP_KERNEL); 792a44ef7c4SIbrahim Tilki if (!cfg->scale_avail) { 793a44ef7c4SIbrahim Tilki fwnode_handle_put(child); 794a44ef7c4SIbrahim Tilki return -ENOMEM; 795a44ef7c4SIbrahim Tilki } 796a44ef7c4SIbrahim Tilki 797a44ef7c4SIbrahim Tilki scale = max11410_get_scale(st, *cfg); 798a44ef7c4SIbrahim Tilki for (i = 0; i < MAX11410_SCALE_AVAIL_SIZE; i++) { 799a44ef7c4SIbrahim Tilki cfg->scale_avail[2 * i] = scale >> i; 800a44ef7c4SIbrahim Tilki cfg->scale_avail[2 * i + 1] = chanspec.scan_type.realbits; 801a44ef7c4SIbrahim Tilki } 802a44ef7c4SIbrahim Tilki } else { 803a44ef7c4SIbrahim Tilki __clear_bit(IIO_CHAN_INFO_SCALE, 804a44ef7c4SIbrahim Tilki &chanspec.info_mask_separate_available); 805a44ef7c4SIbrahim Tilki } 806a44ef7c4SIbrahim Tilki 807a44ef7c4SIbrahim Tilki chanspec.address = chan_idx; 808a44ef7c4SIbrahim Tilki chanspec.scan_index = chan_idx; 809a44ef7c4SIbrahim Tilki chanspec.channel = inputs[0]; 810a44ef7c4SIbrahim Tilki chanspec.channel2 = inputs[1]; 811a44ef7c4SIbrahim Tilki 812a44ef7c4SIbrahim Tilki channels[chan_idx] = chanspec; 813a44ef7c4SIbrahim Tilki chan_idx++; 814a44ef7c4SIbrahim Tilki } 815a44ef7c4SIbrahim Tilki 816a44ef7c4SIbrahim Tilki channels[chan_idx] = (struct iio_chan_spec)IIO_CHAN_SOFT_TIMESTAMP(chan_idx); 817a44ef7c4SIbrahim Tilki 818a44ef7c4SIbrahim Tilki indio_dev->num_channels = chan_idx + 1; 819a44ef7c4SIbrahim Tilki indio_dev->channels = channels; 820a44ef7c4SIbrahim Tilki 821a44ef7c4SIbrahim Tilki return 0; 822a44ef7c4SIbrahim Tilki } 823a44ef7c4SIbrahim Tilki 824a44ef7c4SIbrahim Tilki static void max11410_disable_reg(void *reg) 825a44ef7c4SIbrahim Tilki { 826a44ef7c4SIbrahim Tilki regulator_disable(reg); 827a44ef7c4SIbrahim Tilki } 828a44ef7c4SIbrahim Tilki 829a44ef7c4SIbrahim Tilki static int max11410_init_vref(struct device *dev, 830a44ef7c4SIbrahim Tilki struct regulator **vref, 831a44ef7c4SIbrahim Tilki const char *id) 832a44ef7c4SIbrahim Tilki { 833a44ef7c4SIbrahim Tilki struct regulator *reg; 834a44ef7c4SIbrahim Tilki int ret; 835a44ef7c4SIbrahim Tilki 836a44ef7c4SIbrahim Tilki reg = devm_regulator_get_optional(dev, id); 837a44ef7c4SIbrahim Tilki if (PTR_ERR(reg) == -ENODEV) { 838a44ef7c4SIbrahim Tilki *vref = NULL; 839a44ef7c4SIbrahim Tilki return 0; 840a44ef7c4SIbrahim Tilki } else if (IS_ERR(reg)) { 841a44ef7c4SIbrahim Tilki return PTR_ERR(reg); 842a44ef7c4SIbrahim Tilki } 843a44ef7c4SIbrahim Tilki ret = regulator_enable(reg); 844a44ef7c4SIbrahim Tilki if (ret) 845a44ef7c4SIbrahim Tilki return dev_err_probe(dev, ret, 846a44ef7c4SIbrahim Tilki "Failed to enable regulator %s\n", id); 847a44ef7c4SIbrahim Tilki 848a44ef7c4SIbrahim Tilki *vref = reg; 849a44ef7c4SIbrahim Tilki return devm_add_action_or_reset(dev, max11410_disable_reg, reg); 850a44ef7c4SIbrahim Tilki } 851a44ef7c4SIbrahim Tilki 852a44ef7c4SIbrahim Tilki static int max11410_calibrate(struct max11410_state *st, u32 cal_type) 853a44ef7c4SIbrahim Tilki { 854a44ef7c4SIbrahim Tilki int ret, val; 855a44ef7c4SIbrahim Tilki 856a44ef7c4SIbrahim Tilki ret = max11410_write_reg(st, MAX11410_REG_CAL_START, cal_type); 857a44ef7c4SIbrahim Tilki if (ret) 858a44ef7c4SIbrahim Tilki return ret; 859a44ef7c4SIbrahim Tilki 860a44ef7c4SIbrahim Tilki /* Wait for status register Calibration Ready flag */ 861a44ef7c4SIbrahim Tilki return read_poll_timeout(max11410_read_reg, ret, 862a44ef7c4SIbrahim Tilki ret || (val & MAX11410_STATUS_CAL_READY_BIT), 863a44ef7c4SIbrahim Tilki 50000, MAX11410_CALIB_TIMEOUT_MS * 1000, true, 864a44ef7c4SIbrahim Tilki st, MAX11410_REG_STATUS, &val); 865a44ef7c4SIbrahim Tilki } 866a44ef7c4SIbrahim Tilki 867a44ef7c4SIbrahim Tilki static int max11410_self_calibrate(struct max11410_state *st) 868a44ef7c4SIbrahim Tilki { 869a44ef7c4SIbrahim Tilki int ret, i; 870a44ef7c4SIbrahim Tilki 871a44ef7c4SIbrahim Tilki ret = regmap_write_bits(st->regmap, MAX11410_REG_FILTER, 872a44ef7c4SIbrahim Tilki MAX11410_FILTER_RATE_MASK, 873a44ef7c4SIbrahim Tilki FIELD_PREP(MAX11410_FILTER_RATE_MASK, 874a44ef7c4SIbrahim Tilki MAX11410_FILTER_RATE_MAX)); 875a44ef7c4SIbrahim Tilki if (ret) 876a44ef7c4SIbrahim Tilki return ret; 877a44ef7c4SIbrahim Tilki 878a44ef7c4SIbrahim Tilki ret = max11410_calibrate(st, MAX11410_CAL_START_SELF); 879a44ef7c4SIbrahim Tilki if (ret) 880a44ef7c4SIbrahim Tilki return ret; 881a44ef7c4SIbrahim Tilki 882a44ef7c4SIbrahim Tilki ret = regmap_write_bits(st->regmap, MAX11410_REG_PGA, 883a44ef7c4SIbrahim Tilki MAX11410_PGA_SIG_PATH_MASK, 884a44ef7c4SIbrahim Tilki FIELD_PREP(MAX11410_PGA_SIG_PATH_MASK, 885a44ef7c4SIbrahim Tilki MAX11410_PGA_SIG_PATH_PGA)); 886a44ef7c4SIbrahim Tilki if (ret) 887a44ef7c4SIbrahim Tilki return ret; 888a44ef7c4SIbrahim Tilki 889a44ef7c4SIbrahim Tilki /* PGA calibrations */ 890a44ef7c4SIbrahim Tilki for (i = 1; i < 8; ++i) { 891a44ef7c4SIbrahim Tilki ret = regmap_write_bits(st->regmap, MAX11410_REG_PGA, 892a44ef7c4SIbrahim Tilki MAX11410_PGA_GAIN_MASK, i); 893a44ef7c4SIbrahim Tilki if (ret) 894a44ef7c4SIbrahim Tilki return ret; 895a44ef7c4SIbrahim Tilki 896a44ef7c4SIbrahim Tilki ret = max11410_calibrate(st, MAX11410_CAL_START_PGA); 897a44ef7c4SIbrahim Tilki if (ret) 898a44ef7c4SIbrahim Tilki return ret; 899a44ef7c4SIbrahim Tilki } 900a44ef7c4SIbrahim Tilki 901a44ef7c4SIbrahim Tilki /* Cleanup */ 902a44ef7c4SIbrahim Tilki ret = regmap_write_bits(st->regmap, MAX11410_REG_PGA, 903a44ef7c4SIbrahim Tilki MAX11410_PGA_GAIN_MASK, 0); 904a44ef7c4SIbrahim Tilki if (ret) 905a44ef7c4SIbrahim Tilki return ret; 906a44ef7c4SIbrahim Tilki 907a44ef7c4SIbrahim Tilki ret = regmap_write_bits(st->regmap, MAX11410_REG_FILTER, 908a44ef7c4SIbrahim Tilki MAX11410_FILTER_RATE_MASK, 0); 909a44ef7c4SIbrahim Tilki if (ret) 910a44ef7c4SIbrahim Tilki return ret; 911a44ef7c4SIbrahim Tilki 912a44ef7c4SIbrahim Tilki return regmap_write_bits(st->regmap, MAX11410_REG_PGA, 913a44ef7c4SIbrahim Tilki MAX11410_PGA_SIG_PATH_MASK, 914a44ef7c4SIbrahim Tilki FIELD_PREP(MAX11410_PGA_SIG_PATH_MASK, 915a44ef7c4SIbrahim Tilki MAX11410_PGA_SIG_PATH_BUFFERED)); 916a44ef7c4SIbrahim Tilki } 917a44ef7c4SIbrahim Tilki 918a44ef7c4SIbrahim Tilki static int max11410_probe(struct spi_device *spi) 919a44ef7c4SIbrahim Tilki { 920a44ef7c4SIbrahim Tilki const char *vrefp_regs[] = { "vref0p", "vref1p", "vref2p" }; 921a44ef7c4SIbrahim Tilki const char *vrefn_regs[] = { "vref0n", "vref1n", "vref2n" }; 922a44ef7c4SIbrahim Tilki struct device *dev = &spi->dev; 923a44ef7c4SIbrahim Tilki struct max11410_state *st; 924a44ef7c4SIbrahim Tilki struct iio_dev *indio_dev; 925a44ef7c4SIbrahim Tilki int ret, irqs[2]; 926a44ef7c4SIbrahim Tilki int i; 927a44ef7c4SIbrahim Tilki 928a44ef7c4SIbrahim Tilki indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); 929a44ef7c4SIbrahim Tilki if (!indio_dev) 930a44ef7c4SIbrahim Tilki return -ENOMEM; 931a44ef7c4SIbrahim Tilki 932a44ef7c4SIbrahim Tilki st = iio_priv(indio_dev); 933a44ef7c4SIbrahim Tilki st->spi_dev = spi; 934a44ef7c4SIbrahim Tilki init_completion(&st->completion); 935a44ef7c4SIbrahim Tilki mutex_init(&st->lock); 936a44ef7c4SIbrahim Tilki 937a44ef7c4SIbrahim Tilki indio_dev->name = "max11410"; 938a44ef7c4SIbrahim Tilki indio_dev->modes = INDIO_DIRECT_MODE; 939a44ef7c4SIbrahim Tilki indio_dev->info = &max11410_info; 940a44ef7c4SIbrahim Tilki 941a44ef7c4SIbrahim Tilki st->regmap = devm_regmap_init_spi(spi, ®map_config); 942a44ef7c4SIbrahim Tilki if (IS_ERR(st->regmap)) 943a44ef7c4SIbrahim Tilki return dev_err_probe(dev, PTR_ERR(st->regmap), 944a44ef7c4SIbrahim Tilki "regmap initialization failed\n"); 945a44ef7c4SIbrahim Tilki 946a44ef7c4SIbrahim Tilki ret = max11410_init_vref(dev, &st->avdd, "avdd"); 947a44ef7c4SIbrahim Tilki if (ret) 948a44ef7c4SIbrahim Tilki return ret; 949a44ef7c4SIbrahim Tilki 950a44ef7c4SIbrahim Tilki for (i = 0; i < ARRAY_SIZE(vrefp_regs); i++) { 951a44ef7c4SIbrahim Tilki ret = max11410_init_vref(dev, &st->vrefp[i], vrefp_regs[i]); 952a44ef7c4SIbrahim Tilki if (ret) 953a44ef7c4SIbrahim Tilki return ret; 954a44ef7c4SIbrahim Tilki 955a44ef7c4SIbrahim Tilki ret = max11410_init_vref(dev, &st->vrefn[i], vrefn_regs[i]); 956a44ef7c4SIbrahim Tilki if (ret) 957a44ef7c4SIbrahim Tilki return ret; 958a44ef7c4SIbrahim Tilki } 959a44ef7c4SIbrahim Tilki 960a44ef7c4SIbrahim Tilki /* 961a44ef7c4SIbrahim Tilki * Regulators must be configured before parsing channels for 962a44ef7c4SIbrahim Tilki * validating "adi,reference" property of each channel. 963a44ef7c4SIbrahim Tilki */ 964a44ef7c4SIbrahim Tilki ret = max11410_parse_channels(st, indio_dev); 965a44ef7c4SIbrahim Tilki if (ret) 966a44ef7c4SIbrahim Tilki return ret; 967a44ef7c4SIbrahim Tilki 968a44ef7c4SIbrahim Tilki irqs[0] = fwnode_irq_get_byname(dev_fwnode(dev), "gpio0"); 969a44ef7c4SIbrahim Tilki irqs[1] = fwnode_irq_get_byname(dev_fwnode(dev), "gpio1"); 970a44ef7c4SIbrahim Tilki 971a44ef7c4SIbrahim Tilki if (irqs[0] > 0) { 972a44ef7c4SIbrahim Tilki st->irq = irqs[0]; 973a44ef7c4SIbrahim Tilki ret = regmap_write(st->regmap, MAX11410_REG_GPIO_CTRL(0), 974a44ef7c4SIbrahim Tilki MAX11410_GPIO_INTRB); 975a44ef7c4SIbrahim Tilki } else if (irqs[1] > 0) { 976a44ef7c4SIbrahim Tilki st->irq = irqs[1]; 977a44ef7c4SIbrahim Tilki ret = regmap_write(st->regmap, MAX11410_REG_GPIO_CTRL(1), 978a44ef7c4SIbrahim Tilki MAX11410_GPIO_INTRB); 979a44ef7c4SIbrahim Tilki } else if (spi->irq > 0) { 980a44ef7c4SIbrahim Tilki return dev_err_probe(dev, -ENODEV, 981a44ef7c4SIbrahim Tilki "no interrupt name specified"); 982a44ef7c4SIbrahim Tilki } 983a44ef7c4SIbrahim Tilki 984a44ef7c4SIbrahim Tilki if (ret) 985a44ef7c4SIbrahim Tilki return ret; 986a44ef7c4SIbrahim Tilki 987a44ef7c4SIbrahim Tilki ret = regmap_set_bits(st->regmap, MAX11410_REG_CTRL, 988a44ef7c4SIbrahim Tilki MAX11410_CTRL_FORMAT_BIT); 989a44ef7c4SIbrahim Tilki if (ret) 990a44ef7c4SIbrahim Tilki return ret; 991a44ef7c4SIbrahim Tilki 992a44ef7c4SIbrahim Tilki ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, 993a44ef7c4SIbrahim Tilki &max11410_trigger_handler, 994a44ef7c4SIbrahim Tilki &max11410_buffer_ops); 995a44ef7c4SIbrahim Tilki if (ret) 996a44ef7c4SIbrahim Tilki return ret; 997a44ef7c4SIbrahim Tilki 998a44ef7c4SIbrahim Tilki if (st->irq > 0) { 999a44ef7c4SIbrahim Tilki st->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", 1000a44ef7c4SIbrahim Tilki indio_dev->name, 1001a44ef7c4SIbrahim Tilki iio_device_id(indio_dev)); 1002a44ef7c4SIbrahim Tilki if (!st->trig) 1003a44ef7c4SIbrahim Tilki return -ENOMEM; 1004a44ef7c4SIbrahim Tilki 1005a44ef7c4SIbrahim Tilki st->trig->ops = &max11410_trigger_ops; 1006a44ef7c4SIbrahim Tilki ret = devm_iio_trigger_register(dev, st->trig); 1007a44ef7c4SIbrahim Tilki if (ret) 1008a44ef7c4SIbrahim Tilki return ret; 1009a44ef7c4SIbrahim Tilki 1010a44ef7c4SIbrahim Tilki ret = devm_request_threaded_irq(dev, st->irq, NULL, 1011a44ef7c4SIbrahim Tilki &max11410_interrupt, 1012a44ef7c4SIbrahim Tilki IRQF_ONESHOT, "max11410", 1013a44ef7c4SIbrahim Tilki indio_dev); 1014a44ef7c4SIbrahim Tilki if (ret) 1015a44ef7c4SIbrahim Tilki return ret; 1016a44ef7c4SIbrahim Tilki } 1017a44ef7c4SIbrahim Tilki 1018a44ef7c4SIbrahim Tilki ret = max11410_self_calibrate(st); 1019a44ef7c4SIbrahim Tilki if (ret) 1020a44ef7c4SIbrahim Tilki return dev_err_probe(dev, ret, 1021a44ef7c4SIbrahim Tilki "cannot perform device self calibration\n"); 1022a44ef7c4SIbrahim Tilki 1023a44ef7c4SIbrahim Tilki return devm_iio_device_register(dev, indio_dev); 1024a44ef7c4SIbrahim Tilki } 1025a44ef7c4SIbrahim Tilki 1026a44ef7c4SIbrahim Tilki static const struct of_device_id max11410_spi_of_id[] = { 1027a44ef7c4SIbrahim Tilki { .compatible = "adi,max11410" }, 1028a44ef7c4SIbrahim Tilki { } 1029a44ef7c4SIbrahim Tilki }; 1030a44ef7c4SIbrahim Tilki MODULE_DEVICE_TABLE(of, max11410_spi_of_id); 1031a44ef7c4SIbrahim Tilki 1032a44ef7c4SIbrahim Tilki static const struct spi_device_id max11410_id[] = { 1033a44ef7c4SIbrahim Tilki { "max11410" }, 1034a44ef7c4SIbrahim Tilki { } 1035a44ef7c4SIbrahim Tilki }; 1036a44ef7c4SIbrahim Tilki MODULE_DEVICE_TABLE(spi, max11410_id); 1037a44ef7c4SIbrahim Tilki 1038a44ef7c4SIbrahim Tilki static struct spi_driver max11410_driver = { 1039a44ef7c4SIbrahim Tilki .driver = { 1040a44ef7c4SIbrahim Tilki .name = "max11410", 1041a44ef7c4SIbrahim Tilki .of_match_table = max11410_spi_of_id, 1042a44ef7c4SIbrahim Tilki }, 1043a44ef7c4SIbrahim Tilki .probe = max11410_probe, 1044a44ef7c4SIbrahim Tilki .id_table = max11410_id, 1045a44ef7c4SIbrahim Tilki }; 1046a44ef7c4SIbrahim Tilki module_spi_driver(max11410_driver); 1047a44ef7c4SIbrahim Tilki 1048a44ef7c4SIbrahim Tilki MODULE_AUTHOR("David Jung <David.Jung@analog.com>"); 1049a44ef7c4SIbrahim Tilki MODULE_AUTHOR("Ibrahim Tilki <Ibrahim.Tilki@analog.com>"); 1050a44ef7c4SIbrahim Tilki MODULE_DESCRIPTION("Analog Devices MAX11410 ADC"); 1051a44ef7c4SIbrahim Tilki MODULE_LICENSE("GPL"); 1052