723 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * AD4000 SPI ADC driver4 *5 * Copyright 2024 Analog Devices Inc.6 */7#include <linux/bits.h>8#include <linux/bitfield.h>9#include <linux/byteorder/generic.h>10#include <linux/cleanup.h>11#include <linux/device.h>12#include <linux/err.h>13#include <linux/math.h>14#include <linux/module.h>15#include <linux/mod_devicetable.h>16#include <linux/gpio/consumer.h>17#include <linux/regulator/consumer.h>18#include <linux/spi/spi.h>19#include <linux/units.h>20#include <linux/util_macros.h>21#include <linux/iio/iio.h>22 23#include <linux/iio/buffer.h>24#include <linux/iio/triggered_buffer.h>25#include <linux/iio/trigger_consumer.h>26 27#define AD4000_READ_COMMAND 0x5428#define AD4000_WRITE_COMMAND 0x1429 30#define AD4000_CONFIG_REG_DEFAULT 0xE131 32/* AD4000 Configuration Register programmable bits */33#define AD4000_CFG_SPAN_COMP BIT(3) /* Input span compression */34#define AD4000_CFG_HIGHZ BIT(2) /* High impedance mode */35 36#define AD4000_SCALE_OPTIONS 237 38#define AD4000_TQUIET1_NS 19039#define AD4000_TQUIET2_NS 6040#define AD4000_TCONV_NS 32041 42#define __AD4000_DIFF_CHANNEL(_sign, _real_bits, _storage_bits, _reg_access) \43{ \44 .type = IIO_VOLTAGE, \45 .indexed = 1, \46 .differential = 1, \47 .channel = 0, \48 .channel2 = 1, \49 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \50 BIT(IIO_CHAN_INFO_SCALE), \51 .info_mask_separate_available = _reg_access ? BIT(IIO_CHAN_INFO_SCALE) : 0,\52 .scan_type = { \53 .sign = _sign, \54 .realbits = _real_bits, \55 .storagebits = _storage_bits, \56 .shift = _storage_bits - _real_bits, \57 .endianness = IIO_BE, \58 }, \59}60 61#define AD4000_DIFF_CHANNEL(_sign, _real_bits, _reg_access) \62 __AD4000_DIFF_CHANNEL((_sign), (_real_bits), \63 ((_real_bits) > 16 ? 32 : 16), (_reg_access))64 65#define __AD4000_PSEUDO_DIFF_CHANNEL(_sign, _real_bits, _storage_bits, _reg_access)\66{ \67 .type = IIO_VOLTAGE, \68 .indexed = 1, \69 .channel = 0, \70 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \71 BIT(IIO_CHAN_INFO_SCALE) | \72 BIT(IIO_CHAN_INFO_OFFSET), \73 .info_mask_separate_available = _reg_access ? BIT(IIO_CHAN_INFO_SCALE) : 0,\74 .scan_type = { \75 .sign = _sign, \76 .realbits = _real_bits, \77 .storagebits = _storage_bits, \78 .shift = _storage_bits - _real_bits, \79 .endianness = IIO_BE, \80 }, \81}82 83#define AD4000_PSEUDO_DIFF_CHANNEL(_sign, _real_bits, _reg_access) \84 __AD4000_PSEUDO_DIFF_CHANNEL((_sign), (_real_bits), \85 ((_real_bits) > 16 ? 32 : 16), (_reg_access))86 87static const char * const ad4000_power_supplies[] = {88 "vdd", "vio"89};90 91enum ad4000_sdi {92 AD4000_SDI_MOSI,93 AD4000_SDI_VIO,94 AD4000_SDI_CS,95 AD4000_SDI_GND,96};97 98/* maps adi,sdi-pin property value to enum */99static const char * const ad4000_sdi_pin[] = {100 [AD4000_SDI_MOSI] = "sdi",101 [AD4000_SDI_VIO] = "high",102 [AD4000_SDI_CS] = "cs",103 [AD4000_SDI_GND] = "low",104};105 106/* Gains stored as fractions of 1000 so they can be expressed by integers. */107static const int ad4000_gains[] = {108 454, 909, 1000, 1900,109};110 111struct ad4000_chip_info {112 const char *dev_name;113 struct iio_chan_spec chan_spec;114 struct iio_chan_spec reg_access_chan_spec;115 bool has_hardware_gain;116};117 118static const struct ad4000_chip_info ad4000_chip_info = {119 .dev_name = "ad4000",120 .chan_spec = AD4000_PSEUDO_DIFF_CHANNEL('u', 16, 0),121 .reg_access_chan_spec = AD4000_PSEUDO_DIFF_CHANNEL('u', 16, 1),122};123 124static const struct ad4000_chip_info ad4001_chip_info = {125 .dev_name = "ad4001",126 .chan_spec = AD4000_DIFF_CHANNEL('s', 16, 0),127 .reg_access_chan_spec = AD4000_DIFF_CHANNEL('s', 16, 1),128};129 130static const struct ad4000_chip_info ad4002_chip_info = {131 .dev_name = "ad4002",132 .chan_spec = AD4000_PSEUDO_DIFF_CHANNEL('u', 18, 0),133 .reg_access_chan_spec = AD4000_PSEUDO_DIFF_CHANNEL('u', 18, 1),134};135 136static const struct ad4000_chip_info ad4003_chip_info = {137 .dev_name = "ad4003",138 .chan_spec = AD4000_DIFF_CHANNEL('s', 18, 0),139 .reg_access_chan_spec = AD4000_DIFF_CHANNEL('s', 18, 1),140};141 142static const struct ad4000_chip_info ad4004_chip_info = {143 .dev_name = "ad4004",144 .chan_spec = AD4000_PSEUDO_DIFF_CHANNEL('u', 16, 0),145 .reg_access_chan_spec = AD4000_PSEUDO_DIFF_CHANNEL('u', 16, 1),146};147 148static const struct ad4000_chip_info ad4005_chip_info = {149 .dev_name = "ad4005",150 .chan_spec = AD4000_DIFF_CHANNEL('s', 16, 0),151 .reg_access_chan_spec = AD4000_DIFF_CHANNEL('s', 16, 1),152};153 154static const struct ad4000_chip_info ad4006_chip_info = {155 .dev_name = "ad4006",156 .chan_spec = AD4000_PSEUDO_DIFF_CHANNEL('u', 18, 0),157 .reg_access_chan_spec = AD4000_PSEUDO_DIFF_CHANNEL('u', 18, 1),158};159 160static const struct ad4000_chip_info ad4007_chip_info = {161 .dev_name = "ad4007",162 .chan_spec = AD4000_DIFF_CHANNEL('s', 18, 0),163 .reg_access_chan_spec = AD4000_DIFF_CHANNEL('s', 18, 1),164};165 166static const struct ad4000_chip_info ad4008_chip_info = {167 .dev_name = "ad4008",168 .chan_spec = AD4000_PSEUDO_DIFF_CHANNEL('u', 16, 0),169 .reg_access_chan_spec = AD4000_PSEUDO_DIFF_CHANNEL('u', 16, 1),170};171 172static const struct ad4000_chip_info ad4010_chip_info = {173 .dev_name = "ad4010",174 .chan_spec = AD4000_PSEUDO_DIFF_CHANNEL('u', 18, 0),175 .reg_access_chan_spec = AD4000_PSEUDO_DIFF_CHANNEL('u', 18, 1),176};177 178static const struct ad4000_chip_info ad4011_chip_info = {179 .dev_name = "ad4011",180 .chan_spec = AD4000_DIFF_CHANNEL('s', 18, 0),181 .reg_access_chan_spec = AD4000_DIFF_CHANNEL('s', 18, 1),182};183 184static const struct ad4000_chip_info ad4020_chip_info = {185 .dev_name = "ad4020",186 .chan_spec = AD4000_DIFF_CHANNEL('s', 20, 0),187 .reg_access_chan_spec = AD4000_DIFF_CHANNEL('s', 20, 1),188};189 190static const struct ad4000_chip_info ad4021_chip_info = {191 .dev_name = "ad4021",192 .chan_spec = AD4000_DIFF_CHANNEL('s', 20, 0),193 .reg_access_chan_spec = AD4000_DIFF_CHANNEL('s', 20, 1),194};195 196static const struct ad4000_chip_info ad4022_chip_info = {197 .dev_name = "ad4022",198 .chan_spec = AD4000_DIFF_CHANNEL('s', 20, 0),199 .reg_access_chan_spec = AD4000_DIFF_CHANNEL('s', 20, 1),200};201 202static const struct ad4000_chip_info adaq4001_chip_info = {203 .dev_name = "adaq4001",204 .chan_spec = AD4000_DIFF_CHANNEL('s', 16, 0),205 .reg_access_chan_spec = AD4000_DIFF_CHANNEL('s', 16, 1),206 .has_hardware_gain = true,207};208 209static const struct ad4000_chip_info adaq4003_chip_info = {210 .dev_name = "adaq4003",211 .chan_spec = AD4000_DIFF_CHANNEL('s', 18, 0),212 .reg_access_chan_spec = AD4000_DIFF_CHANNEL('s', 18, 1),213 .has_hardware_gain = true,214};215 216struct ad4000_state {217 struct spi_device *spi;218 struct gpio_desc *cnv_gpio;219 struct spi_transfer xfers[2];220 struct spi_message msg;221 struct mutex lock; /* Protect read modify write cycle */222 int vref_mv;223 enum ad4000_sdi sdi_pin;224 bool span_comp;225 u16 gain_milli;226 int scale_tbl[AD4000_SCALE_OPTIONS][2];227 228 /*229 * DMA (thus cache coherency maintenance) requires the transfer buffers230 * to live in their own cache lines.231 */232 struct {233 union {234 __be16 sample_buf16;235 __be32 sample_buf32;236 } data;237 s64 timestamp __aligned(8);238 } scan __aligned(IIO_DMA_MINALIGN);239 u8 tx_buf[2];240 u8 rx_buf[2];241};242 243static void ad4000_fill_scale_tbl(struct ad4000_state *st,244 struct iio_chan_spec const *chan)245{246 int val, tmp0, tmp1;247 int scale_bits;248 u64 tmp2;249 250 /*251 * ADCs that output two's complement code have one less bit to express252 * voltage magnitude.253 */254 if (chan->scan_type.sign == 's')255 scale_bits = chan->scan_type.realbits - 1;256 else257 scale_bits = chan->scan_type.realbits;258 259 /*260 * The gain is stored as a fraction of 1000 and, as we need to261 * divide vref_mv by the gain, we invert the gain/1000 fraction.262 * Also multiply by an extra MILLI to preserve precision.263 * Thus, we have MILLI * MILLI equals MICRO as fraction numerator.264 */265 val = mult_frac(st->vref_mv, MICRO, st->gain_milli);266 267 /* Would multiply by NANO here but we multiplied by extra MILLI */268 tmp2 = shift_right((u64)val * MICRO, scale_bits);269 tmp0 = div_s64_rem(tmp2, NANO, &tmp1);270 271 /* Store scale for when span compression is disabled */272 st->scale_tbl[0][0] = tmp0; /* Integer part */273 st->scale_tbl[0][1] = abs(tmp1); /* Fractional part */274 275 /* Store scale for when span compression is enabled */276 st->scale_tbl[1][0] = tmp0;277 278 /* The integer part is always zero so don't bother to divide it. */279 if (chan->differential)280 st->scale_tbl[1][1] = DIV_ROUND_CLOSEST(abs(tmp1) * 4, 5);281 else282 st->scale_tbl[1][1] = DIV_ROUND_CLOSEST(abs(tmp1) * 9, 10);283}284 285static int ad4000_write_reg(struct ad4000_state *st, uint8_t val)286{287 st->tx_buf[0] = AD4000_WRITE_COMMAND;288 st->tx_buf[1] = val;289 return spi_write(st->spi, st->tx_buf, ARRAY_SIZE(st->tx_buf));290}291 292static int ad4000_read_reg(struct ad4000_state *st, unsigned int *val)293{294 struct spi_transfer t = {295 .tx_buf = st->tx_buf,296 .rx_buf = st->rx_buf,297 .len = 2,298 };299 int ret;300 301 st->tx_buf[0] = AD4000_READ_COMMAND;302 ret = spi_sync_transfer(st->spi, &t, 1);303 if (ret < 0)304 return ret;305 306 *val = st->rx_buf[1];307 return ret;308}309 310static int ad4000_convert_and_acquire(struct ad4000_state *st)311{312 int ret;313 314 /*315 * In 4-wire mode, the CNV line is held high for the entire conversion316 * and acquisition process. In other modes, the CNV GPIO is optional317 * and, if provided, replaces controller CS. If CNV GPIO is not defined318 * gpiod_set_value_cansleep() has no effect.319 */320 gpiod_set_value_cansleep(st->cnv_gpio, 1);321 ret = spi_sync(st->spi, &st->msg);322 gpiod_set_value_cansleep(st->cnv_gpio, 0);323 324 return ret;325}326 327static int ad4000_single_conversion(struct iio_dev *indio_dev,328 const struct iio_chan_spec *chan, int *val)329{330 struct ad4000_state *st = iio_priv(indio_dev);331 u32 sample;332 int ret;333 334 ret = ad4000_convert_and_acquire(st);335 if (ret < 0)336 return ret;337 338 if (chan->scan_type.storagebits > 16)339 sample = be32_to_cpu(st->scan.data.sample_buf32);340 else341 sample = be16_to_cpu(st->scan.data.sample_buf16);342 343 sample >>= chan->scan_type.shift;344 345 if (chan->scan_type.sign == 's')346 *val = sign_extend32(sample, chan->scan_type.realbits - 1);347 348 return IIO_VAL_INT;349}350 351static int ad4000_read_raw(struct iio_dev *indio_dev,352 struct iio_chan_spec const *chan, int *val,353 int *val2, long info)354{355 struct ad4000_state *st = iio_priv(indio_dev);356 357 switch (info) {358 case IIO_CHAN_INFO_RAW:359 iio_device_claim_direct_scoped(return -EBUSY, indio_dev)360 return ad4000_single_conversion(indio_dev, chan, val);361 unreachable();362 case IIO_CHAN_INFO_SCALE:363 *val = st->scale_tbl[st->span_comp][0];364 *val2 = st->scale_tbl[st->span_comp][1];365 return IIO_VAL_INT_PLUS_NANO;366 case IIO_CHAN_INFO_OFFSET:367 *val = 0;368 if (st->span_comp)369 *val = mult_frac(st->vref_mv, 1, 10);370 371 return IIO_VAL_INT;372 default:373 return -EINVAL;374 }375}376 377static int ad4000_read_avail(struct iio_dev *indio_dev,378 struct iio_chan_spec const *chan,379 const int **vals, int *type, int *length,380 long info)381{382 struct ad4000_state *st = iio_priv(indio_dev);383 384 switch (info) {385 case IIO_CHAN_INFO_SCALE:386 *vals = (int *)st->scale_tbl;387 *length = AD4000_SCALE_OPTIONS * 2;388 *type = IIO_VAL_INT_PLUS_NANO;389 return IIO_AVAIL_LIST;390 default:391 return -EINVAL;392 }393}394 395static int ad4000_write_raw_get_fmt(struct iio_dev *indio_dev,396 struct iio_chan_spec const *chan, long mask)397{398 switch (mask) {399 case IIO_CHAN_INFO_SCALE:400 return IIO_VAL_INT_PLUS_NANO;401 default:402 return IIO_VAL_INT_PLUS_MICRO;403 }404}405 406static int ad4000_write_raw(struct iio_dev *indio_dev,407 struct iio_chan_spec const *chan, int val, int val2,408 long mask)409{410 struct ad4000_state *st = iio_priv(indio_dev);411 unsigned int reg_val;412 bool span_comp_en;413 int ret;414 415 switch (mask) {416 case IIO_CHAN_INFO_SCALE:417 iio_device_claim_direct_scoped(return -EBUSY, indio_dev) {418 guard(mutex)(&st->lock);419 420 ret = ad4000_read_reg(st, ®_val);421 if (ret < 0)422 return ret;423 424 span_comp_en = val2 == st->scale_tbl[1][1];425 reg_val &= ~AD4000_CFG_SPAN_COMP;426 reg_val |= FIELD_PREP(AD4000_CFG_SPAN_COMP, span_comp_en);427 428 ret = ad4000_write_reg(st, reg_val);429 if (ret < 0)430 return ret;431 432 st->span_comp = span_comp_en;433 return 0;434 }435 unreachable();436 default:437 return -EINVAL;438 }439}440 441static irqreturn_t ad4000_trigger_handler(int irq, void *p)442{443 struct iio_poll_func *pf = p;444 struct iio_dev *indio_dev = pf->indio_dev;445 struct ad4000_state *st = iio_priv(indio_dev);446 int ret;447 448 ret = ad4000_convert_and_acquire(st);449 if (ret < 0)450 goto err_out;451 452 iio_push_to_buffers_with_timestamp(indio_dev, &st->scan, pf->timestamp);453 454err_out:455 iio_trigger_notify_done(indio_dev->trig);456 return IRQ_HANDLED;457}458 459static const struct iio_info ad4000_reg_access_info = {460 .read_raw = &ad4000_read_raw,461 .read_avail = &ad4000_read_avail,462 .write_raw = &ad4000_write_raw,463 .write_raw_get_fmt = &ad4000_write_raw_get_fmt,464};465 466static const struct iio_info ad4000_info = {467 .read_raw = &ad4000_read_raw,468};469 470/*471 * This executes a data sample transfer for when the device connections are472 * in "3-wire" mode, selected when the adi,sdi-pin device tree property is473 * absent or set to "high". In this connection mode, the ADC SDI pin is474 * connected to MOSI or to VIO and ADC CNV pin is connected either to a SPI475 * controller CS or to a GPIO.476 * AD4000 series of devices initiate conversions on the rising edge of CNV pin.477 *478 * If the CNV pin is connected to an SPI controller CS line (which is by default479 * active low), the ADC readings would have a latency (delay) of one read.480 * Moreover, since we also do ADC sampling for filling the buffer on triggered481 * buffer mode, the timestamps of buffer readings would be disarranged.482 * To prevent the read latency and reduce the time discrepancy between the483 * sample read request and the time of actual sampling by the ADC, do a484 * preparatory transfer to pulse the CS/CNV line.485 */486static int ad4000_prepare_3wire_mode_message(struct ad4000_state *st,487 const struct iio_chan_spec *chan)488{489 unsigned int cnv_pulse_time = AD4000_TCONV_NS;490 struct spi_transfer *xfers = st->xfers;491 492 xfers[0].cs_change = 1;493 xfers[0].cs_change_delay.value = cnv_pulse_time;494 xfers[0].cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;495 496 xfers[1].rx_buf = &st->scan.data;497 xfers[1].len = BITS_TO_BYTES(chan->scan_type.storagebits);498 xfers[1].delay.value = AD4000_TQUIET2_NS;499 xfers[1].delay.unit = SPI_DELAY_UNIT_NSECS;500 501 spi_message_init_with_transfers(&st->msg, st->xfers, 2);502 503 return devm_spi_optimize_message(&st->spi->dev, st->spi, &st->msg);504}505 506/*507 * This executes a data sample transfer for when the device connections are508 * in "4-wire" mode, selected when the adi,sdi-pin device tree property is509 * set to "cs". In this connection mode, the controller CS pin is connected to510 * ADC SDI pin and a GPIO is connected to ADC CNV pin.511 * The GPIO connected to ADC CNV pin is set outside of the SPI transfer.512 */513static int ad4000_prepare_4wire_mode_message(struct ad4000_state *st,514 const struct iio_chan_spec *chan)515{516 unsigned int cnv_to_sdi_time = AD4000_TCONV_NS;517 struct spi_transfer *xfers = st->xfers;518 519 /*520 * Dummy transfer to cause enough delay between CNV going high and SDI521 * going low.522 */523 xfers[0].cs_off = 1;524 xfers[0].delay.value = cnv_to_sdi_time;525 xfers[0].delay.unit = SPI_DELAY_UNIT_NSECS;526 527 xfers[1].rx_buf = &st->scan.data;528 xfers[1].len = BITS_TO_BYTES(chan->scan_type.storagebits);529 530 spi_message_init_with_transfers(&st->msg, st->xfers, 2);531 532 return devm_spi_optimize_message(&st->spi->dev, st->spi, &st->msg);533}534 535static int ad4000_config(struct ad4000_state *st)536{537 unsigned int reg_val = AD4000_CONFIG_REG_DEFAULT;538 539 if (device_property_present(&st->spi->dev, "adi,high-z-input"))540 reg_val |= FIELD_PREP(AD4000_CFG_HIGHZ, 1);541 542 return ad4000_write_reg(st, reg_val);543}544 545static int ad4000_probe(struct spi_device *spi)546{547 const struct ad4000_chip_info *chip;548 struct device *dev = &spi->dev;549 struct iio_dev *indio_dev;550 struct ad4000_state *st;551 int gain_idx, ret;552 553 indio_dev = devm_iio_device_alloc(dev, sizeof(*st));554 if (!indio_dev)555 return -ENOMEM;556 557 chip = spi_get_device_match_data(spi);558 if (!chip)559 return -EINVAL;560 561 st = iio_priv(indio_dev);562 st->spi = spi;563 564 ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(ad4000_power_supplies),565 ad4000_power_supplies);566 if (ret)567 return dev_err_probe(dev, ret, "Failed to enable power supplies\n");568 569 ret = devm_regulator_get_enable_read_voltage(dev, "ref");570 if (ret < 0)571 return dev_err_probe(dev, ret,572 "Failed to get ref regulator reference\n");573 st->vref_mv = ret / 1000;574 575 st->cnv_gpio = devm_gpiod_get_optional(dev, "cnv", GPIOD_OUT_HIGH);576 if (IS_ERR(st->cnv_gpio))577 return dev_err_probe(dev, PTR_ERR(st->cnv_gpio),578 "Failed to get CNV GPIO");579 580 ret = device_property_match_property_string(dev, "adi,sdi-pin",581 ad4000_sdi_pin,582 ARRAY_SIZE(ad4000_sdi_pin));583 if (ret < 0 && ret != -EINVAL)584 return dev_err_probe(dev, ret,585 "getting adi,sdi-pin property failed\n");586 587 /* Default to usual SPI connections if pin properties are not present */588 st->sdi_pin = ret == -EINVAL ? AD4000_SDI_MOSI : ret;589 switch (st->sdi_pin) {590 case AD4000_SDI_MOSI:591 indio_dev->info = &ad4000_reg_access_info;592 indio_dev->channels = &chip->reg_access_chan_spec;593 594 /*595 * In "3-wire mode", the ADC SDI line must be kept high when596 * data is not being clocked out of the controller.597 * Request the SPI controller to make MOSI idle high.598 */599 spi->mode |= SPI_MOSI_IDLE_HIGH;600 ret = spi_setup(spi);601 if (ret < 0)602 return ret;603 604 ret = ad4000_prepare_3wire_mode_message(st, indio_dev->channels);605 if (ret)606 return ret;607 608 ret = ad4000_config(st);609 if (ret < 0)610 return dev_err_probe(dev, ret, "Failed to config device\n");611 612 break;613 case AD4000_SDI_VIO:614 indio_dev->info = &ad4000_info;615 indio_dev->channels = &chip->chan_spec;616 ret = ad4000_prepare_3wire_mode_message(st, indio_dev->channels);617 if (ret)618 return ret;619 620 break;621 case AD4000_SDI_CS:622 indio_dev->info = &ad4000_info;623 indio_dev->channels = &chip->chan_spec;624 ret = ad4000_prepare_4wire_mode_message(st, indio_dev->channels);625 if (ret)626 return ret;627 628 break;629 case AD4000_SDI_GND:630 return dev_err_probe(dev, -EPROTONOSUPPORT,631 "Unsupported connection mode\n");632 633 default:634 return dev_err_probe(dev, -EINVAL, "Unrecognized connection mode\n");635 }636 637 indio_dev->name = chip->dev_name;638 indio_dev->num_channels = 1;639 640 devm_mutex_init(dev, &st->lock);641 642 st->gain_milli = 1000;643 if (chip->has_hardware_gain) {644 ret = device_property_read_u16(dev, "adi,gain-milli",645 &st->gain_milli);646 if (!ret) {647 /* Match gain value from dt to one of supported gains */648 gain_idx = find_closest(st->gain_milli, ad4000_gains,649 ARRAY_SIZE(ad4000_gains));650 st->gain_milli = ad4000_gains[gain_idx];651 } else {652 return dev_err_probe(dev, ret,653 "Failed to read gain property\n");654 }655 }656 657 ad4000_fill_scale_tbl(st, indio_dev->channels);658 659 ret = devm_iio_triggered_buffer_setup(dev, indio_dev,660 &iio_pollfunc_store_time,661 &ad4000_trigger_handler, NULL);662 if (ret)663 return ret;664 665 return devm_iio_device_register(dev, indio_dev);666}667 668static const struct spi_device_id ad4000_id[] = {669 { "ad4000", (kernel_ulong_t)&ad4000_chip_info },670 { "ad4001", (kernel_ulong_t)&ad4001_chip_info },671 { "ad4002", (kernel_ulong_t)&ad4002_chip_info },672 { "ad4003", (kernel_ulong_t)&ad4003_chip_info },673 { "ad4004", (kernel_ulong_t)&ad4004_chip_info },674 { "ad4005", (kernel_ulong_t)&ad4005_chip_info },675 { "ad4006", (kernel_ulong_t)&ad4006_chip_info },676 { "ad4007", (kernel_ulong_t)&ad4007_chip_info },677 { "ad4008", (kernel_ulong_t)&ad4008_chip_info },678 { "ad4010", (kernel_ulong_t)&ad4010_chip_info },679 { "ad4011", (kernel_ulong_t)&ad4011_chip_info },680 { "ad4020", (kernel_ulong_t)&ad4020_chip_info },681 { "ad4021", (kernel_ulong_t)&ad4021_chip_info },682 { "ad4022", (kernel_ulong_t)&ad4022_chip_info },683 { "adaq4001", (kernel_ulong_t)&adaq4001_chip_info },684 { "adaq4003", (kernel_ulong_t)&adaq4003_chip_info },685 { }686};687MODULE_DEVICE_TABLE(spi, ad4000_id);688 689static const struct of_device_id ad4000_of_match[] = {690 { .compatible = "adi,ad4000", .data = &ad4000_chip_info },691 { .compatible = "adi,ad4001", .data = &ad4001_chip_info },692 { .compatible = "adi,ad4002", .data = &ad4002_chip_info },693 { .compatible = "adi,ad4003", .data = &ad4003_chip_info },694 { .compatible = "adi,ad4004", .data = &ad4004_chip_info },695 { .compatible = "adi,ad4005", .data = &ad4005_chip_info },696 { .compatible = "adi,ad4006", .data = &ad4006_chip_info },697 { .compatible = "adi,ad4007", .data = &ad4007_chip_info },698 { .compatible = "adi,ad4008", .data = &ad4008_chip_info },699 { .compatible = "adi,ad4010", .data = &ad4010_chip_info },700 { .compatible = "adi,ad4011", .data = &ad4011_chip_info },701 { .compatible = "adi,ad4020", .data = &ad4020_chip_info },702 { .compatible = "adi,ad4021", .data = &ad4021_chip_info },703 { .compatible = "adi,ad4022", .data = &ad4022_chip_info },704 { .compatible = "adi,adaq4001", .data = &adaq4001_chip_info },705 { .compatible = "adi,adaq4003", .data = &adaq4003_chip_info },706 { }707};708MODULE_DEVICE_TABLE(of, ad4000_of_match);709 710static struct spi_driver ad4000_driver = {711 .driver = {712 .name = "ad4000",713 .of_match_table = ad4000_of_match,714 },715 .probe = ad4000_probe,716 .id_table = ad4000_id,717};718module_spi_driver(ad4000_driver);719 720MODULE_AUTHOR("Marcelo Schmitt <marcelo.schmitt@analog.com>");721MODULE_DESCRIPTION("Analog Devices AD4000 ADC driver");722MODULE_LICENSE("GPL");723