^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) * Analog devices AD5380, AD5381, AD5382, AD5383, AD5390, AD5391, AD5392
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * multi-channel Digital to Analog Converters driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright 2011 Analog Devices Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/kernel.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/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/iio/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define AD5380_REG_DATA(x) (((x) << 2) | 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define AD5380_REG_OFFSET(x) (((x) << 2) | 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define AD5380_REG_GAIN(x) (((x) << 2) | 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define AD5380_REG_SF_PWR_DOWN (8 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define AD5380_REG_SF_PWR_UP (9 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define AD5380_REG_SF_CTRL (12 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define AD5380_CTRL_PWR_DOWN_MODE_OFFSET 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define AD5380_CTRL_INT_VREF_2V5 BIT(12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define AD5380_CTRL_INT_VREF_EN BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * struct ad5380_chip_info - chip specific information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * @channel_template: channel specification template
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * @num_channels: number of channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * @int_vref: internal vref in uV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct ad5380_chip_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct iio_chan_spec channel_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) unsigned int num_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) unsigned int int_vref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * struct ad5380_state - driver instance specific data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * @regmap: regmap instance used by the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * @chip_info: chip model specific constants, available modes etc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * @vref_reg: vref supply regulator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * @vref: actual reference voltage used in uA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * @pwr_down: whether the chip is currently in power down mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * @lock: lock to protect the data buffer during regmap ops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct ad5380_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) const struct ad5380_chip_info *chip_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct regulator *vref_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) int vref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) bool pwr_down;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) enum ad5380_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) ID_AD5380_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) ID_AD5380_5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) ID_AD5381_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) ID_AD5381_5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) ID_AD5382_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) ID_AD5382_5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) ID_AD5383_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) ID_AD5383_5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) ID_AD5390_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) ID_AD5390_5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) ID_AD5391_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) ID_AD5391_5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) ID_AD5392_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) ID_AD5392_5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static ssize_t ad5380_read_dac_powerdown(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) uintptr_t private, const struct iio_chan_spec *chan, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct ad5380_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return sprintf(buf, "%d\n", st->pwr_down);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static ssize_t ad5380_write_dac_powerdown(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct ad5380_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) bool pwr_down;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) ret = strtobool(buf, &pwr_down);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) mutex_lock(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (pwr_down)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) ret = regmap_write(st->regmap, AD5380_REG_SF_PWR_DOWN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) ret = regmap_write(st->regmap, AD5380_REG_SF_PWR_UP, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) st->pwr_down = pwr_down;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) mutex_unlock(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return ret ? ret : len;
^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) static const char * const ad5380_powerdown_modes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) "100kohm_to_gnd",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) "three_state",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static int ad5380_get_powerdown_mode(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) const struct iio_chan_spec *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct ad5380_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned int mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) ret = regmap_read(st->regmap, AD5380_REG_SF_CTRL, &mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) mode = (mode >> AD5380_CTRL_PWR_DOWN_MODE_OFFSET) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static int ad5380_set_powerdown_mode(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) const struct iio_chan_spec *chan, unsigned int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct ad5380_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) ret = regmap_update_bits(st->regmap, AD5380_REG_SF_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 1 << AD5380_CTRL_PWR_DOWN_MODE_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) mode << AD5380_CTRL_PWR_DOWN_MODE_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return ret;
^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) static const struct iio_enum ad5380_powerdown_mode_enum = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) .items = ad5380_powerdown_modes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .num_items = ARRAY_SIZE(ad5380_powerdown_modes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) .get = ad5380_get_powerdown_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) .set = ad5380_set_powerdown_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static unsigned int ad5380_info_to_reg(struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) long info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) switch (info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return AD5380_REG_DATA(chan->address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) case IIO_CHAN_INFO_CALIBBIAS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return AD5380_REG_OFFSET(chan->address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) case IIO_CHAN_INFO_CALIBSCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return AD5380_REG_GAIN(chan->address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return 0;
^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 int ad5380_write_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct iio_chan_spec const *chan, int val, int val2, long info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) const unsigned int max_val = (1 << chan->scan_type.realbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct ad5380_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) switch (info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) case IIO_CHAN_INFO_CALIBSCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (val >= max_val || val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return regmap_write(st->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ad5380_info_to_reg(chan, info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) val << chan->scan_type.shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) case IIO_CHAN_INFO_CALIBBIAS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) val += (1 << chan->scan_type.realbits) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (val >= max_val || val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return regmap_write(st->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) AD5380_REG_OFFSET(chan->address),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) val << chan->scan_type.shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static int ad5380_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct iio_chan_spec const *chan, int *val, int *val2, long info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct ad5380_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) switch (info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) case IIO_CHAN_INFO_CALIBSCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ret = regmap_read(st->regmap, ad5380_info_to_reg(chan, info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) *val >>= chan->scan_type.shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) case IIO_CHAN_INFO_CALIBBIAS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) ret = regmap_read(st->regmap, AD5380_REG_OFFSET(chan->address),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) *val >>= chan->scan_type.shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) *val -= (1 << chan->scan_type.realbits) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) case IIO_CHAN_INFO_SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) *val = 2 * st->vref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) *val2 = chan->scan_type.realbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return IIO_VAL_FRACTIONAL_LOG2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static const struct iio_info ad5380_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) .read_raw = ad5380_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) .write_raw = ad5380_write_raw,
^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 const struct iio_chan_spec_ext_info ad5380_ext_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) .name = "powerdown",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) .read = ad5380_read_dac_powerdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) .write = ad5380_write_dac_powerdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) .shared = IIO_SEPARATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) &ad5380_powerdown_mode_enum),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) IIO_ENUM_AVAILABLE("powerdown_mode", &ad5380_powerdown_mode_enum),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) #define AD5380_CHANNEL(_bits) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) .type = IIO_VOLTAGE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) .indexed = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) .output = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) BIT(IIO_CHAN_INFO_CALIBSCALE) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) BIT(IIO_CHAN_INFO_CALIBBIAS), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) .scan_type = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) .sign = 'u', \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) .realbits = (_bits), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) .storagebits = 16, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) .shift = 14 - (_bits), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) .ext_info = ad5380_ext_info, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static const struct ad5380_chip_info ad5380_chip_info_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) [ID_AD5380_3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) .channel_template = AD5380_CHANNEL(14),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) .num_channels = 40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) .int_vref = 1250,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) [ID_AD5380_5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) .channel_template = AD5380_CHANNEL(14),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) .num_channels = 40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) .int_vref = 2500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) [ID_AD5381_3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) .channel_template = AD5380_CHANNEL(12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) .num_channels = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) .int_vref = 1250,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) [ID_AD5381_5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) .channel_template = AD5380_CHANNEL(12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) .num_channels = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) .int_vref = 2500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) [ID_AD5382_3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) .channel_template = AD5380_CHANNEL(14),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) .num_channels = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) .int_vref = 1250,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) [ID_AD5382_5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) .channel_template = AD5380_CHANNEL(14),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) .num_channels = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) .int_vref = 2500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) [ID_AD5383_3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) .channel_template = AD5380_CHANNEL(12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) .num_channels = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) .int_vref = 1250,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) [ID_AD5383_5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) .channel_template = AD5380_CHANNEL(12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) .num_channels = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) .int_vref = 2500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) [ID_AD5390_3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) .channel_template = AD5380_CHANNEL(14),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) .num_channels = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) .int_vref = 1250,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) [ID_AD5390_5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) .channel_template = AD5380_CHANNEL(14),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) .num_channels = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) .int_vref = 2500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) [ID_AD5391_3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) .channel_template = AD5380_CHANNEL(12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) .num_channels = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) .int_vref = 1250,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) [ID_AD5391_5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) .channel_template = AD5380_CHANNEL(12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) .num_channels = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) .int_vref = 2500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) [ID_AD5392_3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) .channel_template = AD5380_CHANNEL(14),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) .num_channels = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) .int_vref = 1250,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) [ID_AD5392_5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) .channel_template = AD5380_CHANNEL(14),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) .num_channels = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) .int_vref = 2500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static int ad5380_alloc_channels(struct iio_dev *indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct ad5380_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct iio_chan_spec *channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) channels = kcalloc(st->chip_info->num_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) sizeof(struct iio_chan_spec), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (!channels)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) for (i = 0; i < st->chip_info->num_channels; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) channels[i] = st->chip_info->channel_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) channels[i].channel = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) channels[i].address = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) indio_dev->channels = channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) static int ad5380_probe(struct device *dev, struct regmap *regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) enum ad5380_type type, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct ad5380_state *st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) unsigned int ctrl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (indio_dev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) dev_err(dev, "Failed to allocate iio device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) dev_set_drvdata(dev, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) st->chip_info = &ad5380_chip_info_tbl[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) st->regmap = regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) indio_dev->name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) indio_dev->info = &ad5380_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) indio_dev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) indio_dev->num_channels = st->chip_info->num_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) mutex_init(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) ret = ad5380_alloc_channels(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) dev_err(dev, "Failed to allocate channel spec: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (st->chip_info->int_vref == 2500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) ctrl |= AD5380_CTRL_INT_VREF_2V5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) st->vref_reg = devm_regulator_get(dev, "vref");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (!IS_ERR(st->vref_reg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) ret = regulator_enable(st->vref_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) dev_err(dev, "Failed to enable vref regulators: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) goto error_free_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ret = regulator_get_voltage(st->vref_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) goto error_disable_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) st->vref = ret / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) st->vref = st->chip_info->int_vref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) ctrl |= AD5380_CTRL_INT_VREF_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) ret = regmap_write(st->regmap, AD5380_REG_SF_CTRL, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) dev_err(dev, "Failed to write to device: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) goto error_disable_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) ret = iio_device_register(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) dev_err(dev, "Failed to register iio device: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) goto error_disable_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) error_disable_reg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (!IS_ERR(st->vref_reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) regulator_disable(st->vref_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) error_free_reg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) kfree(indio_dev->channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) static int ad5380_remove(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) struct iio_dev *indio_dev = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) struct ad5380_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) iio_device_unregister(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) kfree(indio_dev->channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (!IS_ERR(st->vref_reg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) regulator_disable(st->vref_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) static bool ad5380_reg_false(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return false;
^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) static const struct regmap_config ad5380_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) .reg_bits = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) .val_bits = 14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) .max_register = AD5380_REG_DATA(40),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) .cache_type = REGCACHE_RBTREE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) .volatile_reg = ad5380_reg_false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) .readable_reg = ad5380_reg_false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) #if IS_ENABLED(CONFIG_SPI_MASTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) static int ad5380_spi_probe(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) const struct spi_device_id *id = spi_get_device_id(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) regmap = devm_regmap_init_spi(spi, &ad5380_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (IS_ERR(regmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return PTR_ERR(regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return ad5380_probe(&spi->dev, regmap, id->driver_data, id->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) static int ad5380_spi_remove(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return ad5380_remove(&spi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) static const struct spi_device_id ad5380_spi_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) { "ad5380-3", ID_AD5380_3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) { "ad5380-5", ID_AD5380_5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) { "ad5381-3", ID_AD5381_3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) { "ad5381-5", ID_AD5381_5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) { "ad5382-3", ID_AD5382_3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) { "ad5382-5", ID_AD5382_5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) { "ad5383-3", ID_AD5383_3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) { "ad5383-5", ID_AD5383_5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) { "ad5384-3", ID_AD5380_3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) { "ad5384-5", ID_AD5380_5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) { "ad5390-3", ID_AD5390_3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) { "ad5390-5", ID_AD5390_5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) { "ad5391-3", ID_AD5391_3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) { "ad5391-5", ID_AD5391_5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) { "ad5392-3", ID_AD5392_3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) { "ad5392-5", ID_AD5392_5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) MODULE_DEVICE_TABLE(spi, ad5380_spi_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) static struct spi_driver ad5380_spi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) .name = "ad5380",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) .probe = ad5380_spi_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) .remove = ad5380_spi_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) .id_table = ad5380_spi_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) static inline int ad5380_spi_register_driver(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) return spi_register_driver(&ad5380_spi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) static inline void ad5380_spi_unregister_driver(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) spi_unregister_driver(&ad5380_spi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) static inline int ad5380_spi_register_driver(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) static inline void ad5380_spi_unregister_driver(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) #if IS_ENABLED(CONFIG_I2C)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) static int ad5380_i2c_probe(struct i2c_client *i2c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) regmap = devm_regmap_init_i2c(i2c, &ad5380_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (IS_ERR(regmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return PTR_ERR(regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return ad5380_probe(&i2c->dev, regmap, id->driver_data, id->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) static int ad5380_i2c_remove(struct i2c_client *i2c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return ad5380_remove(&i2c->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) static const struct i2c_device_id ad5380_i2c_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) { "ad5380-3", ID_AD5380_3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) { "ad5380-5", ID_AD5380_5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) { "ad5381-3", ID_AD5381_3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) { "ad5381-5", ID_AD5381_5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) { "ad5382-3", ID_AD5382_3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) { "ad5382-5", ID_AD5382_5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) { "ad5383-3", ID_AD5383_3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) { "ad5383-5", ID_AD5383_5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) { "ad5384-3", ID_AD5380_3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) { "ad5384-5", ID_AD5380_5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) { "ad5390-3", ID_AD5390_3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) { "ad5390-5", ID_AD5390_5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) { "ad5391-3", ID_AD5391_3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) { "ad5391-5", ID_AD5391_5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) { "ad5392-3", ID_AD5392_3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) { "ad5392-5", ID_AD5392_5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) MODULE_DEVICE_TABLE(i2c, ad5380_i2c_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) static struct i2c_driver ad5380_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) .name = "ad5380",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) .probe = ad5380_i2c_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) .remove = ad5380_i2c_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) .id_table = ad5380_i2c_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) static inline int ad5380_i2c_register_driver(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) return i2c_add_driver(&ad5380_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) static inline void ad5380_i2c_unregister_driver(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) i2c_del_driver(&ad5380_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) static inline int ad5380_i2c_register_driver(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) static inline void ad5380_i2c_unregister_driver(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) static int __init ad5380_spi_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) ret = ad5380_spi_register_driver();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) ret = ad5380_i2c_register_driver();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) ad5380_spi_unregister_driver();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) module_init(ad5380_spi_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) static void __exit ad5380_spi_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) ad5380_i2c_unregister_driver();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) ad5380_spi_unregister_driver();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) module_exit(ad5380_spi_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) MODULE_DESCRIPTION("Analog Devices AD5380/81/82/83/84/90/91/92 DAC");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) MODULE_LICENSE("GPL v2");