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 | 37399b43a15SIbrahim 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 { 416*7b3825e9SNuno Sá int ret2; 417*7b3825e9SNuno Sá 418a44ef7c4SIbrahim Tilki /* Wait for status register Conversion Ready flag */ 419*7b3825e9SNuno Sá ret = read_poll_timeout(max11410_read_reg, ret2, 420*7b3825e9SNuno Sá ret2 || (val & MAX11410_STATUS_CONV_READY_BIT), 421a44ef7c4SIbrahim Tilki 5000, MAX11410_CONVERSION_TIMEOUT_MS * 1000, 422a44ef7c4SIbrahim Tilki true, st, MAX11410_REG_STATUS, &val); 423a44ef7c4SIbrahim Tilki if (ret) 424a44ef7c4SIbrahim Tilki return ret; 425*7b3825e9SNuno Sá if (ret2) 426*7b3825e9SNuno Sá return ret2; 427a44ef7c4SIbrahim Tilki } 428a44ef7c4SIbrahim Tilki 429a44ef7c4SIbrahim Tilki /* Read ADC Data */ 430a44ef7c4SIbrahim Tilki return max11410_read_reg(st, MAX11410_REG_DATA0, sample_raw); 431a44ef7c4SIbrahim Tilki } 432a44ef7c4SIbrahim Tilki 433a44ef7c4SIbrahim Tilki static int max11410_get_scale(struct max11410_state *state, 434a44ef7c4SIbrahim Tilki struct max11410_channel_config cfg) 435a44ef7c4SIbrahim Tilki { 436a44ef7c4SIbrahim Tilki struct regulator *vrefp, *vrefn; 437a44ef7c4SIbrahim Tilki int scale; 438a44ef7c4SIbrahim Tilki 439a44ef7c4SIbrahim Tilki vrefp = max11410_get_vrefp(state, cfg.refsel); 440a44ef7c4SIbrahim Tilki 441a44ef7c4SIbrahim Tilki scale = regulator_get_voltage(vrefp) / 1000; 442a44ef7c4SIbrahim Tilki vrefn = max11410_get_vrefn(state, cfg.refsel); 443a44ef7c4SIbrahim Tilki if (vrefn) 444a44ef7c4SIbrahim Tilki scale -= regulator_get_voltage(vrefn) / 1000; 445a44ef7c4SIbrahim Tilki 446a44ef7c4SIbrahim Tilki if (cfg.bipolar) 447a44ef7c4SIbrahim Tilki scale *= 2; 448a44ef7c4SIbrahim Tilki 449a44ef7c4SIbrahim Tilki return scale >> cfg.gain; 450a44ef7c4SIbrahim Tilki } 451a44ef7c4SIbrahim Tilki 452a44ef7c4SIbrahim Tilki static int max11410_read_raw(struct iio_dev *indio_dev, 453a44ef7c4SIbrahim Tilki struct iio_chan_spec const *chan, 454a44ef7c4SIbrahim Tilki int *val, int *val2, long info) 455a44ef7c4SIbrahim Tilki { 456a44ef7c4SIbrahim Tilki struct max11410_state *state = iio_priv(indio_dev); 457a44ef7c4SIbrahim Tilki struct max11410_channel_config cfg = state->channels[chan->address]; 458a44ef7c4SIbrahim Tilki int ret, reg_val, filter, rate; 459a44ef7c4SIbrahim Tilki 460a44ef7c4SIbrahim Tilki switch (info) { 461a44ef7c4SIbrahim Tilki case IIO_CHAN_INFO_SCALE: 462a44ef7c4SIbrahim Tilki *val = max11410_get_scale(state, cfg); 463a44ef7c4SIbrahim Tilki *val2 = chan->scan_type.realbits; 464a44ef7c4SIbrahim Tilki return IIO_VAL_FRACTIONAL_LOG2; 465a44ef7c4SIbrahim Tilki case IIO_CHAN_INFO_OFFSET: 466a44ef7c4SIbrahim Tilki if (cfg.bipolar) 467a44ef7c4SIbrahim Tilki *val = -BIT(chan->scan_type.realbits - 1); 468a44ef7c4SIbrahim Tilki else 469a44ef7c4SIbrahim Tilki *val = 0; 470a44ef7c4SIbrahim Tilki 471a44ef7c4SIbrahim Tilki return IIO_VAL_INT; 472a44ef7c4SIbrahim Tilki case IIO_CHAN_INFO_RAW: 473a44ef7c4SIbrahim Tilki ret = iio_device_claim_direct_mode(indio_dev); 474a44ef7c4SIbrahim Tilki if (ret) 475a44ef7c4SIbrahim Tilki return ret; 476a44ef7c4SIbrahim Tilki 477a44ef7c4SIbrahim Tilki mutex_lock(&state->lock); 478a44ef7c4SIbrahim Tilki 479a44ef7c4SIbrahim Tilki ret = max11410_sample(state, ®_val, chan); 480a44ef7c4SIbrahim Tilki 481a44ef7c4SIbrahim Tilki mutex_unlock(&state->lock); 482a44ef7c4SIbrahim Tilki 483a44ef7c4SIbrahim Tilki iio_device_release_direct_mode(indio_dev); 484a44ef7c4SIbrahim Tilki 485a44ef7c4SIbrahim Tilki if (ret) 486a44ef7c4SIbrahim Tilki return ret; 487a44ef7c4SIbrahim Tilki 488a44ef7c4SIbrahim Tilki *val = reg_val; 489a44ef7c4SIbrahim Tilki 490a44ef7c4SIbrahim Tilki return IIO_VAL_INT; 491a44ef7c4SIbrahim Tilki case IIO_CHAN_INFO_SAMP_FREQ: 492a44ef7c4SIbrahim Tilki ret = regmap_read(state->regmap, MAX11410_REG_FILTER, ®_val); 493a44ef7c4SIbrahim Tilki if (ret) 494a44ef7c4SIbrahim Tilki return ret; 495a44ef7c4SIbrahim Tilki 496a44ef7c4SIbrahim Tilki filter = FIELD_GET(MAX11410_FILTER_LINEF_MASK, reg_val); 497a44ef7c4SIbrahim Tilki rate = reg_val & MAX11410_FILTER_RATE_MASK; 498a44ef7c4SIbrahim Tilki if (rate >= max11410_sampling_len[filter]) 499a44ef7c4SIbrahim Tilki rate = max11410_sampling_len[filter] - 1; 500a44ef7c4SIbrahim Tilki 501a44ef7c4SIbrahim Tilki *val = max11410_sampling_rates[filter][rate][0]; 502a44ef7c4SIbrahim Tilki *val2 = max11410_sampling_rates[filter][rate][1]; 503a44ef7c4SIbrahim Tilki 504a44ef7c4SIbrahim Tilki return IIO_VAL_INT_PLUS_MICRO; 505a44ef7c4SIbrahim Tilki } 506a44ef7c4SIbrahim Tilki return -EINVAL; 507a44ef7c4SIbrahim Tilki } 508a44ef7c4SIbrahim Tilki 509a44ef7c4SIbrahim Tilki static int max11410_write_raw(struct iio_dev *indio_dev, 510a44ef7c4SIbrahim Tilki struct iio_chan_spec const *chan, 511a44ef7c4SIbrahim Tilki int val, int val2, long mask) 512a44ef7c4SIbrahim Tilki { 513a44ef7c4SIbrahim Tilki struct max11410_state *st = iio_priv(indio_dev); 514a44ef7c4SIbrahim Tilki int i, ret, reg_val, filter, gain; 515a44ef7c4SIbrahim Tilki u32 *scale_avail; 516a44ef7c4SIbrahim Tilki 517a44ef7c4SIbrahim Tilki switch (mask) { 518a44ef7c4SIbrahim Tilki case IIO_CHAN_INFO_SCALE: 519a44ef7c4SIbrahim Tilki scale_avail = st->channels[chan->address].scale_avail; 520a44ef7c4SIbrahim Tilki if (!scale_avail) 521a44ef7c4SIbrahim Tilki return -EOPNOTSUPP; 522a44ef7c4SIbrahim Tilki 523a44ef7c4SIbrahim Tilki /* Accept values in range 0.000001 <= scale < 1.000000 */ 524a44ef7c4SIbrahim Tilki if (val != 0 || val2 == 0) 525a44ef7c4SIbrahim Tilki return -EINVAL; 526a44ef7c4SIbrahim Tilki 527a44ef7c4SIbrahim Tilki ret = iio_device_claim_direct_mode(indio_dev); 528a44ef7c4SIbrahim Tilki if (ret) 529a44ef7c4SIbrahim Tilki return ret; 530a44ef7c4SIbrahim Tilki 531a44ef7c4SIbrahim Tilki /* Convert from INT_PLUS_MICRO to FRACTIONAL_LOG2 */ 532a44ef7c4SIbrahim Tilki val2 = val2 * DIV_ROUND_CLOSEST(BIT(24), 1000000); 533a44ef7c4SIbrahim Tilki val2 = DIV_ROUND_CLOSEST(scale_avail[0], val2); 534a44ef7c4SIbrahim Tilki gain = order_base_2(val2); 535a44ef7c4SIbrahim Tilki 536a44ef7c4SIbrahim Tilki st->channels[chan->address].gain = clamp_val(gain, 0, 7); 537a44ef7c4SIbrahim Tilki 538a44ef7c4SIbrahim Tilki iio_device_release_direct_mode(indio_dev); 539a44ef7c4SIbrahim Tilki 540a44ef7c4SIbrahim Tilki return 0; 541a44ef7c4SIbrahim Tilki case IIO_CHAN_INFO_SAMP_FREQ: 542a44ef7c4SIbrahim Tilki ret = iio_device_claim_direct_mode(indio_dev); 543a44ef7c4SIbrahim Tilki if (ret) 544a44ef7c4SIbrahim Tilki return ret; 545a44ef7c4SIbrahim Tilki 546a44ef7c4SIbrahim Tilki mutex_lock(&st->lock); 547a44ef7c4SIbrahim Tilki 548a44ef7c4SIbrahim Tilki ret = regmap_read(st->regmap, MAX11410_REG_FILTER, ®_val); 549a44ef7c4SIbrahim Tilki if (ret) 550a44ef7c4SIbrahim Tilki goto out; 551a44ef7c4SIbrahim Tilki 552a44ef7c4SIbrahim Tilki filter = FIELD_GET(MAX11410_FILTER_LINEF_MASK, reg_val); 553a44ef7c4SIbrahim Tilki 554a44ef7c4SIbrahim Tilki for (i = 0; i < max11410_sampling_len[filter]; ++i) { 555a44ef7c4SIbrahim Tilki if (val == max11410_sampling_rates[filter][i][0] && 556a44ef7c4SIbrahim Tilki val2 == max11410_sampling_rates[filter][i][1]) 557a44ef7c4SIbrahim Tilki break; 558a44ef7c4SIbrahim Tilki } 559a44ef7c4SIbrahim Tilki if (i == max11410_sampling_len[filter]) { 560a44ef7c4SIbrahim Tilki ret = -EINVAL; 561a44ef7c4SIbrahim Tilki goto out; 562a44ef7c4SIbrahim Tilki } 563a44ef7c4SIbrahim Tilki 564a44ef7c4SIbrahim Tilki ret = regmap_write_bits(st->regmap, MAX11410_REG_FILTER, 565a44ef7c4SIbrahim Tilki MAX11410_FILTER_RATE_MASK, i); 566a44ef7c4SIbrahim Tilki 567a44ef7c4SIbrahim Tilki out: 568a44ef7c4SIbrahim Tilki mutex_unlock(&st->lock); 569a44ef7c4SIbrahim Tilki iio_device_release_direct_mode(indio_dev); 570a44ef7c4SIbrahim Tilki 571a44ef7c4SIbrahim Tilki return ret; 572a44ef7c4SIbrahim Tilki default: 573a44ef7c4SIbrahim Tilki return -EINVAL; 574a44ef7c4SIbrahim Tilki } 575a44ef7c4SIbrahim Tilki } 576a44ef7c4SIbrahim Tilki 577a44ef7c4SIbrahim Tilki static int max11410_read_avail(struct iio_dev *indio_dev, 578a44ef7c4SIbrahim Tilki struct iio_chan_spec const *chan, 579a44ef7c4SIbrahim Tilki const int **vals, int *type, int *length, 580a44ef7c4SIbrahim Tilki long info) 581a44ef7c4SIbrahim Tilki { 582a44ef7c4SIbrahim Tilki struct max11410_state *st = iio_priv(indio_dev); 583a44ef7c4SIbrahim Tilki struct max11410_channel_config cfg; 584a44ef7c4SIbrahim Tilki int ret, reg_val, filter; 585a44ef7c4SIbrahim Tilki 586a44ef7c4SIbrahim Tilki switch (info) { 587a44ef7c4SIbrahim Tilki case IIO_CHAN_INFO_SAMP_FREQ: 588a44ef7c4SIbrahim Tilki ret = regmap_read(st->regmap, MAX11410_REG_FILTER, ®_val); 589a44ef7c4SIbrahim Tilki if (ret) 590a44ef7c4SIbrahim Tilki return ret; 591a44ef7c4SIbrahim Tilki 592a44ef7c4SIbrahim Tilki filter = FIELD_GET(MAX11410_FILTER_LINEF_MASK, reg_val); 593a44ef7c4SIbrahim Tilki 594a44ef7c4SIbrahim Tilki *vals = (const int *)max11410_sampling_rates[filter]; 595a44ef7c4SIbrahim Tilki *length = max11410_sampling_len[filter] * 2; 596a44ef7c4SIbrahim Tilki *type = IIO_VAL_INT_PLUS_MICRO; 597a44ef7c4SIbrahim Tilki 598a44ef7c4SIbrahim Tilki return IIO_AVAIL_LIST; 599a44ef7c4SIbrahim Tilki case IIO_CHAN_INFO_SCALE: 600a44ef7c4SIbrahim Tilki cfg = st->channels[chan->address]; 601a44ef7c4SIbrahim Tilki 602a44ef7c4SIbrahim Tilki if (!cfg.scale_avail) 603a44ef7c4SIbrahim Tilki return -EINVAL; 604a44ef7c4SIbrahim Tilki 605a44ef7c4SIbrahim Tilki *vals = cfg.scale_avail; 606a44ef7c4SIbrahim Tilki *length = MAX11410_SCALE_AVAIL_SIZE * 2; 607a44ef7c4SIbrahim Tilki *type = IIO_VAL_FRACTIONAL_LOG2; 608a44ef7c4SIbrahim Tilki 609a44ef7c4SIbrahim Tilki return IIO_AVAIL_LIST; 610a44ef7c4SIbrahim Tilki } 611a44ef7c4SIbrahim Tilki return -EINVAL; 612a44ef7c4SIbrahim Tilki } 613a44ef7c4SIbrahim Tilki 614a44ef7c4SIbrahim Tilki static const struct iio_info max11410_info = { 615a44ef7c4SIbrahim Tilki .read_raw = max11410_read_raw, 616a44ef7c4SIbrahim Tilki .write_raw = max11410_write_raw, 617a44ef7c4SIbrahim Tilki .read_avail = max11410_read_avail, 618a44ef7c4SIbrahim Tilki .attrs = &max11410_attribute_group, 619a44ef7c4SIbrahim Tilki }; 620a44ef7c4SIbrahim Tilki 621a44ef7c4SIbrahim Tilki static irqreturn_t max11410_trigger_handler(int irq, void *p) 622a44ef7c4SIbrahim Tilki { 623a44ef7c4SIbrahim Tilki struct iio_poll_func *pf = p; 624a44ef7c4SIbrahim Tilki struct iio_dev *indio_dev = pf->indio_dev; 625a44ef7c4SIbrahim Tilki struct max11410_state *st = iio_priv(indio_dev); 626a44ef7c4SIbrahim Tilki int ret; 627a44ef7c4SIbrahim Tilki 628a44ef7c4SIbrahim Tilki ret = max11410_read_reg(st, MAX11410_REG_DATA0, &st->scan.data); 629a44ef7c4SIbrahim Tilki if (ret) { 630a44ef7c4SIbrahim Tilki dev_err(&indio_dev->dev, "cannot read data\n"); 631a44ef7c4SIbrahim Tilki goto out; 632a44ef7c4SIbrahim Tilki } 633a44ef7c4SIbrahim Tilki 634a44ef7c4SIbrahim Tilki iio_push_to_buffers_with_timestamp(indio_dev, &st->scan, 635a44ef7c4SIbrahim Tilki iio_get_time_ns(indio_dev)); 636a44ef7c4SIbrahim Tilki 637a44ef7c4SIbrahim Tilki out: 638a44ef7c4SIbrahim Tilki iio_trigger_notify_done(indio_dev->trig); 639a44ef7c4SIbrahim Tilki 640a44ef7c4SIbrahim Tilki return IRQ_HANDLED; 641a44ef7c4SIbrahim Tilki } 642a44ef7c4SIbrahim Tilki 643a44ef7c4SIbrahim Tilki static int max11410_buffer_postenable(struct iio_dev *indio_dev) 644a44ef7c4SIbrahim Tilki { 645a44ef7c4SIbrahim Tilki struct max11410_state *st = iio_priv(indio_dev); 646a44ef7c4SIbrahim Tilki int scan_ch, ret; 647a44ef7c4SIbrahim Tilki 648a44ef7c4SIbrahim Tilki scan_ch = ffs(*indio_dev->active_scan_mask) - 1; 649a44ef7c4SIbrahim Tilki 650a44ef7c4SIbrahim Tilki ret = max11410_configure_channel(st, &indio_dev->channels[scan_ch]); 651a44ef7c4SIbrahim Tilki if (ret) 652a44ef7c4SIbrahim Tilki return ret; 653a44ef7c4SIbrahim Tilki 654a44ef7c4SIbrahim Tilki /* Start continuous conversion. */ 655a44ef7c4SIbrahim Tilki return max11410_write_reg(st, MAX11410_REG_CONV_START, 656a44ef7c4SIbrahim Tilki MAX11410_CONV_TYPE_CONTINUOUS); 657a44ef7c4SIbrahim Tilki } 658a44ef7c4SIbrahim Tilki 659a44ef7c4SIbrahim Tilki static int max11410_buffer_predisable(struct iio_dev *indio_dev) 660a44ef7c4SIbrahim Tilki { 661a44ef7c4SIbrahim Tilki struct max11410_state *st = iio_priv(indio_dev); 662a44ef7c4SIbrahim Tilki 663a44ef7c4SIbrahim Tilki /* Stop continuous conversion. */ 664a44ef7c4SIbrahim Tilki return max11410_write_reg(st, MAX11410_REG_CONV_START, 665a44ef7c4SIbrahim Tilki MAX11410_CONV_TYPE_SINGLE); 666a44ef7c4SIbrahim Tilki } 667a44ef7c4SIbrahim Tilki 668a44ef7c4SIbrahim Tilki static const struct iio_buffer_setup_ops max11410_buffer_ops = { 669a44ef7c4SIbrahim Tilki .postenable = &max11410_buffer_postenable, 670a44ef7c4SIbrahim Tilki .predisable = &max11410_buffer_predisable, 671a44ef7c4SIbrahim Tilki .validate_scan_mask = &iio_validate_scan_mask_onehot, 672a44ef7c4SIbrahim Tilki }; 673a44ef7c4SIbrahim Tilki 674a44ef7c4SIbrahim Tilki static const struct iio_trigger_ops max11410_trigger_ops = { 675a44ef7c4SIbrahim Tilki .validate_device = iio_trigger_validate_own_device, 676a44ef7c4SIbrahim Tilki }; 677a44ef7c4SIbrahim Tilki 678a44ef7c4SIbrahim Tilki static irqreturn_t max11410_interrupt(int irq, void *dev_id) 679a44ef7c4SIbrahim Tilki { 680a44ef7c4SIbrahim Tilki struct iio_dev *indio_dev = dev_id; 681a44ef7c4SIbrahim Tilki struct max11410_state *st = iio_priv(indio_dev); 682a44ef7c4SIbrahim Tilki 683a44ef7c4SIbrahim Tilki if (iio_buffer_enabled(indio_dev)) 684a44ef7c4SIbrahim Tilki iio_trigger_poll_chained(st->trig); 685a44ef7c4SIbrahim Tilki else 686a44ef7c4SIbrahim Tilki complete(&st->completion); 687a44ef7c4SIbrahim Tilki 688a44ef7c4SIbrahim Tilki return IRQ_HANDLED; 689a44ef7c4SIbrahim Tilki }; 690a44ef7c4SIbrahim Tilki 691a44ef7c4SIbrahim Tilki static int max11410_parse_channels(struct max11410_state *st, 692a44ef7c4SIbrahim Tilki struct iio_dev *indio_dev) 693a44ef7c4SIbrahim Tilki { 694a44ef7c4SIbrahim Tilki struct iio_chan_spec chanspec = chanspec_template; 695a44ef7c4SIbrahim Tilki struct device *dev = &st->spi_dev->dev; 696a44ef7c4SIbrahim Tilki struct max11410_channel_config *cfg; 697a44ef7c4SIbrahim Tilki struct iio_chan_spec *channels; 698a44ef7c4SIbrahim Tilki struct fwnode_handle *child; 699a44ef7c4SIbrahim Tilki u32 reference, sig_path; 700a44ef7c4SIbrahim Tilki const char *node_name; 701a44ef7c4SIbrahim Tilki u32 inputs[2], scale; 702a44ef7c4SIbrahim Tilki unsigned int num_ch; 703a44ef7c4SIbrahim Tilki int chan_idx = 0; 704a44ef7c4SIbrahim Tilki int ret, i; 705a44ef7c4SIbrahim Tilki 706a44ef7c4SIbrahim Tilki num_ch = device_get_child_node_count(dev); 707a44ef7c4SIbrahim Tilki if (num_ch == 0) 708a44ef7c4SIbrahim Tilki return dev_err_probe(&indio_dev->dev, -ENODEV, 709a44ef7c4SIbrahim Tilki "FW has no channels defined\n"); 710a44ef7c4SIbrahim Tilki 711a44ef7c4SIbrahim Tilki /* Reserve space for soft timestamp channel */ 712a44ef7c4SIbrahim Tilki num_ch++; 713a44ef7c4SIbrahim Tilki channels = devm_kcalloc(dev, num_ch, sizeof(*channels), GFP_KERNEL); 714a44ef7c4SIbrahim Tilki if (!channels) 715a44ef7c4SIbrahim Tilki return -ENOMEM; 716a44ef7c4SIbrahim Tilki 717a44ef7c4SIbrahim Tilki st->channels = devm_kcalloc(dev, num_ch, sizeof(*st->channels), 718a44ef7c4SIbrahim Tilki GFP_KERNEL); 719a44ef7c4SIbrahim Tilki if (!st->channels) 720a44ef7c4SIbrahim Tilki return -ENOMEM; 721a44ef7c4SIbrahim Tilki 722a44ef7c4SIbrahim Tilki device_for_each_child_node(dev, child) { 723a44ef7c4SIbrahim Tilki node_name = fwnode_get_name(child); 724a44ef7c4SIbrahim Tilki if (fwnode_property_present(child, "diff-channels")) { 725a44ef7c4SIbrahim Tilki ret = fwnode_property_read_u32_array(child, 726a44ef7c4SIbrahim Tilki "diff-channels", 727a44ef7c4SIbrahim Tilki inputs, 728a44ef7c4SIbrahim Tilki ARRAY_SIZE(inputs)); 729a44ef7c4SIbrahim Tilki 730a44ef7c4SIbrahim Tilki chanspec.differential = 1; 731a44ef7c4SIbrahim Tilki } else { 732a44ef7c4SIbrahim Tilki ret = fwnode_property_read_u32(child, "reg", &inputs[0]); 733a44ef7c4SIbrahim Tilki 734a44ef7c4SIbrahim Tilki inputs[1] = 0; 735a44ef7c4SIbrahim Tilki chanspec.differential = 0; 736a44ef7c4SIbrahim Tilki } 737a44ef7c4SIbrahim Tilki if (ret) { 738a44ef7c4SIbrahim Tilki fwnode_handle_put(child); 739a44ef7c4SIbrahim Tilki return ret; 740a44ef7c4SIbrahim Tilki } 741a44ef7c4SIbrahim Tilki 742a44ef7c4SIbrahim Tilki if (inputs[0] > MAX11410_CHANNEL_INDEX_MAX || 743a44ef7c4SIbrahim Tilki inputs[1] > MAX11410_CHANNEL_INDEX_MAX) { 744a44ef7c4SIbrahim Tilki fwnode_handle_put(child); 745a44ef7c4SIbrahim Tilki return dev_err_probe(&indio_dev->dev, -EINVAL, 746a44ef7c4SIbrahim Tilki "Invalid channel index for %s, should be less than %d\n", 747a44ef7c4SIbrahim Tilki node_name, 748a44ef7c4SIbrahim Tilki MAX11410_CHANNEL_INDEX_MAX + 1); 749a44ef7c4SIbrahim Tilki } 750a44ef7c4SIbrahim Tilki 751a44ef7c4SIbrahim Tilki cfg = &st->channels[chan_idx]; 752a44ef7c4SIbrahim Tilki 753a44ef7c4SIbrahim Tilki reference = MAX11410_REFSEL_AVDD_AGND; 754a44ef7c4SIbrahim Tilki fwnode_property_read_u32(child, "adi,reference", &reference); 755a44ef7c4SIbrahim Tilki if (reference > MAX11410_REFSEL_MAX) { 756a44ef7c4SIbrahim Tilki fwnode_handle_put(child); 757a44ef7c4SIbrahim Tilki return dev_err_probe(&indio_dev->dev, -EINVAL, 758a44ef7c4SIbrahim Tilki "Invalid adi,reference value for %s, should be less than %d.\n", 759a44ef7c4SIbrahim Tilki node_name, MAX11410_REFSEL_MAX + 1); 760a44ef7c4SIbrahim Tilki } 761a44ef7c4SIbrahim Tilki 762a44ef7c4SIbrahim Tilki if (!max11410_get_vrefp(st, reference) || 763a44ef7c4SIbrahim Tilki (!max11410_get_vrefn(st, reference) && reference <= 2)) { 764a44ef7c4SIbrahim Tilki fwnode_handle_put(child); 765a44ef7c4SIbrahim Tilki return dev_err_probe(&indio_dev->dev, -EINVAL, 766a44ef7c4SIbrahim Tilki "Invalid VREF configuration for %s, either specify corresponding VREF regulators or change adi,reference property.\n", 767a44ef7c4SIbrahim Tilki node_name); 768a44ef7c4SIbrahim Tilki } 769a44ef7c4SIbrahim Tilki 770a44ef7c4SIbrahim Tilki sig_path = MAX11410_PGA_SIG_PATH_BUFFERED; 771a44ef7c4SIbrahim Tilki fwnode_property_read_u32(child, "adi,input-mode", &sig_path); 772a44ef7c4SIbrahim Tilki if (sig_path > MAX11410_SIG_PATH_MAX) { 773a44ef7c4SIbrahim Tilki fwnode_handle_put(child); 774a44ef7c4SIbrahim Tilki return dev_err_probe(&indio_dev->dev, -EINVAL, 775a44ef7c4SIbrahim Tilki "Invalid adi,input-mode value for %s, should be less than %d.\n", 776a44ef7c4SIbrahim Tilki node_name, MAX11410_SIG_PATH_MAX + 1); 777a44ef7c4SIbrahim Tilki } 778a44ef7c4SIbrahim Tilki 779a44ef7c4SIbrahim Tilki fwnode_property_read_u32(child, "settling-time-us", 780a44ef7c4SIbrahim Tilki &cfg->settling_time_us); 781a44ef7c4SIbrahim Tilki cfg->bipolar = fwnode_property_read_bool(child, "bipolar"); 782a44ef7c4SIbrahim Tilki cfg->buffered_vrefp = fwnode_property_read_bool(child, "adi,buffered-vrefp"); 783a44ef7c4SIbrahim Tilki cfg->buffered_vrefn = fwnode_property_read_bool(child, "adi,buffered-vrefn"); 784a44ef7c4SIbrahim Tilki cfg->refsel = reference; 785a44ef7c4SIbrahim Tilki cfg->sig_path = sig_path; 786a44ef7c4SIbrahim Tilki cfg->gain = 0; 787a44ef7c4SIbrahim Tilki 788a44ef7c4SIbrahim Tilki /* Enable scale_available property if input mode is PGA */ 789a44ef7c4SIbrahim Tilki if (sig_path == MAX11410_PGA_SIG_PATH_PGA) { 790a44ef7c4SIbrahim Tilki __set_bit(IIO_CHAN_INFO_SCALE, 791a44ef7c4SIbrahim Tilki &chanspec.info_mask_separate_available); 792a44ef7c4SIbrahim Tilki cfg->scale_avail = devm_kcalloc(dev, MAX11410_SCALE_AVAIL_SIZE * 2, 793a44ef7c4SIbrahim Tilki sizeof(*cfg->scale_avail), 794a44ef7c4SIbrahim Tilki GFP_KERNEL); 795a44ef7c4SIbrahim Tilki if (!cfg->scale_avail) { 796a44ef7c4SIbrahim Tilki fwnode_handle_put(child); 797a44ef7c4SIbrahim Tilki return -ENOMEM; 798a44ef7c4SIbrahim Tilki } 799a44ef7c4SIbrahim Tilki 800a44ef7c4SIbrahim Tilki scale = max11410_get_scale(st, *cfg); 801a44ef7c4SIbrahim Tilki for (i = 0; i < MAX11410_SCALE_AVAIL_SIZE; i++) { 802a44ef7c4SIbrahim Tilki cfg->scale_avail[2 * i] = scale >> i; 803a44ef7c4SIbrahim Tilki cfg->scale_avail[2 * i + 1] = chanspec.scan_type.realbits; 804a44ef7c4SIbrahim Tilki } 805a44ef7c4SIbrahim Tilki } else { 806a44ef7c4SIbrahim Tilki __clear_bit(IIO_CHAN_INFO_SCALE, 807a44ef7c4SIbrahim Tilki &chanspec.info_mask_separate_available); 808a44ef7c4SIbrahim Tilki } 809a44ef7c4SIbrahim Tilki 810a44ef7c4SIbrahim Tilki chanspec.address = chan_idx; 811a44ef7c4SIbrahim Tilki chanspec.scan_index = chan_idx; 812a44ef7c4SIbrahim Tilki chanspec.channel = inputs[0]; 813a44ef7c4SIbrahim Tilki chanspec.channel2 = inputs[1]; 814a44ef7c4SIbrahim Tilki 815a44ef7c4SIbrahim Tilki channels[chan_idx] = chanspec; 816a44ef7c4SIbrahim Tilki chan_idx++; 817a44ef7c4SIbrahim Tilki } 818a44ef7c4SIbrahim Tilki 819a44ef7c4SIbrahim Tilki channels[chan_idx] = (struct iio_chan_spec)IIO_CHAN_SOFT_TIMESTAMP(chan_idx); 820a44ef7c4SIbrahim Tilki 821a44ef7c4SIbrahim Tilki indio_dev->num_channels = chan_idx + 1; 822a44ef7c4SIbrahim Tilki indio_dev->channels = channels; 823a44ef7c4SIbrahim Tilki 824a44ef7c4SIbrahim Tilki return 0; 825a44ef7c4SIbrahim Tilki } 826a44ef7c4SIbrahim Tilki 827a44ef7c4SIbrahim Tilki static void max11410_disable_reg(void *reg) 828a44ef7c4SIbrahim Tilki { 829a44ef7c4SIbrahim Tilki regulator_disable(reg); 830a44ef7c4SIbrahim Tilki } 831a44ef7c4SIbrahim Tilki 832a44ef7c4SIbrahim Tilki static int max11410_init_vref(struct device *dev, 833a44ef7c4SIbrahim Tilki struct regulator **vref, 834a44ef7c4SIbrahim Tilki const char *id) 835a44ef7c4SIbrahim Tilki { 836a44ef7c4SIbrahim Tilki struct regulator *reg; 837a44ef7c4SIbrahim Tilki int ret; 838a44ef7c4SIbrahim Tilki 839a44ef7c4SIbrahim Tilki reg = devm_regulator_get_optional(dev, id); 840a44ef7c4SIbrahim Tilki if (PTR_ERR(reg) == -ENODEV) { 841a44ef7c4SIbrahim Tilki *vref = NULL; 842a44ef7c4SIbrahim Tilki return 0; 843a44ef7c4SIbrahim Tilki } else if (IS_ERR(reg)) { 844a44ef7c4SIbrahim Tilki return PTR_ERR(reg); 845a44ef7c4SIbrahim Tilki } 846a44ef7c4SIbrahim Tilki ret = regulator_enable(reg); 847a44ef7c4SIbrahim Tilki if (ret) 848a44ef7c4SIbrahim Tilki return dev_err_probe(dev, ret, 849a44ef7c4SIbrahim Tilki "Failed to enable regulator %s\n", id); 850a44ef7c4SIbrahim Tilki 851a44ef7c4SIbrahim Tilki *vref = reg; 852a44ef7c4SIbrahim Tilki return devm_add_action_or_reset(dev, max11410_disable_reg, reg); 853a44ef7c4SIbrahim Tilki } 854a44ef7c4SIbrahim Tilki 855a44ef7c4SIbrahim Tilki static int max11410_calibrate(struct max11410_state *st, u32 cal_type) 856a44ef7c4SIbrahim Tilki { 857*7b3825e9SNuno Sá int ret, ret2, val; 858a44ef7c4SIbrahim Tilki 859a44ef7c4SIbrahim Tilki ret = max11410_write_reg(st, MAX11410_REG_CAL_START, cal_type); 860a44ef7c4SIbrahim Tilki if (ret) 861a44ef7c4SIbrahim Tilki return ret; 862a44ef7c4SIbrahim Tilki 863a44ef7c4SIbrahim Tilki /* Wait for status register Calibration Ready flag */ 864*7b3825e9SNuno Sá ret = read_poll_timeout(max11410_read_reg, ret2, 865*7b3825e9SNuno Sá ret2 || (val & MAX11410_STATUS_CAL_READY_BIT), 866a44ef7c4SIbrahim Tilki 50000, MAX11410_CALIB_TIMEOUT_MS * 1000, true, 867a44ef7c4SIbrahim Tilki st, MAX11410_REG_STATUS, &val); 868*7b3825e9SNuno Sá if (ret) 869*7b3825e9SNuno Sá return ret; 870*7b3825e9SNuno Sá 871*7b3825e9SNuno Sá return ret2; 872a44ef7c4SIbrahim Tilki } 873a44ef7c4SIbrahim Tilki 874a44ef7c4SIbrahim Tilki static int max11410_self_calibrate(struct max11410_state *st) 875a44ef7c4SIbrahim Tilki { 876a44ef7c4SIbrahim Tilki int ret, i; 877a44ef7c4SIbrahim Tilki 878a44ef7c4SIbrahim Tilki ret = regmap_write_bits(st->regmap, MAX11410_REG_FILTER, 879a44ef7c4SIbrahim Tilki MAX11410_FILTER_RATE_MASK, 880a44ef7c4SIbrahim Tilki FIELD_PREP(MAX11410_FILTER_RATE_MASK, 881a44ef7c4SIbrahim Tilki MAX11410_FILTER_RATE_MAX)); 882a44ef7c4SIbrahim Tilki if (ret) 883a44ef7c4SIbrahim Tilki return ret; 884a44ef7c4SIbrahim Tilki 885a44ef7c4SIbrahim Tilki ret = max11410_calibrate(st, MAX11410_CAL_START_SELF); 886a44ef7c4SIbrahim Tilki if (ret) 887a44ef7c4SIbrahim Tilki return ret; 888a44ef7c4SIbrahim Tilki 889a44ef7c4SIbrahim Tilki ret = regmap_write_bits(st->regmap, MAX11410_REG_PGA, 890a44ef7c4SIbrahim Tilki MAX11410_PGA_SIG_PATH_MASK, 891a44ef7c4SIbrahim Tilki FIELD_PREP(MAX11410_PGA_SIG_PATH_MASK, 892a44ef7c4SIbrahim Tilki MAX11410_PGA_SIG_PATH_PGA)); 893a44ef7c4SIbrahim Tilki if (ret) 894a44ef7c4SIbrahim Tilki return ret; 895a44ef7c4SIbrahim Tilki 896a44ef7c4SIbrahim Tilki /* PGA calibrations */ 897a44ef7c4SIbrahim Tilki for (i = 1; i < 8; ++i) { 898a44ef7c4SIbrahim Tilki ret = regmap_write_bits(st->regmap, MAX11410_REG_PGA, 899a44ef7c4SIbrahim Tilki MAX11410_PGA_GAIN_MASK, i); 900a44ef7c4SIbrahim Tilki if (ret) 901a44ef7c4SIbrahim Tilki return ret; 902a44ef7c4SIbrahim Tilki 903a44ef7c4SIbrahim Tilki ret = max11410_calibrate(st, MAX11410_CAL_START_PGA); 904a44ef7c4SIbrahim Tilki if (ret) 905a44ef7c4SIbrahim Tilki return ret; 906a44ef7c4SIbrahim Tilki } 907a44ef7c4SIbrahim Tilki 908a44ef7c4SIbrahim Tilki /* Cleanup */ 909a44ef7c4SIbrahim Tilki ret = regmap_write_bits(st->regmap, MAX11410_REG_PGA, 910a44ef7c4SIbrahim Tilki MAX11410_PGA_GAIN_MASK, 0); 911a44ef7c4SIbrahim Tilki if (ret) 912a44ef7c4SIbrahim Tilki return ret; 913a44ef7c4SIbrahim Tilki 914a44ef7c4SIbrahim Tilki ret = regmap_write_bits(st->regmap, MAX11410_REG_FILTER, 915a44ef7c4SIbrahim Tilki MAX11410_FILTER_RATE_MASK, 0); 916a44ef7c4SIbrahim Tilki if (ret) 917a44ef7c4SIbrahim Tilki return ret; 918a44ef7c4SIbrahim Tilki 919a44ef7c4SIbrahim Tilki return regmap_write_bits(st->regmap, MAX11410_REG_PGA, 920a44ef7c4SIbrahim Tilki MAX11410_PGA_SIG_PATH_MASK, 921a44ef7c4SIbrahim Tilki FIELD_PREP(MAX11410_PGA_SIG_PATH_MASK, 922a44ef7c4SIbrahim Tilki MAX11410_PGA_SIG_PATH_BUFFERED)); 923a44ef7c4SIbrahim Tilki } 924a44ef7c4SIbrahim Tilki 925a44ef7c4SIbrahim Tilki static int max11410_probe(struct spi_device *spi) 926a44ef7c4SIbrahim Tilki { 927a44ef7c4SIbrahim Tilki const char *vrefp_regs[] = { "vref0p", "vref1p", "vref2p" }; 928a44ef7c4SIbrahim Tilki const char *vrefn_regs[] = { "vref0n", "vref1n", "vref2n" }; 929a44ef7c4SIbrahim Tilki struct device *dev = &spi->dev; 930a44ef7c4SIbrahim Tilki struct max11410_state *st; 931a44ef7c4SIbrahim Tilki struct iio_dev *indio_dev; 932a44ef7c4SIbrahim Tilki int ret, irqs[2]; 933a44ef7c4SIbrahim Tilki int i; 934a44ef7c4SIbrahim Tilki 935a44ef7c4SIbrahim Tilki indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); 936a44ef7c4SIbrahim Tilki if (!indio_dev) 937a44ef7c4SIbrahim Tilki return -ENOMEM; 938a44ef7c4SIbrahim Tilki 939a44ef7c4SIbrahim Tilki st = iio_priv(indio_dev); 940a44ef7c4SIbrahim Tilki st->spi_dev = spi; 941a44ef7c4SIbrahim Tilki init_completion(&st->completion); 942a44ef7c4SIbrahim Tilki mutex_init(&st->lock); 943a44ef7c4SIbrahim Tilki 944a44ef7c4SIbrahim Tilki indio_dev->name = "max11410"; 945a44ef7c4SIbrahim Tilki indio_dev->modes = INDIO_DIRECT_MODE; 946a44ef7c4SIbrahim Tilki indio_dev->info = &max11410_info; 947a44ef7c4SIbrahim Tilki 948a44ef7c4SIbrahim Tilki st->regmap = devm_regmap_init_spi(spi, ®map_config); 949a44ef7c4SIbrahim Tilki if (IS_ERR(st->regmap)) 950a44ef7c4SIbrahim Tilki return dev_err_probe(dev, PTR_ERR(st->regmap), 951a44ef7c4SIbrahim Tilki "regmap initialization failed\n"); 952a44ef7c4SIbrahim Tilki 953a44ef7c4SIbrahim Tilki ret = max11410_init_vref(dev, &st->avdd, "avdd"); 954a44ef7c4SIbrahim Tilki if (ret) 955a44ef7c4SIbrahim Tilki return ret; 956a44ef7c4SIbrahim Tilki 957a44ef7c4SIbrahim Tilki for (i = 0; i < ARRAY_SIZE(vrefp_regs); i++) { 958a44ef7c4SIbrahim Tilki ret = max11410_init_vref(dev, &st->vrefp[i], vrefp_regs[i]); 959a44ef7c4SIbrahim Tilki if (ret) 960a44ef7c4SIbrahim Tilki return ret; 961a44ef7c4SIbrahim Tilki 962a44ef7c4SIbrahim Tilki ret = max11410_init_vref(dev, &st->vrefn[i], vrefn_regs[i]); 963a44ef7c4SIbrahim Tilki if (ret) 964a44ef7c4SIbrahim Tilki return ret; 965a44ef7c4SIbrahim Tilki } 966a44ef7c4SIbrahim Tilki 967a44ef7c4SIbrahim Tilki /* 968a44ef7c4SIbrahim Tilki * Regulators must be configured before parsing channels for 969a44ef7c4SIbrahim Tilki * validating "adi,reference" property of each channel. 970a44ef7c4SIbrahim Tilki */ 971a44ef7c4SIbrahim Tilki ret = max11410_parse_channels(st, indio_dev); 972a44ef7c4SIbrahim Tilki if (ret) 973a44ef7c4SIbrahim Tilki return ret; 974a44ef7c4SIbrahim Tilki 975a44ef7c4SIbrahim Tilki irqs[0] = fwnode_irq_get_byname(dev_fwnode(dev), "gpio0"); 976a44ef7c4SIbrahim Tilki irqs[1] = fwnode_irq_get_byname(dev_fwnode(dev), "gpio1"); 977a44ef7c4SIbrahim Tilki 978a44ef7c4SIbrahim Tilki if (irqs[0] > 0) { 979a44ef7c4SIbrahim Tilki st->irq = irqs[0]; 980a44ef7c4SIbrahim Tilki ret = regmap_write(st->regmap, MAX11410_REG_GPIO_CTRL(0), 981a44ef7c4SIbrahim Tilki MAX11410_GPIO_INTRB); 982a44ef7c4SIbrahim Tilki } else if (irqs[1] > 0) { 983a44ef7c4SIbrahim Tilki st->irq = irqs[1]; 984a44ef7c4SIbrahim Tilki ret = regmap_write(st->regmap, MAX11410_REG_GPIO_CTRL(1), 985a44ef7c4SIbrahim Tilki MAX11410_GPIO_INTRB); 986a44ef7c4SIbrahim Tilki } else if (spi->irq > 0) { 987a44ef7c4SIbrahim Tilki return dev_err_probe(dev, -ENODEV, 988a44ef7c4SIbrahim Tilki "no interrupt name specified"); 989a44ef7c4SIbrahim Tilki } 990a44ef7c4SIbrahim Tilki 991a44ef7c4SIbrahim Tilki if (ret) 992a44ef7c4SIbrahim Tilki return ret; 993a44ef7c4SIbrahim Tilki 994a44ef7c4SIbrahim Tilki ret = regmap_set_bits(st->regmap, MAX11410_REG_CTRL, 995a44ef7c4SIbrahim Tilki MAX11410_CTRL_FORMAT_BIT); 996a44ef7c4SIbrahim Tilki if (ret) 997a44ef7c4SIbrahim Tilki return ret; 998a44ef7c4SIbrahim Tilki 999a44ef7c4SIbrahim Tilki ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, 1000a44ef7c4SIbrahim Tilki &max11410_trigger_handler, 1001a44ef7c4SIbrahim Tilki &max11410_buffer_ops); 1002a44ef7c4SIbrahim Tilki if (ret) 1003a44ef7c4SIbrahim Tilki return ret; 1004a44ef7c4SIbrahim Tilki 1005a44ef7c4SIbrahim Tilki if (st->irq > 0) { 1006a44ef7c4SIbrahim Tilki st->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", 1007a44ef7c4SIbrahim Tilki indio_dev->name, 1008a44ef7c4SIbrahim Tilki iio_device_id(indio_dev)); 1009a44ef7c4SIbrahim Tilki if (!st->trig) 1010a44ef7c4SIbrahim Tilki return -ENOMEM; 1011a44ef7c4SIbrahim Tilki 1012a44ef7c4SIbrahim Tilki st->trig->ops = &max11410_trigger_ops; 1013a44ef7c4SIbrahim Tilki ret = devm_iio_trigger_register(dev, st->trig); 1014a44ef7c4SIbrahim Tilki if (ret) 1015a44ef7c4SIbrahim Tilki return ret; 1016a44ef7c4SIbrahim Tilki 1017a44ef7c4SIbrahim Tilki ret = devm_request_threaded_irq(dev, st->irq, NULL, 1018a44ef7c4SIbrahim Tilki &max11410_interrupt, 1019a44ef7c4SIbrahim Tilki IRQF_ONESHOT, "max11410", 1020a44ef7c4SIbrahim Tilki indio_dev); 1021a44ef7c4SIbrahim Tilki if (ret) 1022a44ef7c4SIbrahim Tilki return ret; 1023a44ef7c4SIbrahim Tilki } 1024a44ef7c4SIbrahim Tilki 1025a44ef7c4SIbrahim Tilki ret = max11410_self_calibrate(st); 1026a44ef7c4SIbrahim Tilki if (ret) 1027a44ef7c4SIbrahim Tilki return dev_err_probe(dev, ret, 1028a44ef7c4SIbrahim Tilki "cannot perform device self calibration\n"); 1029a44ef7c4SIbrahim Tilki 1030a44ef7c4SIbrahim Tilki return devm_iio_device_register(dev, indio_dev); 1031a44ef7c4SIbrahim Tilki } 1032a44ef7c4SIbrahim Tilki 1033a44ef7c4SIbrahim Tilki static const struct of_device_id max11410_spi_of_id[] = { 1034a44ef7c4SIbrahim Tilki { .compatible = "adi,max11410" }, 1035a44ef7c4SIbrahim Tilki { } 1036a44ef7c4SIbrahim Tilki }; 1037a44ef7c4SIbrahim Tilki MODULE_DEVICE_TABLE(of, max11410_spi_of_id); 1038a44ef7c4SIbrahim Tilki 1039a44ef7c4SIbrahim Tilki static const struct spi_device_id max11410_id[] = { 1040a44ef7c4SIbrahim Tilki { "max11410" }, 1041a44ef7c4SIbrahim Tilki { } 1042a44ef7c4SIbrahim Tilki }; 1043a44ef7c4SIbrahim Tilki MODULE_DEVICE_TABLE(spi, max11410_id); 1044a44ef7c4SIbrahim Tilki 1045a44ef7c4SIbrahim Tilki static struct spi_driver max11410_driver = { 1046a44ef7c4SIbrahim Tilki .driver = { 1047a44ef7c4SIbrahim Tilki .name = "max11410", 1048a44ef7c4SIbrahim Tilki .of_match_table = max11410_spi_of_id, 1049a44ef7c4SIbrahim Tilki }, 1050a44ef7c4SIbrahim Tilki .probe = max11410_probe, 1051a44ef7c4SIbrahim Tilki .id_table = max11410_id, 1052a44ef7c4SIbrahim Tilki }; 1053a44ef7c4SIbrahim Tilki module_spi_driver(max11410_driver); 1054a44ef7c4SIbrahim Tilki 1055a44ef7c4SIbrahim Tilki MODULE_AUTHOR("David Jung <David.Jung@analog.com>"); 1056a44ef7c4SIbrahim Tilki MODULE_AUTHOR("Ibrahim Tilki <Ibrahim.Tilki@analog.com>"); 1057a44ef7c4SIbrahim Tilki MODULE_DESCRIPTION("Analog Devices MAX11410 ADC"); 1058a44ef7c4SIbrahim Tilki MODULE_LICENSE("GPL"); 1059