^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2015 Prevas A/S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/iio/buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/iio/trigger_consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/iio/triggered_buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/iio/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define ADS8688_CMD_REG(x) (x << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define ADS8688_CMD_REG_NOOP 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define ADS8688_CMD_REG_RST 0x85
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define ADS8688_CMD_REG_MAN_CH(chan) (0xC0 | (4 * chan))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define ADS8688_CMD_DONT_CARE_BITS 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define ADS8688_PROG_REG(x) (x << 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define ADS8688_PROG_REG_RANGE_CH(chan) (0x05 + chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define ADS8688_PROG_WR_BIT BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define ADS8688_PROG_DONT_CARE_BITS 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define ADS8688_REG_PLUSMINUS25VREF 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define ADS8688_REG_PLUSMINUS125VREF 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define ADS8688_REG_PLUSMINUS0625VREF 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define ADS8688_REG_PLUS25VREF 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define ADS8688_REG_PLUS125VREF 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define ADS8688_VREF_MV 4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define ADS8688_REALBITS 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define ADS8688_MAX_CHANNELS 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * enum ads8688_range - ADS8688 reference voltage range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * @ADS8688_PLUSMINUS25VREF: Device is configured for input range ±2.5 * VREF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * @ADS8688_PLUSMINUS125VREF: Device is configured for input range ±1.25 * VREF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * @ADS8688_PLUSMINUS0625VREF: Device is configured for input range ±0.625 * VREF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * @ADS8688_PLUS25VREF: Device is configured for input range 0 - 2.5 * VREF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * @ADS8688_PLUS125VREF: Device is configured for input range 0 - 1.25 * VREF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) enum ads8688_range {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) ADS8688_PLUSMINUS25VREF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) ADS8688_PLUSMINUS125VREF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) ADS8688_PLUSMINUS0625VREF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) ADS8688_PLUS25VREF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) ADS8688_PLUS125VREF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct ads8688_chip_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) const struct iio_chan_spec *channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) unsigned int num_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct ads8688_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) const struct ads8688_chip_info *chip_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct spi_device *spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct regulator *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) unsigned int vref_mv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) enum ads8688_range range[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) __be32 d32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) u8 d8[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) } data[2] ____cacheline_aligned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) enum ads8688_id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) ID_ADS8684,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) ID_ADS8688,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct ads8688_ranges {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) enum ads8688_range range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) unsigned int scale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static const struct ads8688_ranges ads8688_range_def[5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) .range = ADS8688_PLUSMINUS25VREF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) .scale = 76295,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) .offset = -(1 << (ADS8688_REALBITS - 1)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) .reg = ADS8688_REG_PLUSMINUS25VREF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .range = ADS8688_PLUSMINUS125VREF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .scale = 38148,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .offset = -(1 << (ADS8688_REALBITS - 1)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .reg = ADS8688_REG_PLUSMINUS125VREF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .range = ADS8688_PLUSMINUS0625VREF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .scale = 19074,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .offset = -(1 << (ADS8688_REALBITS - 1)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) .reg = ADS8688_REG_PLUSMINUS0625VREF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) .range = ADS8688_PLUS25VREF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) .scale = 38148,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) .offset = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) .reg = ADS8688_REG_PLUS25VREF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) .range = ADS8688_PLUS125VREF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) .scale = 19074,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) .offset = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) .reg = ADS8688_REG_PLUS125VREF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static ssize_t ads8688_show_scales(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct ads8688_state *st = iio_priv(dev_to_iio_dev(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return sprintf(buf, "0.%09u 0.%09u 0.%09u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) ads8688_range_def[0].scale * st->vref_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) ads8688_range_def[1].scale * st->vref_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) ads8688_range_def[2].scale * st->vref_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static ssize_t ads8688_show_offsets(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return sprintf(buf, "%d %d\n", ads8688_range_def[0].offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) ads8688_range_def[3].offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static IIO_DEVICE_ATTR(in_voltage_scale_available, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ads8688_show_scales, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static IIO_DEVICE_ATTR(in_voltage_offset_available, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ads8688_show_offsets, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static struct attribute *ads8688_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) &iio_dev_attr_in_voltage_scale_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) &iio_dev_attr_in_voltage_offset_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static const struct attribute_group ads8688_attribute_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) .attrs = ads8688_attributes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define ADS8688_CHAN(index) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .type = IIO_VOLTAGE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) .indexed = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) .channel = index, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) | BIT(IIO_CHAN_INFO_SCALE) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) | BIT(IIO_CHAN_INFO_OFFSET), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) .scan_index = index, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) .scan_type = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) .sign = 'u', \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) .realbits = 16, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .storagebits = 16, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .endianness = IIO_BE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static const struct iio_chan_spec ads8684_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) ADS8688_CHAN(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) ADS8688_CHAN(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) ADS8688_CHAN(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) ADS8688_CHAN(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static const struct iio_chan_spec ads8688_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) ADS8688_CHAN(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) ADS8688_CHAN(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) ADS8688_CHAN(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ADS8688_CHAN(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) ADS8688_CHAN(4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) ADS8688_CHAN(5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) ADS8688_CHAN(6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) ADS8688_CHAN(7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static int ads8688_prog_write(struct iio_dev *indio_dev, unsigned int addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) unsigned int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct ads8688_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) tmp = ADS8688_PROG_REG(addr) | ADS8688_PROG_WR_BIT | val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) tmp <<= ADS8688_PROG_DONT_CARE_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) st->data[0].d32 = cpu_to_be32(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return spi_write(st->spi, &st->data[0].d8[1], 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static int ads8688_reset(struct iio_dev *indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct ads8688_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) tmp = ADS8688_CMD_REG(ADS8688_CMD_REG_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) tmp <<= ADS8688_CMD_DONT_CARE_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) st->data[0].d32 = cpu_to_be32(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return spi_write(st->spi, &st->data[0].d8[0], 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static int ads8688_read(struct iio_dev *indio_dev, unsigned int chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) struct ads8688_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct spi_transfer t[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) .tx_buf = &st->data[0].d8[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .len = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) .cs_change = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) .tx_buf = &st->data[1].d8[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) .rx_buf = &st->data[1].d8[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) .len = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) tmp = ADS8688_CMD_REG(ADS8688_CMD_REG_MAN_CH(chan));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) tmp <<= ADS8688_CMD_DONT_CARE_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) st->data[0].d32 = cpu_to_be32(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) tmp = ADS8688_CMD_REG(ADS8688_CMD_REG_NOOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) tmp <<= ADS8688_CMD_DONT_CARE_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) st->data[1].d32 = cpu_to_be32(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) ret = spi_sync_transfer(st->spi, t, ARRAY_SIZE(t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return be32_to_cpu(st->data[1].d32) & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static int ads8688_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) int *val, int *val2, long m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) int ret, offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) unsigned long scale_mv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct ads8688_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) mutex_lock(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) switch (m) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) ret = ads8688_read(indio_dev, chan->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) mutex_unlock(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) *val = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) case IIO_CHAN_INFO_SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) scale_mv = st->vref_mv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) scale_mv *= ads8688_range_def[st->range[chan->channel]].scale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) *val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) *val2 = scale_mv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) mutex_unlock(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return IIO_VAL_INT_PLUS_NANO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) case IIO_CHAN_INFO_OFFSET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) offset = ads8688_range_def[st->range[chan->channel]].offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) *val = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) mutex_unlock(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) mutex_unlock(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static int ads8688_write_reg_range(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) enum ads8688_range range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) tmp = ADS8688_PROG_REG_RANGE_CH(chan->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) ret = ads8688_prog_write(indio_dev, tmp, range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) static int ads8688_write_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) int val, int val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct ads8688_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) unsigned int scale = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) int ret = -EINVAL, i, offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) mutex_lock(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) case IIO_CHAN_INFO_SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /* If the offset is 0 the ±2.5 * VREF mode is not available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) offset = ads8688_range_def[st->range[chan->channel]].offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (offset == 0 && val2 == ads8688_range_def[0].scale * st->vref_mv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) mutex_unlock(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /* Lookup new mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) for (i = 0; i < ARRAY_SIZE(ads8688_range_def); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (val2 == ads8688_range_def[i].scale * st->vref_mv &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) offset == ads8688_range_def[i].offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) ret = ads8688_write_reg_range(indio_dev, chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) ads8688_range_def[i].reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) case IIO_CHAN_INFO_OFFSET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * There are only two available offsets:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * 0 and -(1 << (ADS8688_REALBITS - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (!(ads8688_range_def[0].offset == val ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) ads8688_range_def[3].offset == val)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) mutex_unlock(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * If the device are in ±2.5 * VREF mode, it's not allowed to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) * switch to a mode where the offset is 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (val == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) st->range[chan->channel] == ADS8688_PLUSMINUS25VREF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) mutex_unlock(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) scale = ads8688_range_def[st->range[chan->channel]].scale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) /* Lookup new mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) for (i = 0; i < ARRAY_SIZE(ads8688_range_def); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (val == ads8688_range_def[i].offset &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) scale == ads8688_range_def[i].scale) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) ret = ads8688_write_reg_range(indio_dev, chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ads8688_range_def[i].reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) st->range[chan->channel] = ads8688_range_def[i].range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) mutex_unlock(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) static int ads8688_write_raw_get_fmt(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) case IIO_CHAN_INFO_SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return IIO_VAL_INT_PLUS_NANO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) case IIO_CHAN_INFO_OFFSET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) static const struct iio_info ads8688_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) .read_raw = &ads8688_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) .write_raw = &ads8688_write_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) .write_raw_get_fmt = &ads8688_write_raw_get_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) .attrs = &ads8688_attribute_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static irqreturn_t ads8688_trigger_handler(int irq, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) struct iio_poll_func *pf = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct iio_dev *indio_dev = pf->indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /* Ensure naturally aligned timestamp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) u16 buffer[ADS8688_MAX_CHANNELS + sizeof(s64)/sizeof(u16)] __aligned(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) int i, j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) for (i = 0; i < indio_dev->masklength; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (!test_bit(i, indio_dev->active_scan_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) buffer[j] = ads8688_read(indio_dev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) iio_push_to_buffers_with_timestamp(indio_dev, buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) iio_get_time_ns(indio_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) iio_trigger_notify_done(indio_dev->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) static const struct ads8688_chip_info ads8688_chip_info_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) [ID_ADS8684] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) .channels = ads8684_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) .num_channels = ARRAY_SIZE(ads8684_channels),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) [ID_ADS8688] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) .channels = ads8688_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) .num_channels = ARRAY_SIZE(ads8688_channels),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) static int ads8688_probe(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) struct ads8688_state *st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (indio_dev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) st->reg = devm_regulator_get_optional(&spi->dev, "vref");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (!IS_ERR(st->reg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) ret = regulator_enable(st->reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) ret = regulator_get_voltage(st->reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) goto err_regulator_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) st->vref_mv = ret / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /* Use internal reference */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) st->vref_mv = ADS8688_VREF_MV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) st->chip_info = &ads8688_chip_info_tbl[spi_get_device_id(spi)->driver_data];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) spi->mode = SPI_MODE_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) spi_set_drvdata(spi, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) st->spi = spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) indio_dev->name = spi_get_device_id(spi)->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) indio_dev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) indio_dev->channels = st->chip_info->channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) indio_dev->num_channels = st->chip_info->num_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) indio_dev->info = &ads8688_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) ads8688_reset(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) mutex_init(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) ret = iio_triggered_buffer_setup(indio_dev, NULL, ads8688_trigger_handler, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) dev_err(&spi->dev, "iio triggered buffer setup failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) goto err_regulator_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) ret = iio_device_register(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) goto err_buffer_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) err_buffer_cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) iio_triggered_buffer_cleanup(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) err_regulator_disable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (!IS_ERR(st->reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) regulator_disable(st->reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static int ads8688_remove(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct iio_dev *indio_dev = spi_get_drvdata(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) struct ads8688_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) iio_device_unregister(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) iio_triggered_buffer_cleanup(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (!IS_ERR(st->reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) regulator_disable(st->reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) static const struct spi_device_id ads8688_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) {"ads8684", ID_ADS8684},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) {"ads8688", ID_ADS8688},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) MODULE_DEVICE_TABLE(spi, ads8688_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) static const struct of_device_id ads8688_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) { .compatible = "ti,ads8684" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) { .compatible = "ti,ads8688" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) MODULE_DEVICE_TABLE(of, ads8688_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static struct spi_driver ads8688_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) .name = "ads8688",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) .probe = ads8688_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) .remove = ads8688_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) .id_table = ads8688_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) module_spi_driver(ads8688_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) MODULE_AUTHOR("Sean Nyekjaer <sean@geanix.dk>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) MODULE_DESCRIPTION("Texas Instruments ADS8688 driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) MODULE_LICENSE("GPL v2");