Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * AD5770R Digital to analog converters driver
0004  *
0005  * Copyright 2018 Analog Devices Inc.
0006  */
0007 
0008 #include <linux/bits.h>
0009 #include <linux/delay.h>
0010 #include <linux/device.h>
0011 #include <linux/gpio/consumer.h>
0012 #include <linux/iio/iio.h>
0013 #include <linux/iio/sysfs.h>
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/property.h>
0017 #include <linux/regmap.h>
0018 #include <linux/regulator/consumer.h>
0019 #include <linux/spi/spi.h>
0020 
0021 #define ADI_SPI_IF_CONFIG_A     0x00
0022 #define ADI_SPI_IF_CONFIG_B     0x01
0023 #define ADI_SPI_IF_DEVICE_CONFIG    0x02
0024 #define ADI_SPI_IF_CHIP_TYPE        0x03
0025 #define ADI_SPI_IF_PRODUCT_ID_L     0x04
0026 #define ADI_SPI_IF_PRODUCT_ID_H     0x05
0027 #define ADI_SPI_IF_CHIP_GRADE       0x06
0028 #define ADI_SPI_IF_SCRACTH_PAD      0x0A
0029 #define ADI_SPI_IF_SPI_REVISION     0x0B
0030 #define ADI_SPI_IF_SPI_VENDOR_L     0x0C
0031 #define ADI_SPI_IF_SPI_VENDOR_H     0x0D
0032 #define ADI_SPI_IF_SPI_STREAM_MODE  0x0E
0033 #define ADI_SPI_IF_CONFIG_C     0x10
0034 #define ADI_SPI_IF_STATUS_A     0x11
0035 
0036 /* ADI_SPI_IF_CONFIG_A */
0037 #define ADI_SPI_IF_SW_RESET_MSK     (BIT(0) | BIT(7))
0038 #define ADI_SPI_IF_SW_RESET_SEL(x)  ((x) & ADI_SPI_IF_SW_RESET_MSK)
0039 #define ADI_SPI_IF_ADDR_ASC_MSK     (BIT(2) | BIT(5))
0040 #define ADI_SPI_IF_ADDR_ASC_SEL(x)  (((x) << 2) & ADI_SPI_IF_ADDR_ASC_MSK)
0041 
0042 /* ADI_SPI_IF_CONFIG_B */
0043 #define ADI_SPI_IF_SINGLE_INS_MSK   BIT(7)
0044 #define ADI_SPI_IF_SINGLE_INS_SEL(x)    FIELD_PREP(ADI_SPI_IF_SINGLE_INS_MSK, x)
0045 #define ADI_SPI_IF_SHORT_INS_MSK    BIT(7)
0046 #define ADI_SPI_IF_SHORT_INS_SEL(x) FIELD_PREP(ADI_SPI_IF_SINGLE_INS_MSK, x)
0047 
0048 /* ADI_SPI_IF_CONFIG_C */
0049 #define ADI_SPI_IF_STRICT_REG_MSK   BIT(5)
0050 #define ADI_SPI_IF_STRICT_REG_GET(x)    FIELD_GET(ADI_SPI_IF_STRICT_REG_MSK, x)
0051 
0052 /* AD5770R configuration registers */
0053 #define AD5770R_CHANNEL_CONFIG      0x14
0054 #define AD5770R_OUTPUT_RANGE(ch)    (0x15 + (ch))
0055 #define AD5770R_FILTER_RESISTOR(ch) (0x1D + (ch))
0056 #define AD5770R_REFERENCE       0x1B
0057 #define AD5770R_DAC_LSB(ch)     (0x26 + 2 * (ch))
0058 #define AD5770R_DAC_MSB(ch)     (0x27 + 2 * (ch))
0059 #define AD5770R_CH_SELECT       0x34
0060 #define AD5770R_CH_ENABLE       0x44
0061 
0062 /* AD5770R_CHANNEL_CONFIG */
0063 #define AD5770R_CFG_CH0_SINK_EN(x)      (((x) & 0x1) << 7)
0064 #define AD5770R_CFG_SHUTDOWN_B(x, ch)       (((x) & 0x1) << (ch))
0065 
0066 /* AD5770R_OUTPUT_RANGE */
0067 #define AD5770R_RANGE_OUTPUT_SCALING(x)     (((x) & GENMASK(5, 0)) << 2)
0068 #define AD5770R_RANGE_MODE(x)           ((x) & GENMASK(1, 0))
0069 
0070 /* AD5770R_REFERENCE */
0071 #define AD5770R_REF_RESISTOR_SEL(x)     (((x) & 0x1) << 2)
0072 #define AD5770R_REF_SEL(x)          ((x) & GENMASK(1, 0))
0073 
0074 /* AD5770R_CH_ENABLE */
0075 #define AD5770R_CH_SET(x, ch)       (((x) & 0x1) << (ch))
0076 
0077 #define AD5770R_MAX_CHANNELS    6
0078 #define AD5770R_MAX_CH_MODES    14
0079 #define AD5770R_LOW_VREF_mV 1250
0080 #define AD5770R_HIGH_VREF_mV    2500
0081 
0082 enum ad5770r_ch0_modes {
0083     AD5770R_CH0_0_300 = 0,
0084     AD5770R_CH0_NEG_60_0,
0085     AD5770R_CH0_NEG_60_300
0086 };
0087 
0088 enum ad5770r_ch1_modes {
0089     AD5770R_CH1_0_140_LOW_HEAD = 1,
0090     AD5770R_CH1_0_140_LOW_NOISE,
0091     AD5770R_CH1_0_250
0092 };
0093 
0094 enum ad5770r_ch2_5_modes {
0095     AD5770R_CH_LOW_RANGE = 0,
0096     AD5770R_CH_HIGH_RANGE
0097 };
0098 
0099 enum ad5770r_ref_v {
0100     AD5770R_EXT_2_5_V = 0,
0101     AD5770R_INT_1_25_V_OUT_ON,
0102     AD5770R_EXT_1_25_V,
0103     AD5770R_INT_1_25_V_OUT_OFF
0104 };
0105 
0106 enum ad5770r_output_filter_resistor {
0107     AD5770R_FILTER_60_OHM = 0x0,
0108     AD5770R_FILTER_5_6_KOHM = 0x5,
0109     AD5770R_FILTER_11_2_KOHM,
0110     AD5770R_FILTER_22_2_KOHM,
0111     AD5770R_FILTER_44_4_KOHM,
0112     AD5770R_FILTER_104_KOHM,
0113 };
0114 
0115 struct ad5770r_out_range {
0116     u8  out_scale;
0117     u8  out_range_mode;
0118 };
0119 
0120 /**
0121  * struct ad5770r_state - driver instance specific data
0122  * @spi:        spi_device
0123  * @regmap:     regmap
0124  * @vref_reg:       fixed regulator for reference configuration
0125  * @gpio_reset:     gpio descriptor
0126  * @output_mode:    array contains channels output ranges
0127  * @vref:       reference value
0128  * @ch_pwr_down:    powerdown flags
0129  * @internal_ref:   internal reference flag
0130  * @external_res:   external 2.5k resistor flag
0131  * @transf_buf:     cache aligned buffer for spi read/write
0132  */
0133 struct ad5770r_state {
0134     struct spi_device       *spi;
0135     struct regmap           *regmap;
0136     struct regulator        *vref_reg;
0137     struct gpio_desc        *gpio_reset;
0138     struct ad5770r_out_range    output_mode[AD5770R_MAX_CHANNELS];
0139     int             vref;
0140     bool                ch_pwr_down[AD5770R_MAX_CHANNELS];
0141     bool                internal_ref;
0142     bool                external_res;
0143     u8              transf_buf[2] __aligned(IIO_DMA_MINALIGN);
0144 };
0145 
0146 static const struct regmap_config ad5770r_spi_regmap_config = {
0147     .reg_bits = 8,
0148     .val_bits = 8,
0149     .read_flag_mask = BIT(7),
0150 };
0151 
0152 struct ad5770r_output_modes {
0153     unsigned int ch;
0154     u8 mode;
0155     int min;
0156     int max;
0157 };
0158 
0159 static struct ad5770r_output_modes ad5770r_rng_tbl[] = {
0160     { 0, AD5770R_CH0_0_300, 0, 300 },
0161     { 0, AD5770R_CH0_NEG_60_0, -60, 0 },
0162     { 0, AD5770R_CH0_NEG_60_300, -60, 300 },
0163     { 1, AD5770R_CH1_0_140_LOW_HEAD, 0, 140 },
0164     { 1, AD5770R_CH1_0_140_LOW_NOISE, 0, 140 },
0165     { 1, AD5770R_CH1_0_250, 0, 250 },
0166     { 2, AD5770R_CH_LOW_RANGE, 0, 55 },
0167     { 2, AD5770R_CH_HIGH_RANGE, 0, 150 },
0168     { 3, AD5770R_CH_LOW_RANGE, 0, 45 },
0169     { 3, AD5770R_CH_HIGH_RANGE, 0, 100 },
0170     { 4, AD5770R_CH_LOW_RANGE, 0, 45 },
0171     { 4, AD5770R_CH_HIGH_RANGE, 0, 100 },
0172     { 5, AD5770R_CH_LOW_RANGE, 0, 45 },
0173     { 5, AD5770R_CH_HIGH_RANGE, 0, 100 },
0174 };
0175 
0176 static const unsigned int ad5770r_filter_freqs[] = {
0177     153, 357, 715, 1400, 2800, 262000,
0178 };
0179 
0180 static const unsigned int ad5770r_filter_reg_vals[] = {
0181     AD5770R_FILTER_104_KOHM,
0182     AD5770R_FILTER_44_4_KOHM,
0183     AD5770R_FILTER_22_2_KOHM,
0184     AD5770R_FILTER_11_2_KOHM,
0185     AD5770R_FILTER_5_6_KOHM,
0186     AD5770R_FILTER_60_OHM
0187 };
0188 
0189 static int ad5770r_set_output_mode(struct ad5770r_state *st,
0190                    const struct ad5770r_out_range *out_mode,
0191                    int channel)
0192 {
0193     unsigned int regval;
0194 
0195     regval = AD5770R_RANGE_OUTPUT_SCALING(out_mode->out_scale) |
0196          AD5770R_RANGE_MODE(out_mode->out_range_mode);
0197 
0198     return regmap_write(st->regmap,
0199                 AD5770R_OUTPUT_RANGE(channel), regval);
0200 }
0201 
0202 static int ad5770r_set_reference(struct ad5770r_state *st)
0203 {
0204     unsigned int regval;
0205 
0206     regval = AD5770R_REF_RESISTOR_SEL(st->external_res);
0207 
0208     if (st->internal_ref) {
0209         regval |= AD5770R_REF_SEL(AD5770R_INT_1_25_V_OUT_OFF);
0210     } else {
0211         switch (st->vref) {
0212         case AD5770R_LOW_VREF_mV:
0213             regval |= AD5770R_REF_SEL(AD5770R_EXT_1_25_V);
0214             break;
0215         case AD5770R_HIGH_VREF_mV:
0216             regval |= AD5770R_REF_SEL(AD5770R_EXT_2_5_V);
0217             break;
0218         default:
0219             regval = AD5770R_REF_SEL(AD5770R_INT_1_25_V_OUT_OFF);
0220             break;
0221         }
0222     }
0223 
0224     return regmap_write(st->regmap, AD5770R_REFERENCE, regval);
0225 }
0226 
0227 static int ad5770r_soft_reset(struct ad5770r_state *st)
0228 {
0229     return regmap_write(st->regmap, ADI_SPI_IF_CONFIG_A,
0230                 ADI_SPI_IF_SW_RESET_SEL(1));
0231 }
0232 
0233 static int ad5770r_reset(struct ad5770r_state *st)
0234 {
0235     /* Perform software reset if no GPIO provided */
0236     if (!st->gpio_reset)
0237         return ad5770r_soft_reset(st);
0238 
0239     gpiod_set_value_cansleep(st->gpio_reset, 0);
0240     usleep_range(10, 20);
0241     gpiod_set_value_cansleep(st->gpio_reset, 1);
0242 
0243     /* data must not be written during reset timeframe */
0244     usleep_range(100, 200);
0245 
0246     return 0;
0247 }
0248 
0249 static int ad5770r_get_range(struct ad5770r_state *st,
0250                  int ch, int *min, int *max)
0251 {
0252     int i;
0253     u8 tbl_ch, tbl_mode, out_range;
0254 
0255     out_range = st->output_mode[ch].out_range_mode;
0256 
0257     for (i = 0; i < AD5770R_MAX_CH_MODES; i++) {
0258         tbl_ch = ad5770r_rng_tbl[i].ch;
0259         tbl_mode = ad5770r_rng_tbl[i].mode;
0260         if (tbl_ch == ch && tbl_mode == out_range) {
0261             *min = ad5770r_rng_tbl[i].min;
0262             *max = ad5770r_rng_tbl[i].max;
0263             return 0;
0264         }
0265     }
0266 
0267     return -EINVAL;
0268 }
0269 
0270 static int ad5770r_get_filter_freq(struct iio_dev *indio_dev,
0271                    const struct iio_chan_spec *chan, int *freq)
0272 {
0273     struct ad5770r_state *st = iio_priv(indio_dev);
0274     int ret;
0275     unsigned int regval, i;
0276 
0277     ret = regmap_read(st->regmap,
0278               AD5770R_FILTER_RESISTOR(chan->channel), &regval);
0279     if (ret < 0)
0280         return ret;
0281 
0282     for (i = 0; i < ARRAY_SIZE(ad5770r_filter_reg_vals); i++)
0283         if (regval == ad5770r_filter_reg_vals[i])
0284             break;
0285     if (i == ARRAY_SIZE(ad5770r_filter_reg_vals))
0286         return -EINVAL;
0287 
0288     *freq = ad5770r_filter_freqs[i];
0289 
0290     return IIO_VAL_INT;
0291 }
0292 
0293 static int ad5770r_set_filter_freq(struct iio_dev *indio_dev,
0294                    const struct iio_chan_spec *chan,
0295                    unsigned int freq)
0296 {
0297     struct ad5770r_state *st = iio_priv(indio_dev);
0298     unsigned int regval, i;
0299 
0300     for (i = 0; i < ARRAY_SIZE(ad5770r_filter_freqs); i++)
0301         if (ad5770r_filter_freqs[i] >= freq)
0302             break;
0303     if (i == ARRAY_SIZE(ad5770r_filter_freqs))
0304         return -EINVAL;
0305 
0306     regval = ad5770r_filter_reg_vals[i];
0307 
0308     return regmap_write(st->regmap, AD5770R_FILTER_RESISTOR(chan->channel),
0309                 regval);
0310 }
0311 
0312 static int ad5770r_read_raw(struct iio_dev *indio_dev,
0313                 struct iio_chan_spec const *chan,
0314                 int *val, int *val2, long info)
0315 {
0316     struct ad5770r_state *st = iio_priv(indio_dev);
0317     int max, min, ret;
0318     u16 buf16;
0319 
0320     switch (info) {
0321     case IIO_CHAN_INFO_RAW:
0322         ret = regmap_bulk_read(st->regmap,
0323                        chan->address,
0324                        st->transf_buf, 2);
0325         if (ret)
0326             return 0;
0327 
0328         buf16 = st->transf_buf[0] + (st->transf_buf[1] << 8);
0329         *val = buf16 >> 2;
0330         return IIO_VAL_INT;
0331     case IIO_CHAN_INFO_SCALE:
0332         ret = ad5770r_get_range(st, chan->channel, &min, &max);
0333         if (ret < 0)
0334             return ret;
0335         *val = max - min;
0336         /* There is no sign bit. (negative current is mapped from 0)
0337          * (sourced/sinked) current = raw * scale + offset
0338          * where offset in case of CH0 can be negative.
0339          */
0340         *val2 = 14;
0341         return IIO_VAL_FRACTIONAL_LOG2;
0342     case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
0343         return ad5770r_get_filter_freq(indio_dev, chan, val);
0344     case IIO_CHAN_INFO_OFFSET:
0345         ret = ad5770r_get_range(st, chan->channel, &min, &max);
0346         if (ret < 0)
0347             return ret;
0348         *val = min;
0349         return IIO_VAL_INT;
0350     default:
0351         return -EINVAL;
0352     }
0353 }
0354 
0355 static int ad5770r_write_raw(struct iio_dev *indio_dev,
0356                  struct iio_chan_spec const *chan,
0357                  int val, int val2, long info)
0358 {
0359     struct ad5770r_state *st = iio_priv(indio_dev);
0360 
0361     switch (info) {
0362     case IIO_CHAN_INFO_RAW:
0363         st->transf_buf[0] = ((u16)val >> 6);
0364         st->transf_buf[1] = (val & GENMASK(5, 0)) << 2;
0365         return regmap_bulk_write(st->regmap, chan->address,
0366                      st->transf_buf, 2);
0367     case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
0368         return ad5770r_set_filter_freq(indio_dev, chan, val);
0369     default:
0370         return -EINVAL;
0371     }
0372 }
0373 
0374 static int ad5770r_read_freq_avail(struct iio_dev *indio_dev,
0375                    struct iio_chan_spec const *chan,
0376                    const int **vals, int *type, int *length,
0377                    long mask)
0378 {
0379     switch (mask) {
0380     case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
0381         *type = IIO_VAL_INT;
0382         *vals = ad5770r_filter_freqs;
0383         *length = ARRAY_SIZE(ad5770r_filter_freqs);
0384         return IIO_AVAIL_LIST;
0385     }
0386 
0387     return -EINVAL;
0388 }
0389 
0390 static int ad5770r_reg_access(struct iio_dev *indio_dev,
0391                   unsigned int reg,
0392                   unsigned int writeval,
0393                   unsigned int *readval)
0394 {
0395     struct ad5770r_state *st = iio_priv(indio_dev);
0396 
0397     if (readval)
0398         return regmap_read(st->regmap, reg, readval);
0399     else
0400         return regmap_write(st->regmap, reg, writeval);
0401 }
0402 
0403 static const struct iio_info ad5770r_info = {
0404     .read_raw = ad5770r_read_raw,
0405     .write_raw = ad5770r_write_raw,
0406     .read_avail = ad5770r_read_freq_avail,
0407     .debugfs_reg_access = &ad5770r_reg_access,
0408 };
0409 
0410 static int ad5770r_store_output_range(struct ad5770r_state *st,
0411                       int min, int max, int index)
0412 {
0413     int i;
0414 
0415     for (i = 0; i < AD5770R_MAX_CH_MODES; i++) {
0416         if (ad5770r_rng_tbl[i].ch != index)
0417             continue;
0418         if (ad5770r_rng_tbl[i].min != min ||
0419             ad5770r_rng_tbl[i].max != max)
0420             continue;
0421         st->output_mode[index].out_range_mode = ad5770r_rng_tbl[i].mode;
0422 
0423         return 0;
0424     }
0425 
0426     return -EINVAL;
0427 }
0428 
0429 static ssize_t ad5770r_read_dac_powerdown(struct iio_dev *indio_dev,
0430                       uintptr_t private,
0431                       const struct iio_chan_spec *chan,
0432                       char *buf)
0433 {
0434     struct ad5770r_state *st = iio_priv(indio_dev);
0435 
0436     return sysfs_emit(buf, "%d\n", st->ch_pwr_down[chan->channel]);
0437 }
0438 
0439 static ssize_t ad5770r_write_dac_powerdown(struct iio_dev *indio_dev,
0440                        uintptr_t private,
0441                        const struct iio_chan_spec *chan,
0442                        const char *buf, size_t len)
0443 {
0444     struct ad5770r_state *st = iio_priv(indio_dev);
0445     unsigned int regval;
0446     unsigned int mask;
0447     bool readin;
0448     int ret;
0449 
0450     ret = kstrtobool(buf, &readin);
0451     if (ret)
0452         return ret;
0453 
0454     readin = !readin;
0455 
0456     regval = AD5770R_CFG_SHUTDOWN_B(readin, chan->channel);
0457     if (chan->channel == 0 &&
0458         st->output_mode[0].out_range_mode > AD5770R_CH0_0_300) {
0459         regval |= AD5770R_CFG_CH0_SINK_EN(readin);
0460         mask = BIT(chan->channel) + BIT(7);
0461     } else {
0462         mask = BIT(chan->channel);
0463     }
0464     ret = regmap_update_bits(st->regmap, AD5770R_CHANNEL_CONFIG, mask,
0465                  regval);
0466     if (ret)
0467         return ret;
0468 
0469     regval = AD5770R_CH_SET(readin, chan->channel);
0470     ret = regmap_update_bits(st->regmap, AD5770R_CH_ENABLE,
0471                  BIT(chan->channel), regval);
0472     if (ret)
0473         return ret;
0474 
0475     st->ch_pwr_down[chan->channel] = !readin;
0476 
0477     return len;
0478 }
0479 
0480 static const struct iio_chan_spec_ext_info ad5770r_ext_info[] = {
0481     {
0482         .name = "powerdown",
0483         .read = ad5770r_read_dac_powerdown,
0484         .write = ad5770r_write_dac_powerdown,
0485         .shared = IIO_SEPARATE,
0486     },
0487     { }
0488 };
0489 
0490 #define AD5770R_IDAC_CHANNEL(index, reg) {              \
0491     .type = IIO_CURRENT,                        \
0492     .address = reg,                         \
0493     .indexed = 1,                           \
0494     .channel = index,                       \
0495     .output = 1,                            \
0496     .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |          \
0497         BIT(IIO_CHAN_INFO_SCALE) |              \
0498         BIT(IIO_CHAN_INFO_OFFSET) |             \
0499         BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),   \
0500     .info_mask_shared_by_type_available =               \
0501         BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),   \
0502     .ext_info = ad5770r_ext_info,                   \
0503 }
0504 
0505 static const struct iio_chan_spec ad5770r_channels[] = {
0506     AD5770R_IDAC_CHANNEL(0, AD5770R_DAC_MSB(0)),
0507     AD5770R_IDAC_CHANNEL(1, AD5770R_DAC_MSB(1)),
0508     AD5770R_IDAC_CHANNEL(2, AD5770R_DAC_MSB(2)),
0509     AD5770R_IDAC_CHANNEL(3, AD5770R_DAC_MSB(3)),
0510     AD5770R_IDAC_CHANNEL(4, AD5770R_DAC_MSB(4)),
0511     AD5770R_IDAC_CHANNEL(5, AD5770R_DAC_MSB(5)),
0512 };
0513 
0514 static int ad5770r_channel_config(struct ad5770r_state *st)
0515 {
0516     int ret, tmp[2], min, max;
0517     unsigned int num;
0518     struct fwnode_handle *child;
0519 
0520     num = device_get_child_node_count(&st->spi->dev);
0521     if (num != AD5770R_MAX_CHANNELS)
0522         return -EINVAL;
0523 
0524     device_for_each_child_node(&st->spi->dev, child) {
0525         ret = fwnode_property_read_u32(child, "reg", &num);
0526         if (ret)
0527             goto err_child_out;
0528         if (num >= AD5770R_MAX_CHANNELS) {
0529             ret = -EINVAL;
0530             goto err_child_out;
0531         }
0532 
0533         ret = fwnode_property_read_u32_array(child,
0534                              "adi,range-microamp",
0535                              tmp, 2);
0536         if (ret)
0537             goto err_child_out;
0538 
0539         min = tmp[0] / 1000;
0540         max = tmp[1] / 1000;
0541         ret = ad5770r_store_output_range(st, min, max, num);
0542         if (ret)
0543             goto err_child_out;
0544     }
0545 
0546     return 0;
0547 
0548 err_child_out:
0549     fwnode_handle_put(child);
0550     return ret;
0551 }
0552 
0553 static int ad5770r_init(struct ad5770r_state *st)
0554 {
0555     int ret, i;
0556 
0557     st->gpio_reset = devm_gpiod_get_optional(&st->spi->dev, "reset",
0558                          GPIOD_OUT_HIGH);
0559     if (IS_ERR(st->gpio_reset))
0560         return PTR_ERR(st->gpio_reset);
0561 
0562     /* Perform a reset */
0563     ret = ad5770r_reset(st);
0564     if (ret)
0565         return ret;
0566 
0567     /* Set output range */
0568     ret = ad5770r_channel_config(st);
0569     if (ret)
0570         return ret;
0571 
0572     for (i = 0; i < AD5770R_MAX_CHANNELS; i++) {
0573         ret = ad5770r_set_output_mode(st,  &st->output_mode[i], i);
0574         if (ret)
0575             return ret;
0576     }
0577 
0578     st->external_res = fwnode_property_read_bool(st->spi->dev.fwnode,
0579                              "adi,external-resistor");
0580 
0581     ret = ad5770r_set_reference(st);
0582     if (ret)
0583         return ret;
0584 
0585     /* Set outputs off */
0586     ret = regmap_write(st->regmap, AD5770R_CHANNEL_CONFIG, 0x00);
0587     if (ret)
0588         return ret;
0589 
0590     ret = regmap_write(st->regmap, AD5770R_CH_ENABLE, 0x00);
0591     if (ret)
0592         return ret;
0593 
0594     for (i = 0; i < AD5770R_MAX_CHANNELS; i++)
0595         st->ch_pwr_down[i] = true;
0596 
0597     return ret;
0598 }
0599 
0600 static void ad5770r_disable_regulator(void *data)
0601 {
0602     struct ad5770r_state *st = data;
0603 
0604     regulator_disable(st->vref_reg);
0605 }
0606 
0607 static int ad5770r_probe(struct spi_device *spi)
0608 {
0609     struct ad5770r_state *st;
0610     struct iio_dev *indio_dev;
0611     struct regmap *regmap;
0612     int ret;
0613 
0614     indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
0615     if (!indio_dev)
0616         return -ENOMEM;
0617 
0618     st = iio_priv(indio_dev);
0619     spi_set_drvdata(spi, indio_dev);
0620 
0621     st->spi = spi;
0622 
0623     regmap = devm_regmap_init_spi(spi, &ad5770r_spi_regmap_config);
0624     if (IS_ERR(regmap)) {
0625         dev_err(&spi->dev, "Error initializing spi regmap: %ld\n",
0626             PTR_ERR(regmap));
0627         return PTR_ERR(regmap);
0628     }
0629     st->regmap = regmap;
0630 
0631     st->vref_reg = devm_regulator_get_optional(&spi->dev, "vref");
0632     if (!IS_ERR(st->vref_reg)) {
0633         ret = regulator_enable(st->vref_reg);
0634         if (ret) {
0635             dev_err(&spi->dev,
0636                 "Failed to enable vref regulators: %d\n", ret);
0637             return ret;
0638         }
0639 
0640         ret = devm_add_action_or_reset(&spi->dev,
0641                            ad5770r_disable_regulator,
0642                            st);
0643         if (ret < 0)
0644             return ret;
0645 
0646         ret = regulator_get_voltage(st->vref_reg);
0647         if (ret < 0)
0648             return ret;
0649 
0650         st->vref = ret / 1000;
0651     } else {
0652         if (PTR_ERR(st->vref_reg) == -ENODEV) {
0653             st->vref = AD5770R_LOW_VREF_mV;
0654             st->internal_ref = true;
0655         } else {
0656             return PTR_ERR(st->vref_reg);
0657         }
0658     }
0659 
0660     indio_dev->name = spi_get_device_id(spi)->name;
0661     indio_dev->info = &ad5770r_info;
0662     indio_dev->modes = INDIO_DIRECT_MODE;
0663     indio_dev->channels = ad5770r_channels;
0664     indio_dev->num_channels = ARRAY_SIZE(ad5770r_channels);
0665 
0666     ret = ad5770r_init(st);
0667     if (ret < 0) {
0668         dev_err(&spi->dev, "AD5770R init failed\n");
0669         return ret;
0670     }
0671 
0672     return devm_iio_device_register(&st->spi->dev, indio_dev);
0673 }
0674 
0675 static const struct of_device_id ad5770r_of_id[] = {
0676     { .compatible = "adi,ad5770r", },
0677     {},
0678 };
0679 MODULE_DEVICE_TABLE(of, ad5770r_of_id);
0680 
0681 static const struct spi_device_id ad5770r_id[] = {
0682     { "ad5770r", 0 },
0683     {},
0684 };
0685 MODULE_DEVICE_TABLE(spi, ad5770r_id);
0686 
0687 static struct spi_driver ad5770r_driver = {
0688     .driver = {
0689         .name = KBUILD_MODNAME,
0690         .of_match_table = ad5770r_of_id,
0691     },
0692     .probe = ad5770r_probe,
0693     .id_table = ad5770r_id,
0694 };
0695 
0696 module_spi_driver(ad5770r_driver);
0697 
0698 MODULE_AUTHOR("Mircea Caprioru <mircea.caprioru@analog.com>");
0699 MODULE_DESCRIPTION("Analog Devices AD5770R IDAC");
0700 MODULE_LICENSE("GPL v2");