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