1fea251b6SCosmin Tanislav // SPDX-License-Identifier: GPL-2.0 2fea251b6SCosmin Tanislav /* 3fea251b6SCosmin Tanislav * Copyright (C) 2021 Analog Devices, Inc. 4fea251b6SCosmin Tanislav * Author: Cosmin Tanislav <cosmin.tanislav@analog.com> 5fea251b6SCosmin Tanislav */ 6fea251b6SCosmin Tanislav 7fea251b6SCosmin Tanislav #include <asm/unaligned.h> 8fea251b6SCosmin Tanislav #include <linux/bitfield.h> 9fea251b6SCosmin Tanislav #include <linux/crc8.h> 10fea251b6SCosmin Tanislav #include <linux/device.h> 11fea251b6SCosmin Tanislav #include <linux/err.h> 12fea251b6SCosmin Tanislav #include <linux/gpio/driver.h> 13fea251b6SCosmin Tanislav #include <linux/iio/buffer.h> 14fea251b6SCosmin Tanislav #include <linux/iio/iio.h> 15fea251b6SCosmin Tanislav #include <linux/iio/sysfs.h> 16fea251b6SCosmin Tanislav #include <linux/iio/trigger.h> 17fea251b6SCosmin Tanislav #include <linux/iio/trigger_consumer.h> 18fea251b6SCosmin Tanislav #include <linux/iio/triggered_buffer.h> 19fea251b6SCosmin Tanislav #include <linux/interrupt.h> 20fea251b6SCosmin Tanislav #include <linux/mod_devicetable.h> 21fea251b6SCosmin Tanislav #include <linux/property.h> 22fea251b6SCosmin Tanislav #include <linux/regmap.h> 23fea251b6SCosmin Tanislav #include <linux/regulator/consumer.h> 24fea251b6SCosmin Tanislav #include <linux/spi/spi.h> 25fea251b6SCosmin Tanislav 26fea251b6SCosmin Tanislav #include <dt-bindings/iio/addac/adi,ad74413r.h> 27fea251b6SCosmin Tanislav 28fea251b6SCosmin Tanislav #define AD74413R_CRC_POLYNOMIAL 0x7 29fea251b6SCosmin Tanislav DECLARE_CRC8_TABLE(ad74413r_crc8_table); 30fea251b6SCosmin Tanislav 31fea251b6SCosmin Tanislav #define AD74413R_CHANNEL_MAX 4 32fea251b6SCosmin Tanislav 33fea251b6SCosmin Tanislav #define AD74413R_FRAME_SIZE 4 34fea251b6SCosmin Tanislav 35fea251b6SCosmin Tanislav struct ad74413r_chip_info { 36fea251b6SCosmin Tanislav const char *name; 37fea251b6SCosmin Tanislav bool hart_support; 38fea251b6SCosmin Tanislav }; 39fea251b6SCosmin Tanislav 40fea251b6SCosmin Tanislav struct ad74413r_channel_config { 41fea251b6SCosmin Tanislav u32 func; 42fea251b6SCosmin Tanislav bool gpo_comparator; 43fea251b6SCosmin Tanislav bool initialized; 44fea251b6SCosmin Tanislav }; 45fea251b6SCosmin Tanislav 46fea251b6SCosmin Tanislav struct ad74413r_channels { 47fea251b6SCosmin Tanislav struct iio_chan_spec *channels; 48fea251b6SCosmin Tanislav unsigned int num_channels; 49fea251b6SCosmin Tanislav }; 50fea251b6SCosmin Tanislav 51fea251b6SCosmin Tanislav struct ad74413r_state { 52fea251b6SCosmin Tanislav struct ad74413r_channel_config channel_configs[AD74413R_CHANNEL_MAX]; 53fea251b6SCosmin Tanislav unsigned int gpo_gpio_offsets[AD74413R_CHANNEL_MAX]; 54fea251b6SCosmin Tanislav unsigned int comp_gpio_offsets[AD74413R_CHANNEL_MAX]; 55fea251b6SCosmin Tanislav struct gpio_chip gpo_gpiochip; 56fea251b6SCosmin Tanislav struct gpio_chip comp_gpiochip; 57fea251b6SCosmin Tanislav struct completion adc_data_completion; 58fea251b6SCosmin Tanislav unsigned int num_gpo_gpios; 59fea251b6SCosmin Tanislav unsigned int num_comparator_gpios; 60fea251b6SCosmin Tanislav u32 sense_resistor_ohms; 61fea251b6SCosmin Tanislav 62fea251b6SCosmin Tanislav /* 63fea251b6SCosmin Tanislav * Synchronize consecutive operations when doing a one-shot 64fea251b6SCosmin Tanislav * conversion and when updating the ADC samples SPI message. 65fea251b6SCosmin Tanislav */ 66fea251b6SCosmin Tanislav struct mutex lock; 67fea251b6SCosmin Tanislav 68fea251b6SCosmin Tanislav const struct ad74413r_chip_info *chip_info; 69fea251b6SCosmin Tanislav struct spi_device *spi; 70fea251b6SCosmin Tanislav struct regulator *refin_reg; 71fea251b6SCosmin Tanislav struct regmap *regmap; 72fea251b6SCosmin Tanislav struct device *dev; 73fea251b6SCosmin Tanislav struct iio_trigger *trig; 74fea251b6SCosmin Tanislav 75fea251b6SCosmin Tanislav size_t adc_active_channels; 76fea251b6SCosmin Tanislav struct spi_message adc_samples_msg; 77fea251b6SCosmin Tanislav struct spi_transfer adc_samples_xfer[AD74413R_CHANNEL_MAX + 1]; 78fea251b6SCosmin Tanislav 79fea251b6SCosmin Tanislav /* 80fea251b6SCosmin Tanislav * DMA (thus cache coherency maintenance) requires the 81fea251b6SCosmin Tanislav * transfer buffers to live in their own cache lines. 82fea251b6SCosmin Tanislav */ 83fea251b6SCosmin Tanislav struct { 84fea251b6SCosmin Tanislav u8 rx_buf[AD74413R_FRAME_SIZE * AD74413R_CHANNEL_MAX]; 85fea251b6SCosmin Tanislav s64 timestamp; 86fea251b6SCosmin Tanislav } adc_samples_buf ____cacheline_aligned; 87fea251b6SCosmin Tanislav 88fea251b6SCosmin Tanislav u8 adc_samples_tx_buf[AD74413R_FRAME_SIZE * AD74413R_CHANNEL_MAX]; 89fea251b6SCosmin Tanislav u8 reg_tx_buf[AD74413R_FRAME_SIZE]; 90fea251b6SCosmin Tanislav u8 reg_rx_buf[AD74413R_FRAME_SIZE]; 91fea251b6SCosmin Tanislav }; 92fea251b6SCosmin Tanislav 93fea251b6SCosmin Tanislav #define AD74413R_REG_NOP 0x00 94fea251b6SCosmin Tanislav 95fea251b6SCosmin Tanislav #define AD74413R_REG_CH_FUNC_SETUP_X(x) (0x01 + (x)) 96fea251b6SCosmin Tanislav #define AD74413R_CH_FUNC_SETUP_MASK GENMASK(3, 0) 97fea251b6SCosmin Tanislav 98fea251b6SCosmin Tanislav #define AD74413R_REG_ADC_CONFIG_X(x) (0x05 + (x)) 99fea251b6SCosmin Tanislav #define AD74413R_ADC_CONFIG_RANGE_MASK GENMASK(7, 5) 100fea251b6SCosmin Tanislav #define AD74413R_ADC_CONFIG_REJECTION_MASK GENMASK(4, 3) 101fea251b6SCosmin Tanislav #define AD74413R_ADC_RANGE_10V 0b000 102fea251b6SCosmin Tanislav #define AD74413R_ADC_RANGE_2P5V_EXT_POW 0b001 103fea251b6SCosmin Tanislav #define AD74413R_ADC_RANGE_2P5V_INT_POW 0b010 104fea251b6SCosmin Tanislav #define AD74413R_ADC_RANGE_5V_BI_DIR 0b011 105fea251b6SCosmin Tanislav #define AD74413R_ADC_REJECTION_50_60 0b00 106fea251b6SCosmin Tanislav #define AD74413R_ADC_REJECTION_NONE 0b01 107fea251b6SCosmin Tanislav #define AD74413R_ADC_REJECTION_50_60_HART 0b10 108fea251b6SCosmin Tanislav #define AD74413R_ADC_REJECTION_HART 0b11 109fea251b6SCosmin Tanislav 110fea251b6SCosmin Tanislav #define AD74413R_REG_DIN_CONFIG_X(x) (0x09 + (x)) 111fea251b6SCosmin Tanislav #define AD74413R_DIN_DEBOUNCE_MASK GENMASK(4, 0) 112fea251b6SCosmin Tanislav #define AD74413R_DIN_DEBOUNCE_LEN BIT(5) 113fea251b6SCosmin Tanislav 114fea251b6SCosmin Tanislav #define AD74413R_REG_DAC_CODE_X(x) (0x16 + (x)) 115fea251b6SCosmin Tanislav #define AD74413R_DAC_CODE_MAX GENMASK(12, 0) 116fea251b6SCosmin Tanislav #define AD74413R_DAC_VOLTAGE_MAX 11000 117fea251b6SCosmin Tanislav 118fea251b6SCosmin Tanislav #define AD74413R_REG_GPO_PAR_DATA 0x0d 119fea251b6SCosmin Tanislav #define AD74413R_REG_GPO_CONFIG_X(x) (0x0e + (x)) 120fea251b6SCosmin Tanislav #define AD74413R_GPO_CONFIG_DATA_MASK BIT(3) 121fea251b6SCosmin Tanislav #define AD74413R_GPO_CONFIG_SELECT_MASK GENMASK(2, 0) 122fea251b6SCosmin Tanislav #define AD74413R_GPO_CONFIG_100K_PULL_DOWN 0b000 123fea251b6SCosmin Tanislav #define AD74413R_GPO_CONFIG_LOGIC 0b001 124fea251b6SCosmin Tanislav #define AD74413R_GPO_CONFIG_LOGIC_PARALLEL 0b010 125fea251b6SCosmin Tanislav #define AD74413R_GPO_CONFIG_COMPARATOR 0b011 126fea251b6SCosmin Tanislav #define AD74413R_GPO_CONFIG_HIGH_IMPEDANCE 0b100 127fea251b6SCosmin Tanislav 128fea251b6SCosmin Tanislav #define AD74413R_REG_ADC_CONV_CTRL 0x23 129fea251b6SCosmin Tanislav #define AD74413R_CONV_SEQ_MASK GENMASK(9, 8) 130fea251b6SCosmin Tanislav #define AD74413R_CONV_SEQ_ON 0b00 131fea251b6SCosmin Tanislav #define AD74413R_CONV_SEQ_SINGLE 0b01 132fea251b6SCosmin Tanislav #define AD74413R_CONV_SEQ_CONTINUOUS 0b10 133fea251b6SCosmin Tanislav #define AD74413R_CONV_SEQ_OFF 0b11 134fea251b6SCosmin Tanislav #define AD74413R_CH_EN_MASK(x) BIT(x) 135fea251b6SCosmin Tanislav 136fea251b6SCosmin Tanislav #define AD74413R_REG_DIN_COMP_OUT 0x25 137fea251b6SCosmin Tanislav 138fea251b6SCosmin Tanislav #define AD74413R_REG_ADC_RESULT_X(x) (0x26 + (x)) 139fea251b6SCosmin Tanislav #define AD74413R_ADC_RESULT_MAX GENMASK(15, 0) 140fea251b6SCosmin Tanislav 141fea251b6SCosmin Tanislav #define AD74413R_REG_READ_SELECT 0x41 142fea251b6SCosmin Tanislav 143fea251b6SCosmin Tanislav #define AD74413R_REG_CMD_KEY 0x44 144fea251b6SCosmin Tanislav #define AD74413R_CMD_KEY_LDAC 0x953a 145fea251b6SCosmin Tanislav #define AD74413R_CMD_KEY_RESET1 0x15fa 146fea251b6SCosmin Tanislav #define AD74413R_CMD_KEY_RESET2 0xaf51 147fea251b6SCosmin Tanislav 148fea251b6SCosmin Tanislav static const int ad74413r_adc_sampling_rates[] = { 149fea251b6SCosmin Tanislav 20, 4800, 150fea251b6SCosmin Tanislav }; 151fea251b6SCosmin Tanislav 152fea251b6SCosmin Tanislav static const int ad74413r_adc_sampling_rates_hart[] = { 153fea251b6SCosmin Tanislav 10, 20, 1200, 4800, 154fea251b6SCosmin Tanislav }; 155fea251b6SCosmin Tanislav 156fea251b6SCosmin Tanislav static int ad74413r_crc(u8 *buf) 157fea251b6SCosmin Tanislav { 158fea251b6SCosmin Tanislav return crc8(ad74413r_crc8_table, buf, 3, 0); 159fea251b6SCosmin Tanislav } 160fea251b6SCosmin Tanislav 161fea251b6SCosmin Tanislav static void ad74413r_format_reg_write(u8 reg, u16 val, u8 *buf) 162fea251b6SCosmin Tanislav { 163fea251b6SCosmin Tanislav buf[0] = reg; 164fea251b6SCosmin Tanislav put_unaligned_be16(val, &buf[1]); 165fea251b6SCosmin Tanislav buf[3] = ad74413r_crc(buf); 166fea251b6SCosmin Tanislav } 167fea251b6SCosmin Tanislav 168fea251b6SCosmin Tanislav static int ad74413r_reg_write(void *context, unsigned int reg, unsigned int val) 169fea251b6SCosmin Tanislav { 170fea251b6SCosmin Tanislav struct ad74413r_state *st = context; 171fea251b6SCosmin Tanislav 172fea251b6SCosmin Tanislav ad74413r_format_reg_write(reg, val, st->reg_tx_buf); 173fea251b6SCosmin Tanislav 174fea251b6SCosmin Tanislav return spi_write(st->spi, st->reg_tx_buf, AD74413R_FRAME_SIZE); 175fea251b6SCosmin Tanislav } 176fea251b6SCosmin Tanislav 177fea251b6SCosmin Tanislav static int ad74413r_crc_check(struct ad74413r_state *st, u8 *buf) 178fea251b6SCosmin Tanislav { 179fea251b6SCosmin Tanislav u8 expected_crc = ad74413r_crc(buf); 180fea251b6SCosmin Tanislav 181fea251b6SCosmin Tanislav if (buf[3] != expected_crc) { 182fea251b6SCosmin Tanislav dev_err(st->dev, "Bad CRC %02x for %02x%02x%02x\n", 183fea251b6SCosmin Tanislav buf[3], buf[0], buf[1], buf[2]); 184fea251b6SCosmin Tanislav return -EINVAL; 185fea251b6SCosmin Tanislav } 186fea251b6SCosmin Tanislav 187fea251b6SCosmin Tanislav return 0; 188fea251b6SCosmin Tanislav } 189fea251b6SCosmin Tanislav 190fea251b6SCosmin Tanislav static int ad74413r_reg_read(void *context, unsigned int reg, unsigned int *val) 191fea251b6SCosmin Tanislav { 192fea251b6SCosmin Tanislav struct ad74413r_state *st = context; 193fea251b6SCosmin Tanislav struct spi_transfer reg_read_xfer[] = { 194fea251b6SCosmin Tanislav { 195fea251b6SCosmin Tanislav .tx_buf = st->reg_tx_buf, 196fea251b6SCosmin Tanislav .len = AD74413R_FRAME_SIZE, 197fea251b6SCosmin Tanislav .cs_change = 1, 198fea251b6SCosmin Tanislav }, 199fea251b6SCosmin Tanislav { 200fea251b6SCosmin Tanislav .rx_buf = st->reg_rx_buf, 201fea251b6SCosmin Tanislav .len = AD74413R_FRAME_SIZE, 202fea251b6SCosmin Tanislav }, 203fea251b6SCosmin Tanislav }; 204fea251b6SCosmin Tanislav int ret; 205fea251b6SCosmin Tanislav 206fea251b6SCosmin Tanislav ad74413r_format_reg_write(AD74413R_REG_READ_SELECT, reg, 207fea251b6SCosmin Tanislav st->reg_tx_buf); 208fea251b6SCosmin Tanislav 209fea251b6SCosmin Tanislav ret = spi_sync_transfer(st->spi, reg_read_xfer, 210fea251b6SCosmin Tanislav ARRAY_SIZE(reg_read_xfer)); 211fea251b6SCosmin Tanislav if (ret) 212fea251b6SCosmin Tanislav return ret; 213fea251b6SCosmin Tanislav 214fea251b6SCosmin Tanislav ret = ad74413r_crc_check(st, st->reg_rx_buf); 215fea251b6SCosmin Tanislav if (ret) 216fea251b6SCosmin Tanislav return ret; 217fea251b6SCosmin Tanislav 218fea251b6SCosmin Tanislav *val = get_unaligned_be16(&st->reg_rx_buf[1]); 219fea251b6SCosmin Tanislav 220fea251b6SCosmin Tanislav return 0; 221fea251b6SCosmin Tanislav } 222fea251b6SCosmin Tanislav 223fea251b6SCosmin Tanislav static const struct regmap_config ad74413r_regmap_config = { 224fea251b6SCosmin Tanislav .reg_bits = 8, 225fea251b6SCosmin Tanislav .val_bits = 16, 226fea251b6SCosmin Tanislav .reg_read = ad74413r_reg_read, 227fea251b6SCosmin Tanislav .reg_write = ad74413r_reg_write, 228fea251b6SCosmin Tanislav }; 229fea251b6SCosmin Tanislav 230fea251b6SCosmin Tanislav static int ad74413r_set_gpo_config(struct ad74413r_state *st, 231fea251b6SCosmin Tanislav unsigned int offset, u8 mode) 232fea251b6SCosmin Tanislav { 233fea251b6SCosmin Tanislav return regmap_update_bits(st->regmap, AD74413R_REG_GPO_CONFIG_X(offset), 234fea251b6SCosmin Tanislav AD74413R_GPO_CONFIG_SELECT_MASK, mode); 235fea251b6SCosmin Tanislav } 236fea251b6SCosmin Tanislav 237fea251b6SCosmin Tanislav static const unsigned int ad74413r_debounce_map[AD74413R_DIN_DEBOUNCE_LEN] = { 238fea251b6SCosmin Tanislav 0, 13, 18, 24, 32, 42, 56, 75, 239fea251b6SCosmin Tanislav 100, 130, 180, 240, 320, 420, 560, 750, 240fea251b6SCosmin Tanislav 1000, 1300, 1800, 2400, 3200, 4200, 5600, 7500, 241fea251b6SCosmin Tanislav 10000, 13000, 18000, 24000, 32000, 42000, 56000, 75000, 242fea251b6SCosmin Tanislav }; 243fea251b6SCosmin Tanislav 244fea251b6SCosmin Tanislav static int ad74413r_set_comp_debounce(struct ad74413r_state *st, 245fea251b6SCosmin Tanislav unsigned int offset, 246fea251b6SCosmin Tanislav unsigned int debounce) 247fea251b6SCosmin Tanislav { 248fea251b6SCosmin Tanislav unsigned int val = AD74413R_DIN_DEBOUNCE_LEN - 1; 249fea251b6SCosmin Tanislav unsigned int i; 250fea251b6SCosmin Tanislav 251fea251b6SCosmin Tanislav for (i = 0; i < AD74413R_DIN_DEBOUNCE_LEN; i++) 252fea251b6SCosmin Tanislav if (debounce <= ad74413r_debounce_map[i]) { 253fea251b6SCosmin Tanislav val = i; 254fea251b6SCosmin Tanislav break; 255fea251b6SCosmin Tanislav } 256fea251b6SCosmin Tanislav 257fea251b6SCosmin Tanislav return regmap_update_bits(st->regmap, 258fea251b6SCosmin Tanislav AD74413R_REG_DIN_CONFIG_X(offset), 259fea251b6SCosmin Tanislav AD74413R_DIN_DEBOUNCE_MASK, 260fea251b6SCosmin Tanislav val); 261fea251b6SCosmin Tanislav } 262fea251b6SCosmin Tanislav 263fea251b6SCosmin Tanislav static void ad74413r_gpio_set(struct gpio_chip *chip, 264fea251b6SCosmin Tanislav unsigned int offset, int val) 265fea251b6SCosmin Tanislav { 266fea251b6SCosmin Tanislav struct ad74413r_state *st = gpiochip_get_data(chip); 267fea251b6SCosmin Tanislav unsigned int real_offset = st->gpo_gpio_offsets[offset]; 268fea251b6SCosmin Tanislav int ret; 269fea251b6SCosmin Tanislav 270fea251b6SCosmin Tanislav ret = ad74413r_set_gpo_config(st, real_offset, 271fea251b6SCosmin Tanislav AD74413R_GPO_CONFIG_LOGIC); 272fea251b6SCosmin Tanislav if (ret) 273fea251b6SCosmin Tanislav return; 274fea251b6SCosmin Tanislav 275fea251b6SCosmin Tanislav regmap_update_bits(st->regmap, AD74413R_REG_GPO_CONFIG_X(real_offset), 276fea251b6SCosmin Tanislav AD74413R_GPO_CONFIG_DATA_MASK, 277fea251b6SCosmin Tanislav val ? AD74413R_GPO_CONFIG_DATA_MASK : 0); 278fea251b6SCosmin Tanislav } 279fea251b6SCosmin Tanislav 280fea251b6SCosmin Tanislav static void ad74413r_gpio_set_multiple(struct gpio_chip *chip, 281fea251b6SCosmin Tanislav unsigned long *mask, 282fea251b6SCosmin Tanislav unsigned long *bits) 283fea251b6SCosmin Tanislav { 284fea251b6SCosmin Tanislav struct ad74413r_state *st = gpiochip_get_data(chip); 285fea251b6SCosmin Tanislav unsigned long real_mask = 0; 286fea251b6SCosmin Tanislav unsigned long real_bits = 0; 287fea251b6SCosmin Tanislav unsigned int offset = 0; 288fea251b6SCosmin Tanislav int ret; 289fea251b6SCosmin Tanislav 2908a3e4a56SCosmin Tanislav for_each_set_bit_from(offset, mask, chip->ngpio) { 291fea251b6SCosmin Tanislav unsigned int real_offset = st->gpo_gpio_offsets[offset]; 292fea251b6SCosmin Tanislav 293fea251b6SCosmin Tanislav ret = ad74413r_set_gpo_config(st, real_offset, 294fea251b6SCosmin Tanislav AD74413R_GPO_CONFIG_LOGIC_PARALLEL); 295fea251b6SCosmin Tanislav if (ret) 296fea251b6SCosmin Tanislav return; 297fea251b6SCosmin Tanislav 298fea251b6SCosmin Tanislav real_mask |= BIT(real_offset); 299fea251b6SCosmin Tanislav if (*bits & offset) 300fea251b6SCosmin Tanislav real_bits |= BIT(real_offset); 301fea251b6SCosmin Tanislav } 302fea251b6SCosmin Tanislav 303fea251b6SCosmin Tanislav regmap_update_bits(st->regmap, AD74413R_REG_GPO_PAR_DATA, 304fea251b6SCosmin Tanislav real_mask, real_bits); 305fea251b6SCosmin Tanislav } 306fea251b6SCosmin Tanislav 307fea251b6SCosmin Tanislav static int ad74413r_gpio_get(struct gpio_chip *chip, unsigned int offset) 308fea251b6SCosmin Tanislav { 309fea251b6SCosmin Tanislav struct ad74413r_state *st = gpiochip_get_data(chip); 310fea251b6SCosmin Tanislav unsigned int real_offset = st->comp_gpio_offsets[offset]; 311fea251b6SCosmin Tanislav unsigned int status; 312fea251b6SCosmin Tanislav int ret; 313fea251b6SCosmin Tanislav 314fea251b6SCosmin Tanislav ret = regmap_read(st->regmap, AD74413R_REG_DIN_COMP_OUT, &status); 315fea251b6SCosmin Tanislav if (ret) 316fea251b6SCosmin Tanislav return ret; 317fea251b6SCosmin Tanislav 318*4165456fSCosmin Tanislav status &= BIT(real_offset); 319fea251b6SCosmin Tanislav 320fea251b6SCosmin Tanislav return status ? 1 : 0; 321fea251b6SCosmin Tanislav } 322fea251b6SCosmin Tanislav 323fea251b6SCosmin Tanislav static int ad74413r_gpio_get_multiple(struct gpio_chip *chip, 324fea251b6SCosmin Tanislav unsigned long *mask, 325fea251b6SCosmin Tanislav unsigned long *bits) 326fea251b6SCosmin Tanislav { 327fea251b6SCosmin Tanislav struct ad74413r_state *st = gpiochip_get_data(chip); 328fea251b6SCosmin Tanislav unsigned int offset = 0; 329fea251b6SCosmin Tanislav unsigned int val; 330fea251b6SCosmin Tanislav int ret; 331fea251b6SCosmin Tanislav 332fea251b6SCosmin Tanislav ret = regmap_read(st->regmap, AD74413R_REG_DIN_COMP_OUT, &val); 333fea251b6SCosmin Tanislav if (ret) 334fea251b6SCosmin Tanislav return ret; 335fea251b6SCosmin Tanislav 3368a3e4a56SCosmin Tanislav for_each_set_bit_from(offset, mask, chip->ngpio) { 337fea251b6SCosmin Tanislav unsigned int real_offset = st->comp_gpio_offsets[offset]; 338fea251b6SCosmin Tanislav 339*4165456fSCosmin Tanislav __assign_bit(offset, bits, val & BIT(real_offset)); 340fea251b6SCosmin Tanislav } 341fea251b6SCosmin Tanislav 342fea251b6SCosmin Tanislav return ret; 343fea251b6SCosmin Tanislav } 344fea251b6SCosmin Tanislav 345fea251b6SCosmin Tanislav static int ad74413r_gpio_get_gpo_direction(struct gpio_chip *chip, 346fea251b6SCosmin Tanislav unsigned int offset) 347fea251b6SCosmin Tanislav { 348fea251b6SCosmin Tanislav return GPIO_LINE_DIRECTION_OUT; 349fea251b6SCosmin Tanislav } 350fea251b6SCosmin Tanislav 351fea251b6SCosmin Tanislav static int ad74413r_gpio_get_comp_direction(struct gpio_chip *chip, 352fea251b6SCosmin Tanislav unsigned int offset) 353fea251b6SCosmin Tanislav { 354fea251b6SCosmin Tanislav return GPIO_LINE_DIRECTION_IN; 355fea251b6SCosmin Tanislav } 356fea251b6SCosmin Tanislav 357fea251b6SCosmin Tanislav static int ad74413r_gpio_set_gpo_config(struct gpio_chip *chip, 358fea251b6SCosmin Tanislav unsigned int offset, 359fea251b6SCosmin Tanislav unsigned long config) 360fea251b6SCosmin Tanislav { 361fea251b6SCosmin Tanislav struct ad74413r_state *st = gpiochip_get_data(chip); 362fea251b6SCosmin Tanislav unsigned int real_offset = st->gpo_gpio_offsets[offset]; 363fea251b6SCosmin Tanislav 364fea251b6SCosmin Tanislav switch (pinconf_to_config_param(config)) { 365fea251b6SCosmin Tanislav case PIN_CONFIG_BIAS_PULL_DOWN: 366fea251b6SCosmin Tanislav return ad74413r_set_gpo_config(st, real_offset, 367fea251b6SCosmin Tanislav AD74413R_GPO_CONFIG_100K_PULL_DOWN); 368fea251b6SCosmin Tanislav case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: 369fea251b6SCosmin Tanislav return ad74413r_set_gpo_config(st, real_offset, 370fea251b6SCosmin Tanislav AD74413R_GPO_CONFIG_HIGH_IMPEDANCE); 371fea251b6SCosmin Tanislav default: 372fea251b6SCosmin Tanislav return -ENOTSUPP; 373fea251b6SCosmin Tanislav } 374fea251b6SCosmin Tanislav } 375fea251b6SCosmin Tanislav 376fea251b6SCosmin Tanislav static int ad74413r_gpio_set_comp_config(struct gpio_chip *chip, 377fea251b6SCosmin Tanislav unsigned int offset, 378fea251b6SCosmin Tanislav unsigned long config) 379fea251b6SCosmin Tanislav { 380fea251b6SCosmin Tanislav struct ad74413r_state *st = gpiochip_get_data(chip); 381fea251b6SCosmin Tanislav unsigned int real_offset = st->comp_gpio_offsets[offset]; 382fea251b6SCosmin Tanislav 383fea251b6SCosmin Tanislav switch (pinconf_to_config_param(config)) { 384fea251b6SCosmin Tanislav case PIN_CONFIG_INPUT_DEBOUNCE: 385fea251b6SCosmin Tanislav return ad74413r_set_comp_debounce(st, real_offset, 386fea251b6SCosmin Tanislav pinconf_to_config_argument(config)); 387fea251b6SCosmin Tanislav default: 388fea251b6SCosmin Tanislav return -ENOTSUPP; 389fea251b6SCosmin Tanislav } 390fea251b6SCosmin Tanislav } 391fea251b6SCosmin Tanislav 392fea251b6SCosmin Tanislav static int ad74413r_reset(struct ad74413r_state *st) 393fea251b6SCosmin Tanislav { 394fea251b6SCosmin Tanislav int ret; 395fea251b6SCosmin Tanislav 396fea251b6SCosmin Tanislav ret = regmap_write(st->regmap, AD74413R_REG_CMD_KEY, 397fea251b6SCosmin Tanislav AD74413R_CMD_KEY_RESET1); 398fea251b6SCosmin Tanislav if (ret) 399fea251b6SCosmin Tanislav return ret; 400fea251b6SCosmin Tanislav 401fea251b6SCosmin Tanislav return regmap_write(st->regmap, AD74413R_REG_CMD_KEY, 402fea251b6SCosmin Tanislav AD74413R_CMD_KEY_RESET2); 403fea251b6SCosmin Tanislav } 404fea251b6SCosmin Tanislav 405fea251b6SCosmin Tanislav static int ad74413r_set_channel_dac_code(struct ad74413r_state *st, 406fea251b6SCosmin Tanislav unsigned int channel, int dac_code) 407fea251b6SCosmin Tanislav { 408fea251b6SCosmin Tanislav struct reg_sequence reg_seq[2] = { 409fea251b6SCosmin Tanislav { AD74413R_REG_DAC_CODE_X(channel), dac_code }, 410fea251b6SCosmin Tanislav { AD74413R_REG_CMD_KEY, AD74413R_CMD_KEY_LDAC }, 411fea251b6SCosmin Tanislav }; 412fea251b6SCosmin Tanislav 413fea251b6SCosmin Tanislav return regmap_multi_reg_write(st->regmap, reg_seq, 2); 414fea251b6SCosmin Tanislav } 415fea251b6SCosmin Tanislav 416fea251b6SCosmin Tanislav static int ad74413r_set_channel_function(struct ad74413r_state *st, 417fea251b6SCosmin Tanislav unsigned int channel, u8 func) 418fea251b6SCosmin Tanislav { 419fea251b6SCosmin Tanislav return regmap_update_bits(st->regmap, 420fea251b6SCosmin Tanislav AD74413R_REG_CH_FUNC_SETUP_X(channel), 421fea251b6SCosmin Tanislav AD74413R_CH_FUNC_SETUP_MASK, func); 422fea251b6SCosmin Tanislav } 423fea251b6SCosmin Tanislav 424fea251b6SCosmin Tanislav static int ad74413r_set_adc_conv_seq(struct ad74413r_state *st, 425fea251b6SCosmin Tanislav unsigned int status) 426fea251b6SCosmin Tanislav { 427fea251b6SCosmin Tanislav int ret; 428fea251b6SCosmin Tanislav 429fea251b6SCosmin Tanislav /* 430fea251b6SCosmin Tanislav * These bits do not clear when a conversion completes. 431fea251b6SCosmin Tanislav * To enable a subsequent conversion, repeat the write. 432fea251b6SCosmin Tanislav */ 433fea251b6SCosmin Tanislav ret = regmap_write_bits(st->regmap, AD74413R_REG_ADC_CONV_CTRL, 434fea251b6SCosmin Tanislav AD74413R_CONV_SEQ_MASK, 435fea251b6SCosmin Tanislav FIELD_PREP(AD74413R_CONV_SEQ_MASK, status)); 436fea251b6SCosmin Tanislav if (ret) 437fea251b6SCosmin Tanislav return ret; 438fea251b6SCosmin Tanislav 439fea251b6SCosmin Tanislav /* 440fea251b6SCosmin Tanislav * Wait 100us before starting conversions. 441fea251b6SCosmin Tanislav */ 442fea251b6SCosmin Tanislav usleep_range(100, 120); 443fea251b6SCosmin Tanislav 444fea251b6SCosmin Tanislav return 0; 445fea251b6SCosmin Tanislav } 446fea251b6SCosmin Tanislav 447fea251b6SCosmin Tanislav static int ad74413r_set_adc_channel_enable(struct ad74413r_state *st, 448fea251b6SCosmin Tanislav unsigned int channel, 449fea251b6SCosmin Tanislav bool status) 450fea251b6SCosmin Tanislav { 451fea251b6SCosmin Tanislav return regmap_update_bits(st->regmap, AD74413R_REG_ADC_CONV_CTRL, 452fea251b6SCosmin Tanislav AD74413R_CH_EN_MASK(channel), 453fea251b6SCosmin Tanislav status ? AD74413R_CH_EN_MASK(channel) : 0); 454fea251b6SCosmin Tanislav } 455fea251b6SCosmin Tanislav 456fea251b6SCosmin Tanislav static int ad74413r_get_adc_range(struct ad74413r_state *st, 457fea251b6SCosmin Tanislav unsigned int channel, 458fea251b6SCosmin Tanislav unsigned int *val) 459fea251b6SCosmin Tanislav { 460fea251b6SCosmin Tanislav int ret; 461fea251b6SCosmin Tanislav 462fea251b6SCosmin Tanislav ret = regmap_read(st->regmap, AD74413R_REG_ADC_CONFIG_X(channel), val); 463fea251b6SCosmin Tanislav if (ret) 464fea251b6SCosmin Tanislav return ret; 465fea251b6SCosmin Tanislav 466fea251b6SCosmin Tanislav *val = FIELD_GET(AD74413R_ADC_CONFIG_RANGE_MASK, *val); 467fea251b6SCosmin Tanislav 468fea251b6SCosmin Tanislav return 0; 469fea251b6SCosmin Tanislav } 470fea251b6SCosmin Tanislav 471fea251b6SCosmin Tanislav static int ad74413r_get_adc_rejection(struct ad74413r_state *st, 472fea251b6SCosmin Tanislav unsigned int channel, 473fea251b6SCosmin Tanislav unsigned int *val) 474fea251b6SCosmin Tanislav { 475fea251b6SCosmin Tanislav int ret; 476fea251b6SCosmin Tanislav 477fea251b6SCosmin Tanislav ret = regmap_read(st->regmap, AD74413R_REG_ADC_CONFIG_X(channel), val); 478fea251b6SCosmin Tanislav if (ret) 479fea251b6SCosmin Tanislav return ret; 480fea251b6SCosmin Tanislav 481fea251b6SCosmin Tanislav *val = FIELD_GET(AD74413R_ADC_CONFIG_REJECTION_MASK, *val); 482fea251b6SCosmin Tanislav 483fea251b6SCosmin Tanislav return 0; 484fea251b6SCosmin Tanislav } 485fea251b6SCosmin Tanislav 486fea251b6SCosmin Tanislav static int ad74413r_set_adc_rejection(struct ad74413r_state *st, 487fea251b6SCosmin Tanislav unsigned int channel, 488fea251b6SCosmin Tanislav unsigned int val) 489fea251b6SCosmin Tanislav { 490fea251b6SCosmin Tanislav return regmap_update_bits(st->regmap, 491fea251b6SCosmin Tanislav AD74413R_REG_ADC_CONFIG_X(channel), 492fea251b6SCosmin Tanislav AD74413R_ADC_CONFIG_REJECTION_MASK, 493fea251b6SCosmin Tanislav FIELD_PREP(AD74413R_ADC_CONFIG_REJECTION_MASK, 494fea251b6SCosmin Tanislav val)); 495fea251b6SCosmin Tanislav } 496fea251b6SCosmin Tanislav 497fea251b6SCosmin Tanislav static int ad74413r_rejection_to_rate(struct ad74413r_state *st, 498fea251b6SCosmin Tanislav unsigned int rej, int *val) 499fea251b6SCosmin Tanislav { 500fea251b6SCosmin Tanislav switch (rej) { 501fea251b6SCosmin Tanislav case AD74413R_ADC_REJECTION_50_60: 502fea251b6SCosmin Tanislav *val = 20; 503fea251b6SCosmin Tanislav return 0; 504fea251b6SCosmin Tanislav case AD74413R_ADC_REJECTION_NONE: 505fea251b6SCosmin Tanislav *val = 4800; 506fea251b6SCosmin Tanislav return 0; 507fea251b6SCosmin Tanislav case AD74413R_ADC_REJECTION_50_60_HART: 508fea251b6SCosmin Tanislav *val = 10; 509fea251b6SCosmin Tanislav return 0; 510fea251b6SCosmin Tanislav case AD74413R_ADC_REJECTION_HART: 511fea251b6SCosmin Tanislav *val = 1200; 512fea251b6SCosmin Tanislav return 0; 513fea251b6SCosmin Tanislav default: 514fea251b6SCosmin Tanislav dev_err(st->dev, "ADC rejection invalid\n"); 515fea251b6SCosmin Tanislav return -EINVAL; 516fea251b6SCosmin Tanislav } 517fea251b6SCosmin Tanislav } 518fea251b6SCosmin Tanislav 519fea251b6SCosmin Tanislav static int ad74413r_rate_to_rejection(struct ad74413r_state *st, 520fea251b6SCosmin Tanislav int rate, unsigned int *val) 521fea251b6SCosmin Tanislav { 522fea251b6SCosmin Tanislav switch (rate) { 523fea251b6SCosmin Tanislav case 20: 524fea251b6SCosmin Tanislav *val = AD74413R_ADC_REJECTION_50_60; 525fea251b6SCosmin Tanislav return 0; 526fea251b6SCosmin Tanislav case 4800: 527fea251b6SCosmin Tanislav *val = AD74413R_ADC_REJECTION_NONE; 528fea251b6SCosmin Tanislav return 0; 529fea251b6SCosmin Tanislav case 10: 530fea251b6SCosmin Tanislav *val = AD74413R_ADC_REJECTION_50_60_HART; 531fea251b6SCosmin Tanislav return 0; 532fea251b6SCosmin Tanislav case 1200: 533fea251b6SCosmin Tanislav *val = AD74413R_ADC_REJECTION_HART; 534fea251b6SCosmin Tanislav return 0; 535fea251b6SCosmin Tanislav default: 536fea251b6SCosmin Tanislav dev_err(st->dev, "ADC rate invalid\n"); 537fea251b6SCosmin Tanislav return -EINVAL; 538fea251b6SCosmin Tanislav } 539fea251b6SCosmin Tanislav } 540fea251b6SCosmin Tanislav 541fea251b6SCosmin Tanislav static int ad74413r_range_to_voltage_range(struct ad74413r_state *st, 542fea251b6SCosmin Tanislav unsigned int range, int *val) 543fea251b6SCosmin Tanislav { 544fea251b6SCosmin Tanislav switch (range) { 545fea251b6SCosmin Tanislav case AD74413R_ADC_RANGE_10V: 546fea251b6SCosmin Tanislav *val = 10000; 547fea251b6SCosmin Tanislav return 0; 548fea251b6SCosmin Tanislav case AD74413R_ADC_RANGE_2P5V_EXT_POW: 549fea251b6SCosmin Tanislav case AD74413R_ADC_RANGE_2P5V_INT_POW: 550fea251b6SCosmin Tanislav *val = 2500; 551fea251b6SCosmin Tanislav return 0; 552fea251b6SCosmin Tanislav case AD74413R_ADC_RANGE_5V_BI_DIR: 553fea251b6SCosmin Tanislav *val = 5000; 554fea251b6SCosmin Tanislav return 0; 555fea251b6SCosmin Tanislav default: 556fea251b6SCosmin Tanislav dev_err(st->dev, "ADC range invalid\n"); 557fea251b6SCosmin Tanislav return -EINVAL; 558fea251b6SCosmin Tanislav } 559fea251b6SCosmin Tanislav } 560fea251b6SCosmin Tanislav 561fea251b6SCosmin Tanislav static int ad74413r_range_to_voltage_offset(struct ad74413r_state *st, 562fea251b6SCosmin Tanislav unsigned int range, int *val) 563fea251b6SCosmin Tanislav { 564fea251b6SCosmin Tanislav switch (range) { 565fea251b6SCosmin Tanislav case AD74413R_ADC_RANGE_10V: 566fea251b6SCosmin Tanislav case AD74413R_ADC_RANGE_2P5V_EXT_POW: 567fea251b6SCosmin Tanislav *val = 0; 568fea251b6SCosmin Tanislav return 0; 569fea251b6SCosmin Tanislav case AD74413R_ADC_RANGE_2P5V_INT_POW: 570fea251b6SCosmin Tanislav case AD74413R_ADC_RANGE_5V_BI_DIR: 571fea251b6SCosmin Tanislav *val = -2500; 572fea251b6SCosmin Tanislav return 0; 573fea251b6SCosmin Tanislav default: 574fea251b6SCosmin Tanislav dev_err(st->dev, "ADC range invalid\n"); 575fea251b6SCosmin Tanislav return -EINVAL; 576fea251b6SCosmin Tanislav } 577fea251b6SCosmin Tanislav } 578fea251b6SCosmin Tanislav 579fea251b6SCosmin Tanislav static int ad74413r_range_to_voltage_offset_raw(struct ad74413r_state *st, 580fea251b6SCosmin Tanislav unsigned int range, int *val) 581fea251b6SCosmin Tanislav { 582fea251b6SCosmin Tanislav switch (range) { 583fea251b6SCosmin Tanislav case AD74413R_ADC_RANGE_10V: 584fea251b6SCosmin Tanislav case AD74413R_ADC_RANGE_2P5V_EXT_POW: 585fea251b6SCosmin Tanislav *val = 0; 586fea251b6SCosmin Tanislav return 0; 587fea251b6SCosmin Tanislav case AD74413R_ADC_RANGE_2P5V_INT_POW: 588fea251b6SCosmin Tanislav *val = -((int)AD74413R_ADC_RESULT_MAX); 589fea251b6SCosmin Tanislav return 0; 590fea251b6SCosmin Tanislav case AD74413R_ADC_RANGE_5V_BI_DIR: 591fea251b6SCosmin Tanislav *val = -((int)AD74413R_ADC_RESULT_MAX / 2); 592fea251b6SCosmin Tanislav return 0; 593fea251b6SCosmin Tanislav default: 594fea251b6SCosmin Tanislav dev_err(st->dev, "ADC range invalid\n"); 595fea251b6SCosmin Tanislav return -EINVAL; 596fea251b6SCosmin Tanislav } 597fea251b6SCosmin Tanislav } 598fea251b6SCosmin Tanislav 599fea251b6SCosmin Tanislav static int ad74413r_get_output_voltage_scale(struct ad74413r_state *st, 600fea251b6SCosmin Tanislav int *val, int *val2) 601fea251b6SCosmin Tanislav { 602fea251b6SCosmin Tanislav *val = AD74413R_DAC_VOLTAGE_MAX; 603fea251b6SCosmin Tanislav *val2 = AD74413R_DAC_CODE_MAX; 604fea251b6SCosmin Tanislav 605fea251b6SCosmin Tanislav return IIO_VAL_FRACTIONAL; 606fea251b6SCosmin Tanislav } 607fea251b6SCosmin Tanislav 608fea251b6SCosmin Tanislav static int ad74413r_get_output_current_scale(struct ad74413r_state *st, 609fea251b6SCosmin Tanislav int *val, int *val2) 610fea251b6SCosmin Tanislav { 611fea251b6SCosmin Tanislav *val = regulator_get_voltage(st->refin_reg); 612fea251b6SCosmin Tanislav *val2 = st->sense_resistor_ohms * AD74413R_DAC_CODE_MAX * 1000; 613fea251b6SCosmin Tanislav 614fea251b6SCosmin Tanislav return IIO_VAL_FRACTIONAL; 615fea251b6SCosmin Tanislav } 616fea251b6SCosmin Tanislav 617fea251b6SCosmin Tanislav static int ad74413r_get_input_voltage_scale(struct ad74413r_state *st, 618fea251b6SCosmin Tanislav unsigned int channel, 619fea251b6SCosmin Tanislav int *val, int *val2) 620fea251b6SCosmin Tanislav { 621fea251b6SCosmin Tanislav unsigned int range; 622fea251b6SCosmin Tanislav int ret; 623fea251b6SCosmin Tanislav 624fea251b6SCosmin Tanislav ret = ad74413r_get_adc_range(st, channel, &range); 625fea251b6SCosmin Tanislav if (ret) 626fea251b6SCosmin Tanislav return ret; 627fea251b6SCosmin Tanislav 628fea251b6SCosmin Tanislav ret = ad74413r_range_to_voltage_range(st, range, val); 629fea251b6SCosmin Tanislav if (ret) 630fea251b6SCosmin Tanislav return ret; 631fea251b6SCosmin Tanislav 632fea251b6SCosmin Tanislav *val2 = AD74413R_ADC_RESULT_MAX; 633fea251b6SCosmin Tanislav 634fea251b6SCosmin Tanislav return IIO_VAL_FRACTIONAL; 635fea251b6SCosmin Tanislav } 636fea251b6SCosmin Tanislav 637fea251b6SCosmin Tanislav static int ad74413r_get_input_voltage_offset(struct ad74413r_state *st, 638fea251b6SCosmin Tanislav unsigned int channel, int *val) 639fea251b6SCosmin Tanislav { 640fea251b6SCosmin Tanislav unsigned int range; 641fea251b6SCosmin Tanislav int ret; 642fea251b6SCosmin Tanislav 643fea251b6SCosmin Tanislav ret = ad74413r_get_adc_range(st, channel, &range); 644fea251b6SCosmin Tanislav if (ret) 645fea251b6SCosmin Tanislav return ret; 646fea251b6SCosmin Tanislav 647fea251b6SCosmin Tanislav ret = ad74413r_range_to_voltage_offset_raw(st, range, val); 648fea251b6SCosmin Tanislav if (ret) 649fea251b6SCosmin Tanislav return ret; 650fea251b6SCosmin Tanislav 651fea251b6SCosmin Tanislav return IIO_VAL_INT; 652fea251b6SCosmin Tanislav } 653fea251b6SCosmin Tanislav 654fea251b6SCosmin Tanislav static int ad74413r_get_input_current_scale(struct ad74413r_state *st, 655fea251b6SCosmin Tanislav unsigned int channel, int *val, 656fea251b6SCosmin Tanislav int *val2) 657fea251b6SCosmin Tanislav { 658fea251b6SCosmin Tanislav unsigned int range; 659fea251b6SCosmin Tanislav int ret; 660fea251b6SCosmin Tanislav 661fea251b6SCosmin Tanislav ret = ad74413r_get_adc_range(st, channel, &range); 662fea251b6SCosmin Tanislav if (ret) 663fea251b6SCosmin Tanislav return ret; 664fea251b6SCosmin Tanislav 665fea251b6SCosmin Tanislav ret = ad74413r_range_to_voltage_range(st, range, val); 666fea251b6SCosmin Tanislav if (ret) 667fea251b6SCosmin Tanislav return ret; 668fea251b6SCosmin Tanislav 669fea251b6SCosmin Tanislav *val2 = AD74413R_ADC_RESULT_MAX * st->sense_resistor_ohms; 670fea251b6SCosmin Tanislav 671fea251b6SCosmin Tanislav return IIO_VAL_FRACTIONAL; 672fea251b6SCosmin Tanislav } 673fea251b6SCosmin Tanislav 674fea251b6SCosmin Tanislav static int ad74413_get_input_current_offset(struct ad74413r_state *st, 675fea251b6SCosmin Tanislav unsigned int channel, int *val) 676fea251b6SCosmin Tanislav { 677fea251b6SCosmin Tanislav unsigned int range; 678fea251b6SCosmin Tanislav int voltage_range; 679fea251b6SCosmin Tanislav int voltage_offset; 680fea251b6SCosmin Tanislav int ret; 681fea251b6SCosmin Tanislav 682fea251b6SCosmin Tanislav ret = ad74413r_get_adc_range(st, channel, &range); 683fea251b6SCosmin Tanislav if (ret) 684fea251b6SCosmin Tanislav return ret; 685fea251b6SCosmin Tanislav 686fea251b6SCosmin Tanislav ret = ad74413r_range_to_voltage_range(st, range, &voltage_range); 687fea251b6SCosmin Tanislav if (ret) 688fea251b6SCosmin Tanislav return ret; 689fea251b6SCosmin Tanislav 690fea251b6SCosmin Tanislav ret = ad74413r_range_to_voltage_offset(st, range, &voltage_offset); 691fea251b6SCosmin Tanislav if (ret) 692fea251b6SCosmin Tanislav return ret; 693fea251b6SCosmin Tanislav 694fea251b6SCosmin Tanislav *val = voltage_offset * AD74413R_ADC_RESULT_MAX / voltage_range; 695fea251b6SCosmin Tanislav 696fea251b6SCosmin Tanislav return IIO_VAL_INT; 697fea251b6SCosmin Tanislav } 698fea251b6SCosmin Tanislav 699fea251b6SCosmin Tanislav static int ad74413r_get_adc_rate(struct ad74413r_state *st, 700fea251b6SCosmin Tanislav unsigned int channel, int *val) 701fea251b6SCosmin Tanislav { 702fea251b6SCosmin Tanislav unsigned int rejection; 703fea251b6SCosmin Tanislav int ret; 704fea251b6SCosmin Tanislav 705fea251b6SCosmin Tanislav ret = ad74413r_get_adc_rejection(st, channel, &rejection); 706fea251b6SCosmin Tanislav if (ret) 707fea251b6SCosmin Tanislav return ret; 708fea251b6SCosmin Tanislav 709fea251b6SCosmin Tanislav ret = ad74413r_rejection_to_rate(st, rejection, val); 710fea251b6SCosmin Tanislav if (ret) 711fea251b6SCosmin Tanislav return ret; 712fea251b6SCosmin Tanislav 713fea251b6SCosmin Tanislav return IIO_VAL_INT; 714fea251b6SCosmin Tanislav } 715fea251b6SCosmin Tanislav 716fea251b6SCosmin Tanislav static int ad74413r_set_adc_rate(struct ad74413r_state *st, 717fea251b6SCosmin Tanislav unsigned int channel, int val) 718fea251b6SCosmin Tanislav { 719fea251b6SCosmin Tanislav unsigned int rejection; 720fea251b6SCosmin Tanislav int ret; 721fea251b6SCosmin Tanislav 722fea251b6SCosmin Tanislav ret = ad74413r_rate_to_rejection(st, val, &rejection); 723fea251b6SCosmin Tanislav if (ret) 724fea251b6SCosmin Tanislav return ret; 725fea251b6SCosmin Tanislav 726fea251b6SCosmin Tanislav return ad74413r_set_adc_rejection(st, channel, rejection); 727fea251b6SCosmin Tanislav } 728fea251b6SCosmin Tanislav 729fea251b6SCosmin Tanislav static irqreturn_t ad74413r_trigger_handler(int irq, void *p) 730fea251b6SCosmin Tanislav { 731fea251b6SCosmin Tanislav struct iio_poll_func *pf = p; 732fea251b6SCosmin Tanislav struct iio_dev *indio_dev = pf->indio_dev; 733fea251b6SCosmin Tanislav struct ad74413r_state *st = iio_priv(indio_dev); 734fea251b6SCosmin Tanislav u8 *rx_buf = st->adc_samples_buf.rx_buf; 735fea251b6SCosmin Tanislav unsigned int i; 736fea251b6SCosmin Tanislav int ret; 737fea251b6SCosmin Tanislav 738fea251b6SCosmin Tanislav ret = spi_sync(st->spi, &st->adc_samples_msg); 739fea251b6SCosmin Tanislav if (ret) 740fea251b6SCosmin Tanislav goto out; 741fea251b6SCosmin Tanislav 742fea251b6SCosmin Tanislav for (i = 0; i < st->adc_active_channels; i++) 743fea251b6SCosmin Tanislav ad74413r_crc_check(st, &rx_buf[i * AD74413R_FRAME_SIZE]); 744fea251b6SCosmin Tanislav 745fea251b6SCosmin Tanislav iio_push_to_buffers_with_timestamp(indio_dev, &st->adc_samples_buf, 746fea251b6SCosmin Tanislav iio_get_time_ns(indio_dev)); 747fea251b6SCosmin Tanislav 748fea251b6SCosmin Tanislav out: 749fea251b6SCosmin Tanislav iio_trigger_notify_done(indio_dev->trig); 750fea251b6SCosmin Tanislav 751fea251b6SCosmin Tanislav return IRQ_HANDLED; 752fea251b6SCosmin Tanislav } 753fea251b6SCosmin Tanislav 754fea251b6SCosmin Tanislav static irqreturn_t ad74413r_adc_data_interrupt(int irq, void *data) 755fea251b6SCosmin Tanislav { 756fea251b6SCosmin Tanislav struct iio_dev *indio_dev = data; 757fea251b6SCosmin Tanislav struct ad74413r_state *st = iio_priv(indio_dev); 758fea251b6SCosmin Tanislav 759fea251b6SCosmin Tanislav if (iio_buffer_enabled(indio_dev)) 760fea251b6SCosmin Tanislav iio_trigger_poll(st->trig); 761fea251b6SCosmin Tanislav else 762fea251b6SCosmin Tanislav complete(&st->adc_data_completion); 763fea251b6SCosmin Tanislav 764fea251b6SCosmin Tanislav return IRQ_HANDLED; 765fea251b6SCosmin Tanislav } 766fea251b6SCosmin Tanislav 767fea251b6SCosmin Tanislav static int _ad74413r_get_single_adc_result(struct ad74413r_state *st, 768fea251b6SCosmin Tanislav unsigned int channel, int *val) 769fea251b6SCosmin Tanislav { 770fea251b6SCosmin Tanislav unsigned int uval; 771fea251b6SCosmin Tanislav int ret; 772fea251b6SCosmin Tanislav 773fea251b6SCosmin Tanislav reinit_completion(&st->adc_data_completion); 774fea251b6SCosmin Tanislav 775fea251b6SCosmin Tanislav ret = ad74413r_set_adc_channel_enable(st, channel, true); 776fea251b6SCosmin Tanislav if (ret) 777fea251b6SCosmin Tanislav return ret; 778fea251b6SCosmin Tanislav 779fea251b6SCosmin Tanislav ret = ad74413r_set_adc_conv_seq(st, AD74413R_CONV_SEQ_SINGLE); 780fea251b6SCosmin Tanislav if (ret) 781fea251b6SCosmin Tanislav return ret; 782fea251b6SCosmin Tanislav 783fea251b6SCosmin Tanislav ret = wait_for_completion_timeout(&st->adc_data_completion, 784fea251b6SCosmin Tanislav msecs_to_jiffies(1000)); 785fea251b6SCosmin Tanislav if (!ret) { 786fea251b6SCosmin Tanislav ret = -ETIMEDOUT; 787fea251b6SCosmin Tanislav return ret; 788fea251b6SCosmin Tanislav } 789fea251b6SCosmin Tanislav 790fea251b6SCosmin Tanislav ret = regmap_read(st->regmap, AD74413R_REG_ADC_RESULT_X(channel), 791fea251b6SCosmin Tanislav &uval); 792fea251b6SCosmin Tanislav if (ret) 793fea251b6SCosmin Tanislav return ret; 794fea251b6SCosmin Tanislav 795fea251b6SCosmin Tanislav ret = ad74413r_set_adc_conv_seq(st, AD74413R_CONV_SEQ_OFF); 796fea251b6SCosmin Tanislav if (ret) 797fea251b6SCosmin Tanislav return ret; 798fea251b6SCosmin Tanislav 799fea251b6SCosmin Tanislav ret = ad74413r_set_adc_channel_enable(st, channel, false); 800fea251b6SCosmin Tanislav if (ret) 801fea251b6SCosmin Tanislav return ret; 802fea251b6SCosmin Tanislav 803fea251b6SCosmin Tanislav *val = uval; 804fea251b6SCosmin Tanislav 805fea251b6SCosmin Tanislav return IIO_VAL_INT; 806fea251b6SCosmin Tanislav } 807fea251b6SCosmin Tanislav 808fea251b6SCosmin Tanislav static int ad74413r_get_single_adc_result(struct iio_dev *indio_dev, 809fea251b6SCosmin Tanislav unsigned int channel, int *val) 810fea251b6SCosmin Tanislav { 811fea251b6SCosmin Tanislav struct ad74413r_state *st = iio_priv(indio_dev); 812fea251b6SCosmin Tanislav int ret; 813fea251b6SCosmin Tanislav 814fea251b6SCosmin Tanislav ret = iio_device_claim_direct_mode(indio_dev); 815fea251b6SCosmin Tanislav if (ret) 816fea251b6SCosmin Tanislav return ret; 817fea251b6SCosmin Tanislav 818fea251b6SCosmin Tanislav mutex_lock(&st->lock); 819fea251b6SCosmin Tanislav ret = _ad74413r_get_single_adc_result(st, channel, val); 820fea251b6SCosmin Tanislav mutex_unlock(&st->lock); 821fea251b6SCosmin Tanislav 822fea251b6SCosmin Tanislav iio_device_release_direct_mode(indio_dev); 823fea251b6SCosmin Tanislav 824fea251b6SCosmin Tanislav return ret; 825fea251b6SCosmin Tanislav } 826fea251b6SCosmin Tanislav 827fea251b6SCosmin Tanislav static void ad74413r_adc_to_resistance_result(int adc_result, int *val) 828fea251b6SCosmin Tanislav { 829fea251b6SCosmin Tanislav if (adc_result == AD74413R_ADC_RESULT_MAX) 830fea251b6SCosmin Tanislav adc_result = AD74413R_ADC_RESULT_MAX - 1; 831fea251b6SCosmin Tanislav 832fea251b6SCosmin Tanislav *val = DIV_ROUND_CLOSEST(adc_result * 2100, 833fea251b6SCosmin Tanislav AD74413R_ADC_RESULT_MAX - adc_result); 834fea251b6SCosmin Tanislav } 835fea251b6SCosmin Tanislav 836fea251b6SCosmin Tanislav static int ad74413r_update_scan_mode(struct iio_dev *indio_dev, 837fea251b6SCosmin Tanislav const unsigned long *active_scan_mask) 838fea251b6SCosmin Tanislav { 839fea251b6SCosmin Tanislav struct ad74413r_state *st = iio_priv(indio_dev); 840fea251b6SCosmin Tanislav struct spi_transfer *xfer = st->adc_samples_xfer; 841e7a3290dSKees Cook u8 *rx_buf = st->adc_samples_buf.rx_buf; 842fea251b6SCosmin Tanislav u8 *tx_buf = st->adc_samples_tx_buf; 843fea251b6SCosmin Tanislav unsigned int channel; 844f4a73a97SJonathan Cameron int ret = -EINVAL; 845fea251b6SCosmin Tanislav 846fea251b6SCosmin Tanislav mutex_lock(&st->lock); 847fea251b6SCosmin Tanislav 848fea251b6SCosmin Tanislav spi_message_init(&st->adc_samples_msg); 849fea251b6SCosmin Tanislav st->adc_active_channels = 0; 850fea251b6SCosmin Tanislav 851fea251b6SCosmin Tanislav for_each_clear_bit(channel, active_scan_mask, AD74413R_CHANNEL_MAX) { 852fea251b6SCosmin Tanislav ret = ad74413r_set_adc_channel_enable(st, channel, false); 853fea251b6SCosmin Tanislav if (ret) 854fea251b6SCosmin Tanislav goto out; 855fea251b6SCosmin Tanislav } 856fea251b6SCosmin Tanislav 857fea251b6SCosmin Tanislav if (*active_scan_mask == 0) 858fea251b6SCosmin Tanislav goto out; 859fea251b6SCosmin Tanislav 860fea251b6SCosmin Tanislav /* 861fea251b6SCosmin Tanislav * The read select register is used to select which register's value 862fea251b6SCosmin Tanislav * will be sent by the slave on the next SPI frame. 863fea251b6SCosmin Tanislav * 864fea251b6SCosmin Tanislav * Create an SPI message that, on each step, writes to the read select 865fea251b6SCosmin Tanislav * register to select the ADC result of the next enabled channel, and 866fea251b6SCosmin Tanislav * reads the ADC result of the previous enabled channel. 867fea251b6SCosmin Tanislav * 868fea251b6SCosmin Tanislav * Example: 869fea251b6SCosmin Tanislav * W: [WCH1] [WCH2] [WCH2] [WCH3] [ ] 870fea251b6SCosmin Tanislav * R: [ ] [RCH1] [RCH2] [RCH3] [RCH4] 871fea251b6SCosmin Tanislav */ 872fea251b6SCosmin Tanislav 873fea251b6SCosmin Tanislav for_each_set_bit(channel, active_scan_mask, AD74413R_CHANNEL_MAX) { 874fea251b6SCosmin Tanislav ret = ad74413r_set_adc_channel_enable(st, channel, true); 875fea251b6SCosmin Tanislav if (ret) 876fea251b6SCosmin Tanislav goto out; 877fea251b6SCosmin Tanislav 878fea251b6SCosmin Tanislav st->adc_active_channels++; 879fea251b6SCosmin Tanislav 880fea251b6SCosmin Tanislav if (xfer == st->adc_samples_xfer) 881fea251b6SCosmin Tanislav xfer->rx_buf = NULL; 882fea251b6SCosmin Tanislav else 883fea251b6SCosmin Tanislav xfer->rx_buf = rx_buf; 884fea251b6SCosmin Tanislav 885fea251b6SCosmin Tanislav xfer->tx_buf = tx_buf; 886fea251b6SCosmin Tanislav xfer->len = AD74413R_FRAME_SIZE; 887fea251b6SCosmin Tanislav xfer->cs_change = 1; 888fea251b6SCosmin Tanislav 889fea251b6SCosmin Tanislav ad74413r_format_reg_write(AD74413R_REG_READ_SELECT, 890fea251b6SCosmin Tanislav AD74413R_REG_ADC_RESULT_X(channel), 891fea251b6SCosmin Tanislav tx_buf); 892fea251b6SCosmin Tanislav 893fea251b6SCosmin Tanislav spi_message_add_tail(xfer, &st->adc_samples_msg); 894fea251b6SCosmin Tanislav 895fea251b6SCosmin Tanislav tx_buf += AD74413R_FRAME_SIZE; 896e7a3290dSKees Cook if (xfer != st->adc_samples_xfer) 897fea251b6SCosmin Tanislav rx_buf += AD74413R_FRAME_SIZE; 898e7a3290dSKees Cook xfer++; 899fea251b6SCosmin Tanislav } 900fea251b6SCosmin Tanislav 901fea251b6SCosmin Tanislav xfer->rx_buf = rx_buf; 902fea251b6SCosmin Tanislav xfer->tx_buf = NULL; 903fea251b6SCosmin Tanislav xfer->len = AD74413R_FRAME_SIZE; 904fea251b6SCosmin Tanislav xfer->cs_change = 0; 905fea251b6SCosmin Tanislav 906fea251b6SCosmin Tanislav spi_message_add_tail(xfer, &st->adc_samples_msg); 907fea251b6SCosmin Tanislav 908fea251b6SCosmin Tanislav out: 909fea251b6SCosmin Tanislav mutex_unlock(&st->lock); 910fea251b6SCosmin Tanislav 911fea251b6SCosmin Tanislav return ret; 912fea251b6SCosmin Tanislav } 913fea251b6SCosmin Tanislav 914fea251b6SCosmin Tanislav static int ad74413r_buffer_postenable(struct iio_dev *indio_dev) 915fea251b6SCosmin Tanislav { 916fea251b6SCosmin Tanislav struct ad74413r_state *st = iio_priv(indio_dev); 917fea251b6SCosmin Tanislav 918fea251b6SCosmin Tanislav return ad74413r_set_adc_conv_seq(st, AD74413R_CONV_SEQ_CONTINUOUS); 919fea251b6SCosmin Tanislav } 920fea251b6SCosmin Tanislav 921fea251b6SCosmin Tanislav static int ad74413r_buffer_predisable(struct iio_dev *indio_dev) 922fea251b6SCosmin Tanislav { 923fea251b6SCosmin Tanislav struct ad74413r_state *st = iio_priv(indio_dev); 924fea251b6SCosmin Tanislav 925fea251b6SCosmin Tanislav return ad74413r_set_adc_conv_seq(st, AD74413R_CONV_SEQ_OFF); 926fea251b6SCosmin Tanislav } 927fea251b6SCosmin Tanislav 928fea251b6SCosmin Tanislav static int ad74413r_read_raw(struct iio_dev *indio_dev, 929fea251b6SCosmin Tanislav struct iio_chan_spec const *chan, 930fea251b6SCosmin Tanislav int *val, int *val2, long info) 931fea251b6SCosmin Tanislav { 932fea251b6SCosmin Tanislav struct ad74413r_state *st = iio_priv(indio_dev); 933fea251b6SCosmin Tanislav 934fea251b6SCosmin Tanislav switch (info) { 935fea251b6SCosmin Tanislav case IIO_CHAN_INFO_SCALE: 936fea251b6SCosmin Tanislav switch (chan->type) { 937fea251b6SCosmin Tanislav case IIO_VOLTAGE: 938fea251b6SCosmin Tanislav if (chan->output) 939fea251b6SCosmin Tanislav return ad74413r_get_output_voltage_scale(st, 940fea251b6SCosmin Tanislav val, val2); 941fea251b6SCosmin Tanislav else 942fea251b6SCosmin Tanislav return ad74413r_get_input_voltage_scale(st, 943fea251b6SCosmin Tanislav chan->channel, val, val2); 944fea251b6SCosmin Tanislav case IIO_CURRENT: 945fea251b6SCosmin Tanislav if (chan->output) 946fea251b6SCosmin Tanislav return ad74413r_get_output_current_scale(st, 947fea251b6SCosmin Tanislav val, val2); 948fea251b6SCosmin Tanislav else 949fea251b6SCosmin Tanislav return ad74413r_get_input_current_scale(st, 950fea251b6SCosmin Tanislav chan->channel, val, val2); 951fea251b6SCosmin Tanislav default: 952fea251b6SCosmin Tanislav return -EINVAL; 953fea251b6SCosmin Tanislav } 954fea251b6SCosmin Tanislav case IIO_CHAN_INFO_OFFSET: 955fea251b6SCosmin Tanislav switch (chan->type) { 956fea251b6SCosmin Tanislav case IIO_VOLTAGE: 957fea251b6SCosmin Tanislav return ad74413r_get_input_voltage_offset(st, 958fea251b6SCosmin Tanislav chan->channel, val); 959fea251b6SCosmin Tanislav case IIO_CURRENT: 960fea251b6SCosmin Tanislav return ad74413_get_input_current_offset(st, 961fea251b6SCosmin Tanislav chan->channel, val); 962fea251b6SCosmin Tanislav default: 963fea251b6SCosmin Tanislav return -EINVAL; 964fea251b6SCosmin Tanislav } 965fea251b6SCosmin Tanislav case IIO_CHAN_INFO_RAW: 966fea251b6SCosmin Tanislav if (chan->output) 967fea251b6SCosmin Tanislav return -EINVAL; 968fea251b6SCosmin Tanislav 969fea251b6SCosmin Tanislav return ad74413r_get_single_adc_result(indio_dev, chan->channel, 970fea251b6SCosmin Tanislav val); 971fea251b6SCosmin Tanislav case IIO_CHAN_INFO_PROCESSED: { 972fea251b6SCosmin Tanislav int ret; 973fea251b6SCosmin Tanislav 974fea251b6SCosmin Tanislav ret = ad74413r_get_single_adc_result(indio_dev, chan->channel, 975fea251b6SCosmin Tanislav val); 976fea251b6SCosmin Tanislav if (ret) 977fea251b6SCosmin Tanislav return ret; 978fea251b6SCosmin Tanislav 979fea251b6SCosmin Tanislav ad74413r_adc_to_resistance_result(*val, val); 980fea251b6SCosmin Tanislav 981fea251b6SCosmin Tanislav return ret; 982fea251b6SCosmin Tanislav } 983fea251b6SCosmin Tanislav case IIO_CHAN_INFO_SAMP_FREQ: 984fea251b6SCosmin Tanislav return ad74413r_get_adc_rate(st, chan->channel, val); 985fea251b6SCosmin Tanislav default: 986fea251b6SCosmin Tanislav return -EINVAL; 987fea251b6SCosmin Tanislav } 988fea251b6SCosmin Tanislav } 989fea251b6SCosmin Tanislav 990fea251b6SCosmin Tanislav static int ad74413r_write_raw(struct iio_dev *indio_dev, 991fea251b6SCosmin Tanislav struct iio_chan_spec const *chan, 992fea251b6SCosmin Tanislav int val, int val2, long info) 993fea251b6SCosmin Tanislav { 994fea251b6SCosmin Tanislav struct ad74413r_state *st = iio_priv(indio_dev); 995fea251b6SCosmin Tanislav 996fea251b6SCosmin Tanislav switch (info) { 997fea251b6SCosmin Tanislav case IIO_CHAN_INFO_RAW: 998fea251b6SCosmin Tanislav if (!chan->output) 999fea251b6SCosmin Tanislav return -EINVAL; 1000fea251b6SCosmin Tanislav 1001fea251b6SCosmin Tanislav if (val < 0 || val > AD74413R_DAC_CODE_MAX) { 1002fea251b6SCosmin Tanislav dev_err(st->dev, "Invalid DAC code\n"); 1003fea251b6SCosmin Tanislav return -EINVAL; 1004fea251b6SCosmin Tanislav } 1005fea251b6SCosmin Tanislav 1006fea251b6SCosmin Tanislav return ad74413r_set_channel_dac_code(st, chan->channel, val); 1007fea251b6SCosmin Tanislav case IIO_CHAN_INFO_SAMP_FREQ: 1008fea251b6SCosmin Tanislav return ad74413r_set_adc_rate(st, chan->channel, val); 1009fea251b6SCosmin Tanislav default: 1010fea251b6SCosmin Tanislav return -EINVAL; 1011fea251b6SCosmin Tanislav } 1012fea251b6SCosmin Tanislav } 1013fea251b6SCosmin Tanislav 1014fea251b6SCosmin Tanislav static int ad74413r_read_avail(struct iio_dev *indio_dev, 1015fea251b6SCosmin Tanislav struct iio_chan_spec const *chan, 1016fea251b6SCosmin Tanislav const int **vals, int *type, int *length, 1017fea251b6SCosmin Tanislav long info) 1018fea251b6SCosmin Tanislav { 1019fea251b6SCosmin Tanislav struct ad74413r_state *st = iio_priv(indio_dev); 1020fea251b6SCosmin Tanislav 1021fea251b6SCosmin Tanislav switch (info) { 1022fea251b6SCosmin Tanislav case IIO_CHAN_INFO_SAMP_FREQ: 1023fea251b6SCosmin Tanislav if (st->chip_info->hart_support) { 1024fea251b6SCosmin Tanislav *vals = ad74413r_adc_sampling_rates_hart; 1025fea251b6SCosmin Tanislav *length = ARRAY_SIZE(ad74413r_adc_sampling_rates_hart); 1026fea251b6SCosmin Tanislav } else { 1027fea251b6SCosmin Tanislav *vals = ad74413r_adc_sampling_rates; 1028fea251b6SCosmin Tanislav *length = ARRAY_SIZE(ad74413r_adc_sampling_rates); 1029fea251b6SCosmin Tanislav } 1030fea251b6SCosmin Tanislav *type = IIO_VAL_INT; 1031fea251b6SCosmin Tanislav return IIO_AVAIL_LIST; 1032fea251b6SCosmin Tanislav default: 1033fea251b6SCosmin Tanislav return -EINVAL; 1034fea251b6SCosmin Tanislav } 1035fea251b6SCosmin Tanislav } 1036fea251b6SCosmin Tanislav 1037fea251b6SCosmin Tanislav static const struct iio_buffer_setup_ops ad74413r_buffer_ops = { 1038fea251b6SCosmin Tanislav .postenable = &ad74413r_buffer_postenable, 1039fea251b6SCosmin Tanislav .predisable = &ad74413r_buffer_predisable, 1040fea251b6SCosmin Tanislav }; 1041fea251b6SCosmin Tanislav 1042fea251b6SCosmin Tanislav static const struct iio_trigger_ops ad74413r_trigger_ops = { 1043fea251b6SCosmin Tanislav .validate_device = iio_trigger_validate_own_device, 1044fea251b6SCosmin Tanislav }; 1045fea251b6SCosmin Tanislav 1046fea251b6SCosmin Tanislav static const struct iio_info ad74413r_info = { 1047fea251b6SCosmin Tanislav .read_raw = &ad74413r_read_raw, 1048fea251b6SCosmin Tanislav .write_raw = &ad74413r_write_raw, 1049fea251b6SCosmin Tanislav .read_avail = &ad74413r_read_avail, 1050fea251b6SCosmin Tanislav .update_scan_mode = &ad74413r_update_scan_mode, 1051fea251b6SCosmin Tanislav }; 1052fea251b6SCosmin Tanislav 1053fea251b6SCosmin Tanislav #define AD74413R_DAC_CHANNEL(_type, extra_mask_separate) \ 1054fea251b6SCosmin Tanislav { \ 1055fea251b6SCosmin Tanislav .type = (_type), \ 1056fea251b6SCosmin Tanislav .indexed = 1, \ 1057fea251b6SCosmin Tanislav .output = 1, \ 1058fea251b6SCosmin Tanislav .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \ 1059fea251b6SCosmin Tanislav | (extra_mask_separate), \ 1060fea251b6SCosmin Tanislav } 1061fea251b6SCosmin Tanislav 1062fea251b6SCosmin Tanislav #define AD74413R_ADC_CHANNEL(_type, extra_mask_separate) \ 1063fea251b6SCosmin Tanislav { \ 1064fea251b6SCosmin Tanislav .type = (_type), \ 1065fea251b6SCosmin Tanislav .indexed = 1, \ 1066fea251b6SCosmin Tanislav .output = 0, \ 1067fea251b6SCosmin Tanislav .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \ 1068fea251b6SCosmin Tanislav | BIT(IIO_CHAN_INFO_SAMP_FREQ) \ 1069fea251b6SCosmin Tanislav | (extra_mask_separate), \ 1070fea251b6SCosmin Tanislav .info_mask_separate_available = \ 1071fea251b6SCosmin Tanislav BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 1072fea251b6SCosmin Tanislav .scan_type = { \ 1073fea251b6SCosmin Tanislav .sign = 'u', \ 1074fea251b6SCosmin Tanislav .realbits = 16, \ 1075fea251b6SCosmin Tanislav .storagebits = 32, \ 1076fea251b6SCosmin Tanislav .shift = 8, \ 1077fea251b6SCosmin Tanislav .endianness = IIO_BE, \ 1078fea251b6SCosmin Tanislav }, \ 1079fea251b6SCosmin Tanislav } 1080fea251b6SCosmin Tanislav 1081fea251b6SCosmin Tanislav #define AD74413R_ADC_VOLTAGE_CHANNEL \ 1082fea251b6SCosmin Tanislav AD74413R_ADC_CHANNEL(IIO_VOLTAGE, BIT(IIO_CHAN_INFO_SCALE) \ 1083fea251b6SCosmin Tanislav | BIT(IIO_CHAN_INFO_OFFSET)) 1084fea251b6SCosmin Tanislav 1085fea251b6SCosmin Tanislav #define AD74413R_ADC_CURRENT_CHANNEL \ 1086fea251b6SCosmin Tanislav AD74413R_ADC_CHANNEL(IIO_CURRENT, BIT(IIO_CHAN_INFO_SCALE) \ 1087fea251b6SCosmin Tanislav | BIT(IIO_CHAN_INFO_OFFSET)) 1088fea251b6SCosmin Tanislav 1089fea251b6SCosmin Tanislav static struct iio_chan_spec ad74413r_voltage_output_channels[] = { 1090fea251b6SCosmin Tanislav AD74413R_DAC_CHANNEL(IIO_VOLTAGE, BIT(IIO_CHAN_INFO_SCALE)), 1091fea251b6SCosmin Tanislav AD74413R_ADC_CURRENT_CHANNEL, 1092fea251b6SCosmin Tanislav }; 1093fea251b6SCosmin Tanislav 1094fea251b6SCosmin Tanislav static struct iio_chan_spec ad74413r_current_output_channels[] = { 1095fea251b6SCosmin Tanislav AD74413R_DAC_CHANNEL(IIO_CURRENT, BIT(IIO_CHAN_INFO_SCALE)), 1096fea251b6SCosmin Tanislav AD74413R_ADC_VOLTAGE_CHANNEL, 1097fea251b6SCosmin Tanislav }; 1098fea251b6SCosmin Tanislav 1099fea251b6SCosmin Tanislav static struct iio_chan_spec ad74413r_voltage_input_channels[] = { 1100fea251b6SCosmin Tanislav AD74413R_ADC_VOLTAGE_CHANNEL, 1101fea251b6SCosmin Tanislav }; 1102fea251b6SCosmin Tanislav 1103fea251b6SCosmin Tanislav static struct iio_chan_spec ad74413r_current_input_channels[] = { 1104fea251b6SCosmin Tanislav AD74413R_ADC_CURRENT_CHANNEL, 1105fea251b6SCosmin Tanislav }; 1106fea251b6SCosmin Tanislav 1107fea251b6SCosmin Tanislav static struct iio_chan_spec ad74413r_resistance_input_channels[] = { 1108fea251b6SCosmin Tanislav AD74413R_ADC_CHANNEL(IIO_RESISTANCE, BIT(IIO_CHAN_INFO_PROCESSED)), 1109fea251b6SCosmin Tanislav }; 1110fea251b6SCosmin Tanislav 1111fea251b6SCosmin Tanislav static struct iio_chan_spec ad74413r_digital_input_channels[] = { 1112fea251b6SCosmin Tanislav AD74413R_ADC_VOLTAGE_CHANNEL, 1113fea251b6SCosmin Tanislav }; 1114fea251b6SCosmin Tanislav 1115fea251b6SCosmin Tanislav #define _AD74413R_CHANNELS(_channels) \ 1116fea251b6SCosmin Tanislav { \ 1117fea251b6SCosmin Tanislav .channels = _channels, \ 1118fea251b6SCosmin Tanislav .num_channels = ARRAY_SIZE(_channels), \ 1119fea251b6SCosmin Tanislav } 1120fea251b6SCosmin Tanislav 1121fea251b6SCosmin Tanislav #define AD74413R_CHANNELS(name) \ 1122fea251b6SCosmin Tanislav _AD74413R_CHANNELS(ad74413r_ ## name ## _channels) 1123fea251b6SCosmin Tanislav 1124fea251b6SCosmin Tanislav static const struct ad74413r_channels ad74413r_channels_map[] = { 1125fea251b6SCosmin Tanislav [CH_FUNC_HIGH_IMPEDANCE] = AD74413R_CHANNELS(voltage_input), 1126fea251b6SCosmin Tanislav [CH_FUNC_VOLTAGE_OUTPUT] = AD74413R_CHANNELS(voltage_output), 1127fea251b6SCosmin Tanislav [CH_FUNC_CURRENT_OUTPUT] = AD74413R_CHANNELS(current_output), 1128fea251b6SCosmin Tanislav [CH_FUNC_VOLTAGE_INPUT] = AD74413R_CHANNELS(voltage_input), 1129fea251b6SCosmin Tanislav [CH_FUNC_CURRENT_INPUT_EXT_POWER] = AD74413R_CHANNELS(current_input), 1130fea251b6SCosmin Tanislav [CH_FUNC_CURRENT_INPUT_LOOP_POWER] = AD74413R_CHANNELS(current_input), 1131fea251b6SCosmin Tanislav [CH_FUNC_RESISTANCE_INPUT] = AD74413R_CHANNELS(resistance_input), 1132fea251b6SCosmin Tanislav [CH_FUNC_DIGITAL_INPUT_LOGIC] = AD74413R_CHANNELS(digital_input), 1133fea251b6SCosmin Tanislav [CH_FUNC_DIGITAL_INPUT_LOOP_POWER] = AD74413R_CHANNELS(digital_input), 1134fea251b6SCosmin Tanislav [CH_FUNC_CURRENT_INPUT_EXT_POWER_HART] = AD74413R_CHANNELS(current_input), 1135fea251b6SCosmin Tanislav [CH_FUNC_CURRENT_INPUT_LOOP_POWER_HART] = AD74413R_CHANNELS(current_input), 1136fea251b6SCosmin Tanislav }; 1137fea251b6SCosmin Tanislav 1138fea251b6SCosmin Tanislav static int ad74413r_parse_channel_config(struct iio_dev *indio_dev, 1139fea251b6SCosmin Tanislav struct fwnode_handle *channel_node) 1140fea251b6SCosmin Tanislav { 1141fea251b6SCosmin Tanislav struct ad74413r_state *st = iio_priv(indio_dev); 1142fea251b6SCosmin Tanislav struct ad74413r_channel_config *config; 1143fea251b6SCosmin Tanislav u32 index; 1144fea251b6SCosmin Tanislav int ret; 1145fea251b6SCosmin Tanislav 1146fea251b6SCosmin Tanislav ret = fwnode_property_read_u32(channel_node, "reg", &index); 1147fea251b6SCosmin Tanislav if (ret) { 1148fea251b6SCosmin Tanislav dev_err(st->dev, "Failed to read channel reg: %d\n", ret); 1149fea251b6SCosmin Tanislav return ret; 1150fea251b6SCosmin Tanislav } 1151fea251b6SCosmin Tanislav 11525d97d9e9SDan Carpenter if (index >= AD74413R_CHANNEL_MAX) { 1153fea251b6SCosmin Tanislav dev_err(st->dev, "Channel index %u is too large\n", index); 1154fea251b6SCosmin Tanislav return -EINVAL; 1155fea251b6SCosmin Tanislav } 1156fea251b6SCosmin Tanislav 1157fea251b6SCosmin Tanislav config = &st->channel_configs[index]; 1158fea251b6SCosmin Tanislav if (config->initialized) { 1159fea251b6SCosmin Tanislav dev_err(st->dev, "Channel %u already initialized\n", index); 1160fea251b6SCosmin Tanislav return -EINVAL; 1161fea251b6SCosmin Tanislav } 1162fea251b6SCosmin Tanislav 1163fea251b6SCosmin Tanislav config->func = CH_FUNC_HIGH_IMPEDANCE; 1164fea251b6SCosmin Tanislav fwnode_property_read_u32(channel_node, "adi,ch-func", &config->func); 1165fea251b6SCosmin Tanislav 1166fea251b6SCosmin Tanislav if (config->func < CH_FUNC_MIN || config->func > CH_FUNC_MAX) { 1167fea251b6SCosmin Tanislav dev_err(st->dev, "Invalid channel function %u\n", config->func); 1168fea251b6SCosmin Tanislav return -EINVAL; 1169fea251b6SCosmin Tanislav } 1170fea251b6SCosmin Tanislav 1171fea251b6SCosmin Tanislav if (!st->chip_info->hart_support && 1172fea251b6SCosmin Tanislav (config->func == CH_FUNC_CURRENT_INPUT_EXT_POWER_HART || 1173fea251b6SCosmin Tanislav config->func == CH_FUNC_CURRENT_INPUT_LOOP_POWER_HART)) { 1174fea251b6SCosmin Tanislav dev_err(st->dev, "Unsupported HART function %u\n", config->func); 1175fea251b6SCosmin Tanislav return -EINVAL; 1176fea251b6SCosmin Tanislav } 1177fea251b6SCosmin Tanislav 1178fea251b6SCosmin Tanislav if (config->func == CH_FUNC_DIGITAL_INPUT_LOGIC || 1179fea251b6SCosmin Tanislav config->func == CH_FUNC_DIGITAL_INPUT_LOOP_POWER) 1180fea251b6SCosmin Tanislav st->num_comparator_gpios++; 1181fea251b6SCosmin Tanislav 1182fea251b6SCosmin Tanislav config->gpo_comparator = fwnode_property_read_bool(channel_node, 1183fea251b6SCosmin Tanislav "adi,gpo-comparator"); 1184fea251b6SCosmin Tanislav 1185fea251b6SCosmin Tanislav if (!config->gpo_comparator) 1186fea251b6SCosmin Tanislav st->num_gpo_gpios++; 1187fea251b6SCosmin Tanislav 1188fea251b6SCosmin Tanislav indio_dev->num_channels += ad74413r_channels_map[config->func].num_channels; 1189fea251b6SCosmin Tanislav 1190fea251b6SCosmin Tanislav config->initialized = true; 1191fea251b6SCosmin Tanislav 1192fea251b6SCosmin Tanislav return 0; 1193fea251b6SCosmin Tanislav } 1194fea251b6SCosmin Tanislav 1195fea251b6SCosmin Tanislav static int ad74413r_parse_channel_configs(struct iio_dev *indio_dev) 1196fea251b6SCosmin Tanislav { 1197fea251b6SCosmin Tanislav struct ad74413r_state *st = iio_priv(indio_dev); 1198fea251b6SCosmin Tanislav struct fwnode_handle *channel_node = NULL; 1199fea251b6SCosmin Tanislav int ret; 1200fea251b6SCosmin Tanislav 1201fea251b6SCosmin Tanislav fwnode_for_each_available_child_node(dev_fwnode(st->dev), channel_node) { 1202fea251b6SCosmin Tanislav ret = ad74413r_parse_channel_config(indio_dev, channel_node); 1203fea251b6SCosmin Tanislav if (ret) 1204fea251b6SCosmin Tanislav goto put_channel_node; 1205fea251b6SCosmin Tanislav } 1206fea251b6SCosmin Tanislav 1207fea251b6SCosmin Tanislav return 0; 1208fea251b6SCosmin Tanislav 1209fea251b6SCosmin Tanislav put_channel_node: 1210fea251b6SCosmin Tanislav fwnode_handle_put(channel_node); 1211fea251b6SCosmin Tanislav 1212fea251b6SCosmin Tanislav return ret; 1213fea251b6SCosmin Tanislav } 1214fea251b6SCosmin Tanislav 1215fea251b6SCosmin Tanislav static int ad74413r_setup_channels(struct iio_dev *indio_dev) 1216fea251b6SCosmin Tanislav { 1217fea251b6SCosmin Tanislav struct ad74413r_state *st = iio_priv(indio_dev); 1218fea251b6SCosmin Tanislav struct ad74413r_channel_config *config; 1219fea251b6SCosmin Tanislav struct iio_chan_spec *channels, *chans; 1220fea251b6SCosmin Tanislav unsigned int i, num_chans, chan_i; 1221fea251b6SCosmin Tanislav int ret; 1222fea251b6SCosmin Tanislav 1223fea251b6SCosmin Tanislav channels = devm_kcalloc(st->dev, sizeof(*channels), 1224fea251b6SCosmin Tanislav indio_dev->num_channels, GFP_KERNEL); 1225fea251b6SCosmin Tanislav if (!channels) 1226fea251b6SCosmin Tanislav return -ENOMEM; 1227fea251b6SCosmin Tanislav 1228fea251b6SCosmin Tanislav indio_dev->channels = channels; 1229fea251b6SCosmin Tanislav 1230fea251b6SCosmin Tanislav for (i = 0; i < AD74413R_CHANNEL_MAX; i++) { 1231fea251b6SCosmin Tanislav config = &st->channel_configs[i]; 1232fea251b6SCosmin Tanislav chans = ad74413r_channels_map[config->func].channels; 1233fea251b6SCosmin Tanislav num_chans = ad74413r_channels_map[config->func].num_channels; 1234fea251b6SCosmin Tanislav 1235fea251b6SCosmin Tanislav memcpy(channels, chans, num_chans * sizeof(*chans)); 1236fea251b6SCosmin Tanislav 1237fea251b6SCosmin Tanislav for (chan_i = 0; chan_i < num_chans; chan_i++) { 1238fea251b6SCosmin Tanislav struct iio_chan_spec *chan = &channels[chan_i]; 1239fea251b6SCosmin Tanislav 1240fea251b6SCosmin Tanislav chan->channel = i; 1241fea251b6SCosmin Tanislav if (chan->output) 1242fea251b6SCosmin Tanislav chan->scan_index = -1; 1243fea251b6SCosmin Tanislav else 1244fea251b6SCosmin Tanislav chan->scan_index = i; 1245fea251b6SCosmin Tanislav } 1246fea251b6SCosmin Tanislav 1247fea251b6SCosmin Tanislav ret = ad74413r_set_channel_function(st, i, config->func); 1248fea251b6SCosmin Tanislav if (ret) 1249fea251b6SCosmin Tanislav return ret; 1250fea251b6SCosmin Tanislav 1251fea251b6SCosmin Tanislav channels += num_chans; 1252fea251b6SCosmin Tanislav } 1253fea251b6SCosmin Tanislav 1254fea251b6SCosmin Tanislav return 0; 1255fea251b6SCosmin Tanislav } 1256fea251b6SCosmin Tanislav 1257fea251b6SCosmin Tanislav static int ad74413r_setup_gpios(struct ad74413r_state *st) 1258fea251b6SCosmin Tanislav { 1259fea251b6SCosmin Tanislav struct ad74413r_channel_config *config; 1260fea251b6SCosmin Tanislav unsigned int comp_gpio_i = 0; 1261fea251b6SCosmin Tanislav unsigned int gpo_gpio_i = 0; 1262fea251b6SCosmin Tanislav unsigned int i; 1263fea251b6SCosmin Tanislav u8 gpo_config; 1264fea251b6SCosmin Tanislav int ret; 1265fea251b6SCosmin Tanislav 1266fea251b6SCosmin Tanislav for (i = 0; i < AD74413R_CHANNEL_MAX; i++) { 1267fea251b6SCosmin Tanislav config = &st->channel_configs[i]; 1268fea251b6SCosmin Tanislav 1269fea251b6SCosmin Tanislav if (config->gpo_comparator) { 1270fea251b6SCosmin Tanislav gpo_config = AD74413R_GPO_CONFIG_COMPARATOR; 1271fea251b6SCosmin Tanislav } else { 1272fea251b6SCosmin Tanislav gpo_config = AD74413R_GPO_CONFIG_LOGIC; 1273fea251b6SCosmin Tanislav st->gpo_gpio_offsets[gpo_gpio_i++] = i; 1274fea251b6SCosmin Tanislav } 1275fea251b6SCosmin Tanislav 1276fea251b6SCosmin Tanislav if (config->func == CH_FUNC_DIGITAL_INPUT_LOGIC || 1277fea251b6SCosmin Tanislav config->func == CH_FUNC_DIGITAL_INPUT_LOOP_POWER) 1278fea251b6SCosmin Tanislav st->comp_gpio_offsets[comp_gpio_i++] = i; 1279fea251b6SCosmin Tanislav 1280fea251b6SCosmin Tanislav ret = ad74413r_set_gpo_config(st, i, gpo_config); 1281fea251b6SCosmin Tanislav if (ret) 1282fea251b6SCosmin Tanislav return ret; 1283fea251b6SCosmin Tanislav } 1284fea251b6SCosmin Tanislav 1285fea251b6SCosmin Tanislav return 0; 1286fea251b6SCosmin Tanislav } 1287fea251b6SCosmin Tanislav 1288fea251b6SCosmin Tanislav static void ad74413r_regulator_disable(void *regulator) 1289fea251b6SCosmin Tanislav { 1290fea251b6SCosmin Tanislav regulator_disable(regulator); 1291fea251b6SCosmin Tanislav } 1292fea251b6SCosmin Tanislav 1293fea251b6SCosmin Tanislav static int ad74413r_probe(struct spi_device *spi) 1294fea251b6SCosmin Tanislav { 1295fea251b6SCosmin Tanislav struct ad74413r_state *st; 1296fea251b6SCosmin Tanislav struct iio_dev *indio_dev; 1297fea251b6SCosmin Tanislav int ret; 1298fea251b6SCosmin Tanislav 1299fea251b6SCosmin Tanislav indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); 1300fea251b6SCosmin Tanislav if (!indio_dev) 1301fea251b6SCosmin Tanislav return -ENOMEM; 1302fea251b6SCosmin Tanislav 1303fea251b6SCosmin Tanislav st = iio_priv(indio_dev); 1304fea251b6SCosmin Tanislav 1305fea251b6SCosmin Tanislav st->spi = spi; 1306fea251b6SCosmin Tanislav st->dev = &spi->dev; 1307fea251b6SCosmin Tanislav st->chip_info = device_get_match_data(&spi->dev); 1308fea251b6SCosmin Tanislav mutex_init(&st->lock); 1309fea251b6SCosmin Tanislav init_completion(&st->adc_data_completion); 1310fea251b6SCosmin Tanislav 1311fea251b6SCosmin Tanislav st->regmap = devm_regmap_init(st->dev, NULL, st, 1312fea251b6SCosmin Tanislav &ad74413r_regmap_config); 1313fea251b6SCosmin Tanislav if (IS_ERR(st->regmap)) 1314fea251b6SCosmin Tanislav return PTR_ERR(st->regmap); 1315fea251b6SCosmin Tanislav 1316fea251b6SCosmin Tanislav st->refin_reg = devm_regulator_get(st->dev, "refin"); 1317fea251b6SCosmin Tanislav if (IS_ERR(st->refin_reg)) 1318fea251b6SCosmin Tanislav return dev_err_probe(st->dev, PTR_ERR(st->refin_reg), 1319fea251b6SCosmin Tanislav "Failed to get refin regulator\n"); 1320fea251b6SCosmin Tanislav 1321fea251b6SCosmin Tanislav ret = regulator_enable(st->refin_reg); 1322fea251b6SCosmin Tanislav if (ret) 1323fea251b6SCosmin Tanislav return ret; 1324fea251b6SCosmin Tanislav 1325fea251b6SCosmin Tanislav ret = devm_add_action_or_reset(st->dev, ad74413r_regulator_disable, 1326fea251b6SCosmin Tanislav st->refin_reg); 1327fea251b6SCosmin Tanislav if (ret) 1328fea251b6SCosmin Tanislav return ret; 1329fea251b6SCosmin Tanislav 1330fea251b6SCosmin Tanislav st->sense_resistor_ohms = 100000000; 1331fea251b6SCosmin Tanislav device_property_read_u32(st->dev, "shunt-resistor-micro-ohms", 1332fea251b6SCosmin Tanislav &st->sense_resistor_ohms); 1333fea251b6SCosmin Tanislav st->sense_resistor_ohms /= 1000000; 1334fea251b6SCosmin Tanislav 1335fea251b6SCosmin Tanislav st->trig = devm_iio_trigger_alloc(st->dev, "%s-dev%d", 1336fea251b6SCosmin Tanislav st->chip_info->name, iio_device_id(indio_dev)); 1337fea251b6SCosmin Tanislav if (!st->trig) 1338fea251b6SCosmin Tanislav return -ENOMEM; 1339fea251b6SCosmin Tanislav 1340fea251b6SCosmin Tanislav st->trig->ops = &ad74413r_trigger_ops; 1341fea251b6SCosmin Tanislav iio_trigger_set_drvdata(st->trig, st); 1342fea251b6SCosmin Tanislav 1343fea251b6SCosmin Tanislav ret = devm_iio_trigger_register(st->dev, st->trig); 1344fea251b6SCosmin Tanislav if (ret) 1345fea251b6SCosmin Tanislav return ret; 1346fea251b6SCosmin Tanislav 1347fea251b6SCosmin Tanislav indio_dev->name = st->chip_info->name; 1348fea251b6SCosmin Tanislav indio_dev->modes = INDIO_DIRECT_MODE; 1349fea251b6SCosmin Tanislav indio_dev->info = &ad74413r_info; 1350fea251b6SCosmin Tanislav indio_dev->trig = iio_trigger_get(st->trig); 1351fea251b6SCosmin Tanislav 1352fea251b6SCosmin Tanislav ret = ad74413r_reset(st); 1353fea251b6SCosmin Tanislav if (ret) 1354fea251b6SCosmin Tanislav return ret; 1355fea251b6SCosmin Tanislav 1356fea251b6SCosmin Tanislav ret = ad74413r_parse_channel_configs(indio_dev); 1357fea251b6SCosmin Tanislav if (ret) 1358fea251b6SCosmin Tanislav return ret; 1359fea251b6SCosmin Tanislav 1360fea251b6SCosmin Tanislav ret = ad74413r_setup_channels(indio_dev); 1361fea251b6SCosmin Tanislav if (ret) 1362fea251b6SCosmin Tanislav return ret; 1363fea251b6SCosmin Tanislav 1364fea251b6SCosmin Tanislav ret = ad74413r_setup_gpios(st); 1365fea251b6SCosmin Tanislav if (ret) 1366fea251b6SCosmin Tanislav return ret; 1367fea251b6SCosmin Tanislav 1368fea251b6SCosmin Tanislav if (st->num_gpo_gpios) { 1369fea251b6SCosmin Tanislav st->gpo_gpiochip.owner = THIS_MODULE; 1370fea251b6SCosmin Tanislav st->gpo_gpiochip.label = st->chip_info->name; 1371fea251b6SCosmin Tanislav st->gpo_gpiochip.base = -1; 1372fea251b6SCosmin Tanislav st->gpo_gpiochip.ngpio = st->num_gpo_gpios; 1373fea251b6SCosmin Tanislav st->gpo_gpiochip.parent = st->dev; 1374fea251b6SCosmin Tanislav st->gpo_gpiochip.can_sleep = true; 1375fea251b6SCosmin Tanislav st->gpo_gpiochip.set = ad74413r_gpio_set; 1376fea251b6SCosmin Tanislav st->gpo_gpiochip.set_multiple = ad74413r_gpio_set_multiple; 1377fea251b6SCosmin Tanislav st->gpo_gpiochip.set_config = ad74413r_gpio_set_gpo_config; 1378fea251b6SCosmin Tanislav st->gpo_gpiochip.get_direction = 1379fea251b6SCosmin Tanislav ad74413r_gpio_get_gpo_direction; 1380fea251b6SCosmin Tanislav 1381fea251b6SCosmin Tanislav ret = devm_gpiochip_add_data(st->dev, &st->gpo_gpiochip, st); 1382fea251b6SCosmin Tanislav if (ret) 1383fea251b6SCosmin Tanislav return ret; 1384fea251b6SCosmin Tanislav } 1385fea251b6SCosmin Tanislav 1386fea251b6SCosmin Tanislav if (st->num_comparator_gpios) { 1387fea251b6SCosmin Tanislav st->comp_gpiochip.owner = THIS_MODULE; 1388fea251b6SCosmin Tanislav st->comp_gpiochip.label = st->chip_info->name; 1389fea251b6SCosmin Tanislav st->comp_gpiochip.base = -1; 1390fea251b6SCosmin Tanislav st->comp_gpiochip.ngpio = st->num_comparator_gpios; 1391fea251b6SCosmin Tanislav st->comp_gpiochip.parent = st->dev; 1392fea251b6SCosmin Tanislav st->comp_gpiochip.can_sleep = true; 1393fea251b6SCosmin Tanislav st->comp_gpiochip.get = ad74413r_gpio_get; 1394fea251b6SCosmin Tanislav st->comp_gpiochip.get_multiple = ad74413r_gpio_get_multiple; 1395fea251b6SCosmin Tanislav st->comp_gpiochip.set_config = ad74413r_gpio_set_comp_config; 1396fea251b6SCosmin Tanislav st->comp_gpiochip.get_direction = 1397fea251b6SCosmin Tanislav ad74413r_gpio_get_comp_direction; 1398fea251b6SCosmin Tanislav 1399fea251b6SCosmin Tanislav ret = devm_gpiochip_add_data(st->dev, &st->comp_gpiochip, st); 1400fea251b6SCosmin Tanislav if (ret) 1401fea251b6SCosmin Tanislav return ret; 1402fea251b6SCosmin Tanislav } 1403fea251b6SCosmin Tanislav 1404fea251b6SCosmin Tanislav ret = ad74413r_set_adc_conv_seq(st, AD74413R_CONV_SEQ_OFF); 1405fea251b6SCosmin Tanislav if (ret) 1406fea251b6SCosmin Tanislav return ret; 1407fea251b6SCosmin Tanislav 1408fea251b6SCosmin Tanislav ret = devm_request_irq(st->dev, spi->irq, ad74413r_adc_data_interrupt, 1409fea251b6SCosmin Tanislav 0, st->chip_info->name, indio_dev); 1410fea251b6SCosmin Tanislav if (ret) 1411fea251b6SCosmin Tanislav return dev_err_probe(st->dev, ret, "Failed to request irq\n"); 1412fea251b6SCosmin Tanislav 1413fea251b6SCosmin Tanislav ret = devm_iio_triggered_buffer_setup(st->dev, indio_dev, 1414fea251b6SCosmin Tanislav &iio_pollfunc_store_time, 1415fea251b6SCosmin Tanislav &ad74413r_trigger_handler, 1416fea251b6SCosmin Tanislav &ad74413r_buffer_ops); 1417fea251b6SCosmin Tanislav if (ret) 1418fea251b6SCosmin Tanislav return ret; 1419fea251b6SCosmin Tanislav 1420fea251b6SCosmin Tanislav return devm_iio_device_register(st->dev, indio_dev); 1421fea251b6SCosmin Tanislav } 1422fea251b6SCosmin Tanislav 1423fea251b6SCosmin Tanislav static int ad74413r_unregister_driver(struct spi_driver *spi) 1424fea251b6SCosmin Tanislav { 1425fea251b6SCosmin Tanislav spi_unregister_driver(spi); 1426fea251b6SCosmin Tanislav 1427fea251b6SCosmin Tanislav return 0; 1428fea251b6SCosmin Tanislav } 1429fea251b6SCosmin Tanislav 1430fea251b6SCosmin Tanislav static int __init ad74413r_register_driver(struct spi_driver *spi) 1431fea251b6SCosmin Tanislav { 1432fea251b6SCosmin Tanislav crc8_populate_msb(ad74413r_crc8_table, AD74413R_CRC_POLYNOMIAL); 1433fea251b6SCosmin Tanislav 1434fea251b6SCosmin Tanislav return spi_register_driver(spi); 1435fea251b6SCosmin Tanislav } 1436fea251b6SCosmin Tanislav 1437fea251b6SCosmin Tanislav static const struct ad74413r_chip_info ad74412r_chip_info_data = { 1438fea251b6SCosmin Tanislav .hart_support = false, 1439fea251b6SCosmin Tanislav .name = "ad74412r", 1440fea251b6SCosmin Tanislav }; 1441fea251b6SCosmin Tanislav 1442fea251b6SCosmin Tanislav static const struct ad74413r_chip_info ad74413r_chip_info_data = { 1443fea251b6SCosmin Tanislav .hart_support = true, 1444fea251b6SCosmin Tanislav .name = "ad74413r", 1445fea251b6SCosmin Tanislav }; 1446fea251b6SCosmin Tanislav 1447fea251b6SCosmin Tanislav static const struct of_device_id ad74413r_dt_id[] = { 1448fea251b6SCosmin Tanislav { 1449fea251b6SCosmin Tanislav .compatible = "adi,ad74412r", 1450fea251b6SCosmin Tanislav .data = &ad74412r_chip_info_data, 1451fea251b6SCosmin Tanislav }, 1452fea251b6SCosmin Tanislav { 1453fea251b6SCosmin Tanislav .compatible = "adi,ad74413r", 1454fea251b6SCosmin Tanislav .data = &ad74413r_chip_info_data, 1455fea251b6SCosmin Tanislav }, 1456fea251b6SCosmin Tanislav {}, 1457fea251b6SCosmin Tanislav }; 1458fea251b6SCosmin Tanislav MODULE_DEVICE_TABLE(of, ad74413r_dt_id); 1459fea251b6SCosmin Tanislav 1460fea251b6SCosmin Tanislav static struct spi_driver ad74413r_driver = { 1461fea251b6SCosmin Tanislav .driver = { 1462fea251b6SCosmin Tanislav .name = "ad74413r", 1463fea251b6SCosmin Tanislav .of_match_table = ad74413r_dt_id, 1464fea251b6SCosmin Tanislav }, 1465fea251b6SCosmin Tanislav .probe = ad74413r_probe, 1466fea251b6SCosmin Tanislav }; 1467fea251b6SCosmin Tanislav 1468fea251b6SCosmin Tanislav module_driver(ad74413r_driver, 1469fea251b6SCosmin Tanislav ad74413r_register_driver, 1470fea251b6SCosmin Tanislav ad74413r_unregister_driver); 1471fea251b6SCosmin Tanislav 1472fea251b6SCosmin Tanislav MODULE_AUTHOR("Cosmin Tanislav <cosmin.tanislav@analog.com>"); 1473fea251b6SCosmin Tanislav MODULE_DESCRIPTION("Analog Devices AD74413R ADDAC"); 1474fea251b6SCosmin Tanislav MODULE_LICENSE("GPL v2"); 1475