Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * AD5758 Digital to analog converters driver
0004  *
0005  * Copyright 2018 Analog Devices Inc.
0006  *
0007  * TODO: Currently CRC is not supported in this driver
0008  */
0009 #include <linux/bsearch.h>
0010 #include <linux/delay.h>
0011 #include <linux/kernel.h>
0012 #include <linux/module.h>
0013 #include <linux/mod_devicetable.h>
0014 #include <linux/property.h>
0015 #include <linux/spi/spi.h>
0016 #include <linux/gpio/consumer.h>
0017 
0018 #include <linux/iio/iio.h>
0019 #include <linux/iio/sysfs.h>
0020 
0021 /* AD5758 registers definition */
0022 #define AD5758_NOP              0x00
0023 #define AD5758_DAC_INPUT            0x01
0024 #define AD5758_DAC_OUTPUT           0x02
0025 #define AD5758_CLEAR_CODE           0x03
0026 #define AD5758_USER_GAIN            0x04
0027 #define AD5758_USER_OFFSET          0x05
0028 #define AD5758_DAC_CONFIG           0x06
0029 #define AD5758_SW_LDAC              0x07
0030 #define AD5758_KEY              0x08
0031 #define AD5758_GP_CONFIG1           0x09
0032 #define AD5758_GP_CONFIG2           0x0A
0033 #define AD5758_DCDC_CONFIG1         0x0B
0034 #define AD5758_DCDC_CONFIG2         0x0C
0035 #define AD5758_WDT_CONFIG           0x0F
0036 #define AD5758_DIGITAL_DIAG_CONFIG      0x10
0037 #define AD5758_ADC_CONFIG           0x11
0038 #define AD5758_FAULT_PIN_CONFIG         0x12
0039 #define AD5758_TWO_STAGE_READBACK_SELECT    0x13
0040 #define AD5758_DIGITAL_DIAG_RESULTS     0x14
0041 #define AD5758_ANALOG_DIAG_RESULTS      0x15
0042 #define AD5758_STATUS               0x16
0043 #define AD5758_CHIP_ID              0x17
0044 #define AD5758_FREQ_MONITOR         0x18
0045 #define AD5758_DEVICE_ID_0          0x19
0046 #define AD5758_DEVICE_ID_1          0x1A
0047 #define AD5758_DEVICE_ID_2          0x1B
0048 #define AD5758_DEVICE_ID_3          0x1C
0049 
0050 /* AD5758_DAC_CONFIG */
0051 #define AD5758_DAC_CONFIG_RANGE_MSK     GENMASK(3, 0)
0052 #define AD5758_DAC_CONFIG_RANGE_MODE(x)     (((x) & 0xF) << 0)
0053 #define AD5758_DAC_CONFIG_INT_EN_MSK        BIT(5)
0054 #define AD5758_DAC_CONFIG_INT_EN_MODE(x)    (((x) & 0x1) << 5)
0055 #define AD5758_DAC_CONFIG_OUT_EN_MSK        BIT(6)
0056 #define AD5758_DAC_CONFIG_OUT_EN_MODE(x)    (((x) & 0x1) << 6)
0057 #define AD5758_DAC_CONFIG_SR_EN_MSK     BIT(8)
0058 #define AD5758_DAC_CONFIG_SR_EN_MODE(x)     (((x) & 0x1) << 8)
0059 #define AD5758_DAC_CONFIG_SR_CLOCK_MSK      GENMASK(12, 9)
0060 #define AD5758_DAC_CONFIG_SR_CLOCK_MODE(x)  (((x) & 0xF) << 9)
0061 #define AD5758_DAC_CONFIG_SR_STEP_MSK       GENMASK(15, 13)
0062 #define AD5758_DAC_CONFIG_SR_STEP_MODE(x)   (((x) & 0x7) << 13)
0063 
0064 /* AD5758_KEY */
0065 #define AD5758_KEY_CODE_RESET_1         0x15FA
0066 #define AD5758_KEY_CODE_RESET_2         0xAF51
0067 #define AD5758_KEY_CODE_SINGLE_ADC_CONV     0x1ADC
0068 #define AD5758_KEY_CODE_RESET_WDT       0x0D06
0069 #define AD5758_KEY_CODE_CALIB_MEM_REFRESH   0xFCBA
0070 
0071 /* AD5758_DCDC_CONFIG1 */
0072 #define AD5758_DCDC_CONFIG1_DCDC_VPROG_MSK  GENMASK(4, 0)
0073 #define AD5758_DCDC_CONFIG1_DCDC_VPROG_MODE(x)  (((x) & 0x1F) << 0)
0074 #define AD5758_DCDC_CONFIG1_DCDC_MODE_MSK   GENMASK(6, 5)
0075 #define AD5758_DCDC_CONFIG1_DCDC_MODE_MODE(x)   (((x) & 0x3) << 5)
0076 
0077 /* AD5758_DCDC_CONFIG2 */
0078 #define AD5758_DCDC_CONFIG2_ILIMIT_MSK      GENMASK(3, 1)
0079 #define AD5758_DCDC_CONFIG2_ILIMIT_MODE(x)  (((x) & 0x7) << 1)
0080 #define AD5758_DCDC_CONFIG2_INTR_SAT_3WI_MSK    BIT(11)
0081 #define AD5758_DCDC_CONFIG2_BUSY_3WI_MSK    BIT(12)
0082 
0083 /* AD5758_DIGITAL_DIAG_RESULTS */
0084 #define AD5758_CAL_MEM_UNREFRESHED_MSK      BIT(15)
0085 
0086 /* AD5758_ADC_CONFIG */
0087 #define AD5758_ADC_CONFIG_PPC_BUF_EN(x)     (((x) & 0x1) << 11)
0088 #define AD5758_ADC_CONFIG_PPC_BUF_MSK       BIT(11)
0089 
0090 #define AD5758_WR_FLAG_MSK(x)       (0x80 | ((x) & 0x1F))
0091 
0092 #define AD5758_FULL_SCALE_MICRO 65535000000ULL
0093 
0094 struct ad5758_range {
0095     int reg;
0096     int min;
0097     int max;
0098 };
0099 
0100 /**
0101  * struct ad5758_state - driver instance specific data
0102  * @spi:    spi_device
0103  * @lock:   mutex lock
0104  * @gpio_reset: gpio descriptor for the reset line
0105  * @out_range:  struct which stores the output range
0106  * @dc_dc_mode: variable which stores the mode of operation
0107  * @dc_dc_ilim: variable which stores the dc-to-dc converter current limit
0108  * @slew_time:  variable which stores the target slew time
0109  * @pwr_down:   variable which contains whether a channel is powered down or not
0110  * @d32:    spi transfer buffers
0111  */
0112 struct ad5758_state {
0113     struct spi_device *spi;
0114     struct mutex lock;
0115     struct gpio_desc *gpio_reset;
0116     struct ad5758_range out_range;
0117     unsigned int dc_dc_mode;
0118     unsigned int dc_dc_ilim;
0119     unsigned int slew_time;
0120     bool pwr_down;
0121     __be32 d32[3];
0122 };
0123 
0124 /*
0125  * Output ranges corresponding to bits [3:0] from DAC_CONFIG register
0126  * 0000: 0 V to 5 V voltage range
0127  * 0001: 0 V to 10 V voltage range
0128  * 0010: ±5 V voltage range
0129  * 0011: ±10 V voltage range
0130  * 1000: 0 mA to 20 mA current range
0131  * 1001: 0 mA to 24 mA current range
0132  * 1010: 4 mA to 20 mA current range
0133  * 1011: ±20 mA current range
0134  * 1100: ±24 mA current range
0135  * 1101: -1 mA to +22 mA current range
0136  */
0137 enum ad5758_output_range {
0138     AD5758_RANGE_0V_5V,
0139     AD5758_RANGE_0V_10V,
0140     AD5758_RANGE_PLUSMINUS_5V,
0141     AD5758_RANGE_PLUSMINUS_10V,
0142     AD5758_RANGE_0mA_20mA = 8,
0143     AD5758_RANGE_0mA_24mA,
0144     AD5758_RANGE_4mA_24mA,
0145     AD5758_RANGE_PLUSMINUS_20mA,
0146     AD5758_RANGE_PLUSMINUS_24mA,
0147     AD5758_RANGE_MINUS_1mA_PLUS_22mA,
0148 };
0149 
0150 enum ad5758_dc_dc_mode {
0151     AD5758_DCDC_MODE_POWER_OFF,
0152     AD5758_DCDC_MODE_DPC_CURRENT,
0153     AD5758_DCDC_MODE_DPC_VOLTAGE,
0154     AD5758_DCDC_MODE_PPC_CURRENT,
0155 };
0156 
0157 static const struct ad5758_range ad5758_voltage_range[] = {
0158     { AD5758_RANGE_0V_5V, 0, 5000000 },
0159     { AD5758_RANGE_0V_10V, 0, 10000000 },
0160     { AD5758_RANGE_PLUSMINUS_5V, -5000000, 5000000 },
0161     { AD5758_RANGE_PLUSMINUS_10V, -10000000, 10000000 }
0162 };
0163 
0164 static const struct ad5758_range ad5758_current_range[] = {
0165     { AD5758_RANGE_0mA_20mA, 0, 20000},
0166     { AD5758_RANGE_0mA_24mA, 0, 24000 },
0167     { AD5758_RANGE_4mA_24mA, 4, 24000 },
0168     { AD5758_RANGE_PLUSMINUS_20mA, -20000, 20000 },
0169     { AD5758_RANGE_PLUSMINUS_24mA, -24000, 24000 },
0170     { AD5758_RANGE_MINUS_1mA_PLUS_22mA, -1000, 22000 },
0171 };
0172 
0173 static const int ad5758_sr_clk[16] = {
0174     240000, 200000, 150000, 128000, 64000, 32000, 16000, 8000, 4000, 2000,
0175     1000, 512, 256, 128, 64, 16
0176 };
0177 
0178 static const int ad5758_sr_step[8] = {
0179     4, 12, 64, 120, 256, 500, 1820, 2048
0180 };
0181 
0182 static const int ad5758_dc_dc_ilim[6] = {
0183     150000, 200000, 250000, 300000, 350000, 400000
0184 };
0185 
0186 static int ad5758_spi_reg_read(struct ad5758_state *st, unsigned int addr)
0187 {
0188     struct spi_transfer t[] = {
0189         {
0190             .tx_buf = &st->d32[0],
0191             .len = 4,
0192             .cs_change = 1,
0193         }, {
0194             .tx_buf = &st->d32[1],
0195             .rx_buf = &st->d32[2],
0196             .len = 4,
0197         },
0198     };
0199     int ret;
0200 
0201     st->d32[0] = cpu_to_be32(
0202         (AD5758_WR_FLAG_MSK(AD5758_TWO_STAGE_READBACK_SELECT) << 24) |
0203         (addr << 8));
0204     st->d32[1] = cpu_to_be32(AD5758_WR_FLAG_MSK(AD5758_NOP) << 24);
0205 
0206     ret = spi_sync_transfer(st->spi, t, ARRAY_SIZE(t));
0207     if (ret < 0)
0208         return ret;
0209 
0210     return (be32_to_cpu(st->d32[2]) >> 8) & 0xFFFF;
0211 }
0212 
0213 static int ad5758_spi_reg_write(struct ad5758_state *st,
0214                 unsigned int addr,
0215                 unsigned int val)
0216 {
0217     st->d32[0] = cpu_to_be32((AD5758_WR_FLAG_MSK(addr) << 24) |
0218                  ((val & 0xFFFF) << 8));
0219 
0220     return spi_write(st->spi, &st->d32[0], sizeof(st->d32[0]));
0221 }
0222 
0223 static int ad5758_spi_write_mask(struct ad5758_state *st,
0224                  unsigned int addr,
0225                  unsigned long int mask,
0226                  unsigned int val)
0227 {
0228     int regval;
0229 
0230     regval = ad5758_spi_reg_read(st, addr);
0231     if (regval < 0)
0232         return regval;
0233 
0234     regval &= ~mask;
0235     regval |= val;
0236 
0237     return ad5758_spi_reg_write(st, addr, regval);
0238 }
0239 
0240 static int cmpfunc(const void *a, const void *b)
0241 {
0242     return *(int *)a - *(int *)b;
0243 }
0244 
0245 static int ad5758_find_closest_match(const int *array,
0246                      unsigned int size, int val)
0247 {
0248     int i;
0249 
0250     for (i = 0; i < size; i++) {
0251         if (val <= array[i])
0252             return i;
0253     }
0254 
0255     return size - 1;
0256 }
0257 
0258 static int ad5758_wait_for_task_complete(struct ad5758_state *st,
0259                      unsigned int reg,
0260                      unsigned int mask)
0261 {
0262     unsigned int timeout;
0263     int ret;
0264 
0265     timeout = 10;
0266     do {
0267         ret = ad5758_spi_reg_read(st, reg);
0268         if (ret < 0)
0269             return ret;
0270 
0271         if (!(ret & mask))
0272             return 0;
0273 
0274         usleep_range(100, 1000);
0275     } while (--timeout);
0276 
0277     dev_err(&st->spi->dev,
0278         "Error reading bit 0x%x in 0x%x register\n", mask, reg);
0279 
0280     return -EIO;
0281 }
0282 
0283 static int ad5758_calib_mem_refresh(struct ad5758_state *st)
0284 {
0285     int ret;
0286 
0287     ret = ad5758_spi_reg_write(st, AD5758_KEY,
0288                    AD5758_KEY_CODE_CALIB_MEM_REFRESH);
0289     if (ret < 0) {
0290         dev_err(&st->spi->dev,
0291             "Failed to initiate a calibration memory refresh\n");
0292         return ret;
0293     }
0294 
0295     /* Wait to allow time for the internal calibrations to complete */
0296     return ad5758_wait_for_task_complete(st, AD5758_DIGITAL_DIAG_RESULTS,
0297                          AD5758_CAL_MEM_UNREFRESHED_MSK);
0298 }
0299 
0300 static int ad5758_soft_reset(struct ad5758_state *st)
0301 {
0302     int ret;
0303 
0304     ret = ad5758_spi_reg_write(st, AD5758_KEY, AD5758_KEY_CODE_RESET_1);
0305     if (ret < 0)
0306         return ret;
0307 
0308     ret = ad5758_spi_reg_write(st, AD5758_KEY, AD5758_KEY_CODE_RESET_2);
0309 
0310     /* Perform a software reset and wait at least 100us */
0311     usleep_range(100, 1000);
0312 
0313     return ret;
0314 }
0315 
0316 static int ad5758_set_dc_dc_conv_mode(struct ad5758_state *st,
0317                       enum ad5758_dc_dc_mode mode)
0318 {
0319     int ret;
0320 
0321     /*
0322      * The ENABLE_PPC_BUFFERS bit must be set prior to enabling PPC current
0323      * mode.
0324      */
0325     if (mode == AD5758_DCDC_MODE_PPC_CURRENT) {
0326         ret  = ad5758_spi_write_mask(st, AD5758_ADC_CONFIG,
0327                     AD5758_ADC_CONFIG_PPC_BUF_MSK,
0328                     AD5758_ADC_CONFIG_PPC_BUF_EN(1));
0329         if (ret < 0)
0330             return ret;
0331     }
0332 
0333     ret = ad5758_spi_write_mask(st, AD5758_DCDC_CONFIG1,
0334                     AD5758_DCDC_CONFIG1_DCDC_MODE_MSK,
0335                     AD5758_DCDC_CONFIG1_DCDC_MODE_MODE(mode));
0336     if (ret < 0)
0337         return ret;
0338 
0339     /*
0340      * Poll the BUSY_3WI bit in the DCDC_CONFIG2 register until it is 0.
0341      * This allows the 3-wire interface communication to complete.
0342      */
0343     ret = ad5758_wait_for_task_complete(st, AD5758_DCDC_CONFIG2,
0344                         AD5758_DCDC_CONFIG2_BUSY_3WI_MSK);
0345     if (ret < 0)
0346         return ret;
0347 
0348     st->dc_dc_mode = mode;
0349 
0350     return ret;
0351 }
0352 
0353 static int ad5758_set_dc_dc_ilim(struct ad5758_state *st, unsigned int ilim)
0354 {
0355     int ret;
0356 
0357     ret = ad5758_spi_write_mask(st, AD5758_DCDC_CONFIG2,
0358                     AD5758_DCDC_CONFIG2_ILIMIT_MSK,
0359                     AD5758_DCDC_CONFIG2_ILIMIT_MODE(ilim));
0360     if (ret < 0)
0361         return ret;
0362     /*
0363      * Poll the BUSY_3WI bit in the DCDC_CONFIG2 register until it is 0.
0364      * This allows the 3-wire interface communication to complete.
0365      */
0366     return ad5758_wait_for_task_complete(st, AD5758_DCDC_CONFIG2,
0367                          AD5758_DCDC_CONFIG2_BUSY_3WI_MSK);
0368 }
0369 
0370 static int ad5758_slew_rate_set(struct ad5758_state *st,
0371                 unsigned int sr_clk_idx,
0372                 unsigned int sr_step_idx)
0373 {
0374     unsigned int mode;
0375     unsigned long int mask;
0376     int ret;
0377 
0378     mask = AD5758_DAC_CONFIG_SR_EN_MSK |
0379            AD5758_DAC_CONFIG_SR_CLOCK_MSK |
0380            AD5758_DAC_CONFIG_SR_STEP_MSK;
0381     mode = AD5758_DAC_CONFIG_SR_EN_MODE(1) |
0382            AD5758_DAC_CONFIG_SR_STEP_MODE(sr_step_idx) |
0383            AD5758_DAC_CONFIG_SR_CLOCK_MODE(sr_clk_idx);
0384 
0385     ret = ad5758_spi_write_mask(st, AD5758_DAC_CONFIG, mask, mode);
0386     if (ret < 0)
0387         return ret;
0388 
0389     /* Wait to allow time for the internal calibrations to complete */
0390     return ad5758_wait_for_task_complete(st, AD5758_DIGITAL_DIAG_RESULTS,
0391                          AD5758_CAL_MEM_UNREFRESHED_MSK);
0392 }
0393 
0394 static int ad5758_slew_rate_config(struct ad5758_state *st)
0395 {
0396     unsigned int sr_clk_idx, sr_step_idx;
0397     int i, res;
0398     s64 diff_new, diff_old;
0399     u64 sr_step, calc_slew_time;
0400 
0401     sr_clk_idx = 0;
0402     sr_step_idx = 0;
0403     diff_old = S64_MAX;
0404     /*
0405      * The slew time can be determined by using the formula:
0406      * Slew Time = (Full Scale Out / (Step Size x Update Clk Freq))
0407      * where Slew time is expressed in microseconds
0408      * Given the desired slew time, the following algorithm determines the
0409      * best match for the step size and the update clock frequency.
0410      */
0411     for (i = 0; i < ARRAY_SIZE(ad5758_sr_clk); i++) {
0412         /*
0413          * Go through each valid update clock freq and determine a raw
0414          * value for the step size by using the formula:
0415          * Step Size = Full Scale Out / (Update Clk Freq * Slew Time)
0416          */
0417         sr_step = AD5758_FULL_SCALE_MICRO;
0418         do_div(sr_step, ad5758_sr_clk[i]);
0419         do_div(sr_step, st->slew_time);
0420         /*
0421          * After a raw value for step size was determined, find the
0422          * closest valid match
0423          */
0424         res = ad5758_find_closest_match(ad5758_sr_step,
0425                         ARRAY_SIZE(ad5758_sr_step),
0426                         sr_step);
0427         /* Calculate the slew time */
0428         calc_slew_time = AD5758_FULL_SCALE_MICRO;
0429         do_div(calc_slew_time, ad5758_sr_step[res]);
0430         do_div(calc_slew_time, ad5758_sr_clk[i]);
0431         /*
0432          * Determine with how many microseconds the calculated slew time
0433          * is different from the desired slew time and store the diff
0434          * for the next iteration
0435          */
0436         diff_new = abs(st->slew_time - calc_slew_time);
0437         if (diff_new < diff_old) {
0438             diff_old = diff_new;
0439             sr_clk_idx = i;
0440             sr_step_idx = res;
0441         }
0442     }
0443 
0444     return ad5758_slew_rate_set(st, sr_clk_idx, sr_step_idx);
0445 }
0446 
0447 static int ad5758_set_out_range(struct ad5758_state *st, int range)
0448 {
0449     int ret;
0450 
0451     ret = ad5758_spi_write_mask(st, AD5758_DAC_CONFIG,
0452                     AD5758_DAC_CONFIG_RANGE_MSK,
0453                     AD5758_DAC_CONFIG_RANGE_MODE(range));
0454     if (ret < 0)
0455         return ret;
0456 
0457     /* Wait to allow time for the internal calibrations to complete */
0458     return ad5758_wait_for_task_complete(st, AD5758_DIGITAL_DIAG_RESULTS,
0459                          AD5758_CAL_MEM_UNREFRESHED_MSK);
0460 }
0461 
0462 static int ad5758_internal_buffers_en(struct ad5758_state *st, bool enable)
0463 {
0464     int ret;
0465 
0466     ret = ad5758_spi_write_mask(st, AD5758_DAC_CONFIG,
0467                     AD5758_DAC_CONFIG_INT_EN_MSK,
0468                     AD5758_DAC_CONFIG_INT_EN_MODE(enable));
0469     if (ret < 0)
0470         return ret;
0471 
0472     /* Wait to allow time for the internal calibrations to complete */
0473     return ad5758_wait_for_task_complete(st, AD5758_DIGITAL_DIAG_RESULTS,
0474                          AD5758_CAL_MEM_UNREFRESHED_MSK);
0475 }
0476 
0477 static int ad5758_reset(struct ad5758_state *st)
0478 {
0479     if (st->gpio_reset) {
0480         gpiod_set_value(st->gpio_reset, 0);
0481         usleep_range(100, 1000);
0482         gpiod_set_value(st->gpio_reset, 1);
0483         usleep_range(100, 1000);
0484 
0485         return 0;
0486     } else {
0487         /* Perform a software reset */
0488         return ad5758_soft_reset(st);
0489     }
0490 }
0491 
0492 static int ad5758_reg_access(struct iio_dev *indio_dev,
0493                  unsigned int reg,
0494                  unsigned int writeval,
0495                  unsigned int *readval)
0496 {
0497     struct ad5758_state *st = iio_priv(indio_dev);
0498     int ret;
0499 
0500     mutex_lock(&st->lock);
0501     if (readval) {
0502         ret = ad5758_spi_reg_read(st, reg);
0503         if (ret < 0) {
0504             mutex_unlock(&st->lock);
0505             return ret;
0506         }
0507 
0508         *readval = ret;
0509         ret = 0;
0510     } else {
0511         ret = ad5758_spi_reg_write(st, reg, writeval);
0512     }
0513     mutex_unlock(&st->lock);
0514 
0515     return ret;
0516 }
0517 
0518 static int ad5758_read_raw(struct iio_dev *indio_dev,
0519                struct iio_chan_spec const *chan,
0520                int *val, int *val2, long info)
0521 {
0522     struct ad5758_state *st = iio_priv(indio_dev);
0523     int max, min, ret;
0524 
0525     switch (info) {
0526     case IIO_CHAN_INFO_RAW:
0527         mutex_lock(&st->lock);
0528         ret = ad5758_spi_reg_read(st, AD5758_DAC_INPUT);
0529         mutex_unlock(&st->lock);
0530         if (ret < 0)
0531             return ret;
0532 
0533         *val = ret;
0534         return IIO_VAL_INT;
0535     case IIO_CHAN_INFO_SCALE:
0536         min = st->out_range.min;
0537         max = st->out_range.max;
0538         *val = (max - min) / 1000;
0539         *val2 = 16;
0540         return IIO_VAL_FRACTIONAL_LOG2;
0541     case IIO_CHAN_INFO_OFFSET:
0542         min = st->out_range.min;
0543         max = st->out_range.max;
0544         *val = ((min * (1 << 16)) / (max - min)) / 1000;
0545         return IIO_VAL_INT;
0546     default:
0547         return -EINVAL;
0548     }
0549 }
0550 
0551 static int ad5758_write_raw(struct iio_dev *indio_dev,
0552                 struct iio_chan_spec const *chan,
0553                 int val, int val2, long info)
0554 {
0555     struct ad5758_state *st = iio_priv(indio_dev);
0556     int ret;
0557 
0558     switch (info) {
0559     case IIO_CHAN_INFO_RAW:
0560         mutex_lock(&st->lock);
0561         ret = ad5758_spi_reg_write(st, AD5758_DAC_INPUT, val);
0562         mutex_unlock(&st->lock);
0563         return ret;
0564     default:
0565         return -EINVAL;
0566     }
0567 }
0568 
0569 static ssize_t ad5758_read_powerdown(struct iio_dev *indio_dev,
0570                      uintptr_t priv,
0571                      const struct iio_chan_spec *chan,
0572                      char *buf)
0573 {
0574     struct ad5758_state *st = iio_priv(indio_dev);
0575 
0576     return sysfs_emit(buf, "%d\n", st->pwr_down);
0577 }
0578 
0579 static ssize_t ad5758_write_powerdown(struct iio_dev *indio_dev,
0580                       uintptr_t priv,
0581                       struct iio_chan_spec const *chan,
0582                       const char *buf, size_t len)
0583 {
0584     struct ad5758_state *st = iio_priv(indio_dev);
0585     bool pwr_down;
0586     unsigned int dac_config_mode, val;
0587     unsigned long int dac_config_msk;
0588     int ret;
0589 
0590     ret = kstrtobool(buf, &pwr_down);
0591     if (ret)
0592         return ret;
0593 
0594     mutex_lock(&st->lock);
0595     if (pwr_down)
0596         val = 0;
0597     else
0598         val = 1;
0599 
0600     dac_config_mode = AD5758_DAC_CONFIG_OUT_EN_MODE(val) |
0601               AD5758_DAC_CONFIG_INT_EN_MODE(val);
0602     dac_config_msk = AD5758_DAC_CONFIG_OUT_EN_MSK |
0603              AD5758_DAC_CONFIG_INT_EN_MSK;
0604 
0605     ret = ad5758_spi_write_mask(st, AD5758_DAC_CONFIG,
0606                     dac_config_msk,
0607                     dac_config_mode);
0608     if (ret < 0)
0609         goto err_unlock;
0610 
0611     st->pwr_down = pwr_down;
0612 
0613 err_unlock:
0614     mutex_unlock(&st->lock);
0615 
0616     return ret ? ret : len;
0617 }
0618 
0619 static const struct iio_info ad5758_info = {
0620     .read_raw = ad5758_read_raw,
0621     .write_raw = ad5758_write_raw,
0622     .debugfs_reg_access = &ad5758_reg_access,
0623 };
0624 
0625 static const struct iio_chan_spec_ext_info ad5758_ext_info[] = {
0626     {
0627         .name = "powerdown",
0628         .read = ad5758_read_powerdown,
0629         .write = ad5758_write_powerdown,
0630         .shared = IIO_SHARED_BY_TYPE,
0631     },
0632     { }
0633 };
0634 
0635 #define AD5758_DAC_CHAN(_chan_type) {               \
0636     .type = (_chan_type),                   \
0637     .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_RAW) |    \
0638         BIT(IIO_CHAN_INFO_SCALE) |          \
0639         BIT(IIO_CHAN_INFO_OFFSET),          \
0640     .indexed = 1,                       \
0641     .output = 1,                        \
0642     .ext_info = ad5758_ext_info,                \
0643 }
0644 
0645 static const struct iio_chan_spec ad5758_voltage_ch[] = {
0646     AD5758_DAC_CHAN(IIO_VOLTAGE)
0647 };
0648 
0649 static const struct iio_chan_spec ad5758_current_ch[] = {
0650     AD5758_DAC_CHAN(IIO_CURRENT)
0651 };
0652 
0653 static bool ad5758_is_valid_mode(enum ad5758_dc_dc_mode mode)
0654 {
0655     switch (mode) {
0656     case AD5758_DCDC_MODE_DPC_CURRENT:
0657     case AD5758_DCDC_MODE_DPC_VOLTAGE:
0658     case AD5758_DCDC_MODE_PPC_CURRENT:
0659         return true;
0660     default:
0661         return false;
0662     }
0663 }
0664 
0665 static int ad5758_crc_disable(struct ad5758_state *st)
0666 {
0667     unsigned int mask;
0668 
0669     mask = (AD5758_WR_FLAG_MSK(AD5758_DIGITAL_DIAG_CONFIG) << 24) | 0x5C3A;
0670     st->d32[0] = cpu_to_be32(mask);
0671 
0672     return spi_write(st->spi, &st->d32[0], 4);
0673 }
0674 
0675 static int ad5758_find_out_range(struct ad5758_state *st,
0676                  const struct ad5758_range *range,
0677                  unsigned int size,
0678                  int min, int max)
0679 {
0680     int i;
0681 
0682     for (i = 0; i < size; i++) {
0683         if ((min == range[i].min) && (max == range[i].max)) {
0684             st->out_range.reg = range[i].reg;
0685             st->out_range.min = range[i].min;
0686             st->out_range.max = range[i].max;
0687 
0688             return 0;
0689         }
0690     }
0691 
0692     return -EINVAL;
0693 }
0694 
0695 static int ad5758_parse_dt(struct ad5758_state *st)
0696 {
0697     unsigned int tmp, tmparray[2], size;
0698     const struct ad5758_range *range;
0699     int *index, ret;
0700 
0701     st->dc_dc_ilim = 0;
0702     ret = device_property_read_u32(&st->spi->dev,
0703                        "adi,dc-dc-ilim-microamp", &tmp);
0704     if (ret) {
0705         dev_dbg(&st->spi->dev,
0706             "Missing \"dc-dc-ilim-microamp\" property\n");
0707     } else {
0708         index = bsearch(&tmp, ad5758_dc_dc_ilim,
0709                 ARRAY_SIZE(ad5758_dc_dc_ilim),
0710                 sizeof(int), cmpfunc);
0711         if (!index)
0712             dev_dbg(&st->spi->dev, "dc-dc-ilim out of range\n");
0713         else
0714             st->dc_dc_ilim = index - ad5758_dc_dc_ilim;
0715     }
0716 
0717     ret = device_property_read_u32(&st->spi->dev, "adi,dc-dc-mode",
0718                        &st->dc_dc_mode);
0719     if (ret) {
0720         dev_err(&st->spi->dev, "Missing \"dc-dc-mode\" property\n");
0721         return ret;
0722     }
0723 
0724     if (!ad5758_is_valid_mode(st->dc_dc_mode))
0725         return -EINVAL;
0726 
0727     if (st->dc_dc_mode == AD5758_DCDC_MODE_DPC_VOLTAGE) {
0728         ret = device_property_read_u32_array(&st->spi->dev,
0729                              "adi,range-microvolt",
0730                              tmparray, 2);
0731         if (ret) {
0732             dev_err(&st->spi->dev,
0733                 "Missing \"range-microvolt\" property\n");
0734             return ret;
0735         }
0736         range = ad5758_voltage_range;
0737         size = ARRAY_SIZE(ad5758_voltage_range);
0738     } else {
0739         ret = device_property_read_u32_array(&st->spi->dev,
0740                              "adi,range-microamp",
0741                              tmparray, 2);
0742         if (ret) {
0743             dev_err(&st->spi->dev,
0744                 "Missing \"range-microamp\" property\n");
0745             return ret;
0746         }
0747         range = ad5758_current_range;
0748         size = ARRAY_SIZE(ad5758_current_range);
0749     }
0750 
0751     ret = ad5758_find_out_range(st, range, size, tmparray[0], tmparray[1]);
0752     if (ret) {
0753         dev_err(&st->spi->dev, "range invalid\n");
0754         return ret;
0755     }
0756 
0757     ret = device_property_read_u32(&st->spi->dev, "adi,slew-time-us", &tmp);
0758     if (ret) {
0759         dev_dbg(&st->spi->dev, "Missing \"slew-time-us\" property\n");
0760         st->slew_time = 0;
0761     } else {
0762         st->slew_time = tmp;
0763     }
0764 
0765     return 0;
0766 }
0767 
0768 static int ad5758_init(struct ad5758_state *st)
0769 {
0770     int regval, ret;
0771 
0772     st->gpio_reset = devm_gpiod_get_optional(&st->spi->dev, "reset",
0773                          GPIOD_OUT_HIGH);
0774     if (IS_ERR(st->gpio_reset))
0775         return PTR_ERR(st->gpio_reset);
0776 
0777     /* Disable CRC checks */
0778     ret = ad5758_crc_disable(st);
0779     if (ret < 0)
0780         return ret;
0781 
0782     /* Perform a reset */
0783     ret = ad5758_reset(st);
0784     if (ret < 0)
0785         return ret;
0786 
0787     /* Disable CRC checks */
0788     ret = ad5758_crc_disable(st);
0789     if (ret < 0)
0790         return ret;
0791 
0792     /* Perform a calibration memory refresh */
0793     ret = ad5758_calib_mem_refresh(st);
0794     if (ret < 0)
0795         return ret;
0796 
0797     regval = ad5758_spi_reg_read(st, AD5758_DIGITAL_DIAG_RESULTS);
0798     if (regval < 0)
0799         return regval;
0800 
0801     /* Clear all the error flags */
0802     ret = ad5758_spi_reg_write(st, AD5758_DIGITAL_DIAG_RESULTS, regval);
0803     if (ret < 0)
0804         return ret;
0805 
0806     /* Set the dc-to-dc current limit */
0807     ret = ad5758_set_dc_dc_ilim(st, st->dc_dc_ilim);
0808     if (ret < 0)
0809         return ret;
0810 
0811     /* Configure the dc-to-dc controller mode */
0812     ret = ad5758_set_dc_dc_conv_mode(st, st->dc_dc_mode);
0813     if (ret < 0)
0814         return ret;
0815 
0816     /* Configure the output range */
0817     ret = ad5758_set_out_range(st, st->out_range.reg);
0818     if (ret < 0)
0819         return ret;
0820 
0821     /* Enable Slew Rate Control, set the slew rate clock and step */
0822     if (st->slew_time) {
0823         ret = ad5758_slew_rate_config(st);
0824         if (ret < 0)
0825             return ret;
0826     }
0827 
0828     /* Power up the DAC and internal (INT) amplifiers */
0829     ret = ad5758_internal_buffers_en(st, 1);
0830     if (ret < 0)
0831         return ret;
0832 
0833     /* Enable VIOUT */
0834     return ad5758_spi_write_mask(st, AD5758_DAC_CONFIG,
0835                      AD5758_DAC_CONFIG_OUT_EN_MSK,
0836                      AD5758_DAC_CONFIG_OUT_EN_MODE(1));
0837 }
0838 
0839 static int ad5758_probe(struct spi_device *spi)
0840 {
0841     struct ad5758_state *st;
0842     struct iio_dev *indio_dev;
0843     int ret;
0844 
0845     indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
0846     if (!indio_dev)
0847         return -ENOMEM;
0848 
0849     st = iio_priv(indio_dev);
0850     spi_set_drvdata(spi, indio_dev);
0851 
0852     st->spi = spi;
0853 
0854     mutex_init(&st->lock);
0855 
0856     indio_dev->name = spi_get_device_id(spi)->name;
0857     indio_dev->info = &ad5758_info;
0858     indio_dev->modes = INDIO_DIRECT_MODE;
0859     indio_dev->num_channels = 1;
0860 
0861     ret = ad5758_parse_dt(st);
0862     if (ret < 0)
0863         return ret;
0864 
0865     if (st->dc_dc_mode == AD5758_DCDC_MODE_DPC_VOLTAGE)
0866         indio_dev->channels = ad5758_voltage_ch;
0867     else
0868         indio_dev->channels = ad5758_current_ch;
0869 
0870     ret = ad5758_init(st);
0871     if (ret < 0) {
0872         dev_err(&spi->dev, "AD5758 init failed\n");
0873         return ret;
0874     }
0875 
0876     return devm_iio_device_register(&st->spi->dev, indio_dev);
0877 }
0878 
0879 static const struct spi_device_id ad5758_id[] = {
0880     { "ad5758", 0 },
0881     {}
0882 };
0883 MODULE_DEVICE_TABLE(spi, ad5758_id);
0884 
0885 static const struct of_device_id ad5758_of_match[] = {
0886         { .compatible = "adi,ad5758" },
0887         { },
0888 };
0889 MODULE_DEVICE_TABLE(of, ad5758_of_match);
0890 
0891 static struct spi_driver ad5758_driver = {
0892     .driver = {
0893         .name = KBUILD_MODNAME,
0894         .of_match_table = ad5758_of_match,
0895     },
0896     .probe = ad5758_probe,
0897     .id_table = ad5758_id,
0898 };
0899 
0900 module_spi_driver(ad5758_driver);
0901 
0902 MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
0903 MODULE_DESCRIPTION("Analog Devices AD5758 DAC");
0904 MODULE_LICENSE("GPL v2");