root/drivers/iio/dac/ad5761.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _ad5761_spi_write
  2. ad5761_spi_write
  3. _ad5761_spi_read
  4. ad5761_spi_read
  5. ad5761_spi_set_range
  6. ad5761_read_raw
  7. ad5761_write_raw
  8. ad5761_get_vref
  9. ad5761_probe
  10. ad5761_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * AD5721, AD5721R, AD5761, AD5761R, Voltage Output Digital to Analog Converter
   4  *
   5  * Copyright 2016 Qtechnology A/S
   6  * 2016 Ricardo Ribalda <ricardo.ribalda@gmail.com>
   7  */
   8 #include <linux/kernel.h>
   9 #include <linux/module.h>
  10 #include <linux/spi/spi.h>
  11 #include <linux/bitops.h>
  12 #include <linux/iio/iio.h>
  13 #include <linux/iio/sysfs.h>
  14 #include <linux/regulator/consumer.h>
  15 #include <linux/platform_data/ad5761.h>
  16 
  17 #define AD5761_ADDR(addr)               ((addr & 0xf) << 16)
  18 #define AD5761_ADDR_NOOP                0x0
  19 #define AD5761_ADDR_DAC_WRITE           0x3
  20 #define AD5761_ADDR_CTRL_WRITE_REG      0x4
  21 #define AD5761_ADDR_SW_DATA_RESET       0x7
  22 #define AD5761_ADDR_DAC_READ            0xb
  23 #define AD5761_ADDR_CTRL_READ_REG       0xc
  24 #define AD5761_ADDR_SW_FULL_RESET       0xf
  25 
  26 #define AD5761_CTRL_USE_INTVREF         BIT(5)
  27 #define AD5761_CTRL_ETS                 BIT(6)
  28 
  29 /**
  30  * struct ad5761_chip_info - chip specific information
  31  * @int_vref:   Value of the internal reference voltage in mV - 0 if external
  32  *              reference voltage is used
  33  * @channel:    channel specification
  34 */
  35 
  36 struct ad5761_chip_info {
  37         unsigned long int_vref;
  38         const struct iio_chan_spec channel;
  39 };
  40 
  41 struct ad5761_range_params {
  42         int m;
  43         int c;
  44 };
  45 
  46 enum ad5761_supported_device_ids {
  47         ID_AD5721,
  48         ID_AD5721R,
  49         ID_AD5761,
  50         ID_AD5761R,
  51 };
  52 
  53 /**
  54  * struct ad5761_state - driver instance specific data
  55  * @spi:                spi_device
  56  * @vref_reg:           reference voltage regulator
  57  * @use_intref:         true when the internal voltage reference is used
  58  * @vref:               actual voltage reference in mVolts
  59  * @range:              output range mode used
  60  * @data:               cache aligned spi buffer
  61  */
  62 struct ad5761_state {
  63         struct spi_device               *spi;
  64         struct regulator                *vref_reg;
  65 
  66         bool use_intref;
  67         int vref;
  68         enum ad5761_voltage_range range;
  69 
  70         /*
  71          * DMA (thus cache coherency maintenance) requires the
  72          * transfer buffers to live in their own cache lines.
  73          */
  74         union {
  75                 __be32 d32;
  76                 u8 d8[4];
  77         } data[3] ____cacheline_aligned;
  78 };
  79 
  80 static const struct ad5761_range_params ad5761_range_params[] = {
  81         [AD5761_VOLTAGE_RANGE_M10V_10V] = {
  82                 .m = 80,
  83                 .c = 40,
  84         },
  85         [AD5761_VOLTAGE_RANGE_0V_10V] = {
  86                 .m = 40,
  87                 .c = 0,
  88         },
  89         [AD5761_VOLTAGE_RANGE_M5V_5V] = {
  90                 .m = 40,
  91                 .c = 20,
  92         },
  93         [AD5761_VOLTAGE_RANGE_0V_5V] = {
  94                 .m = 20,
  95                 .c = 0,
  96         },
  97         [AD5761_VOLTAGE_RANGE_M2V5_7V5] = {
  98                 .m = 40,
  99                 .c = 10,
 100         },
 101         [AD5761_VOLTAGE_RANGE_M3V_3V] = {
 102                 .m = 24,
 103                 .c = 12,
 104         },
 105         [AD5761_VOLTAGE_RANGE_0V_16V] = {
 106                 .m = 64,
 107                 .c = 0,
 108         },
 109         [AD5761_VOLTAGE_RANGE_0V_20V] = {
 110                 .m = 80,
 111                 .c = 0,
 112         },
 113 };
 114 
 115 static int _ad5761_spi_write(struct ad5761_state *st, u8 addr, u16 val)
 116 {
 117         st->data[0].d32 = cpu_to_be32(AD5761_ADDR(addr) | val);
 118 
 119         return spi_write(st->spi, &st->data[0].d8[1], 3);
 120 }
 121 
 122 static int ad5761_spi_write(struct iio_dev *indio_dev, u8 addr, u16 val)
 123 {
 124         struct ad5761_state *st = iio_priv(indio_dev);
 125         int ret;
 126 
 127         mutex_lock(&indio_dev->mlock);
 128         ret = _ad5761_spi_write(st, addr, val);
 129         mutex_unlock(&indio_dev->mlock);
 130 
 131         return ret;
 132 }
 133 
 134 static int _ad5761_spi_read(struct ad5761_state *st, u8 addr, u16 *val)
 135 {
 136         int ret;
 137         struct spi_transfer xfers[] = {
 138                 {
 139                         .tx_buf = &st->data[0].d8[1],
 140                         .bits_per_word = 8,
 141                         .len = 3,
 142                         .cs_change = true,
 143                 }, {
 144                         .tx_buf = &st->data[1].d8[1],
 145                         .rx_buf = &st->data[2].d8[1],
 146                         .bits_per_word = 8,
 147                         .len = 3,
 148                 },
 149         };
 150 
 151         st->data[0].d32 = cpu_to_be32(AD5761_ADDR(addr));
 152         st->data[1].d32 = cpu_to_be32(AD5761_ADDR(AD5761_ADDR_NOOP));
 153 
 154         ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
 155 
 156         *val = be32_to_cpu(st->data[2].d32);
 157 
 158         return ret;
 159 }
 160 
 161 static int ad5761_spi_read(struct iio_dev *indio_dev, u8 addr, u16 *val)
 162 {
 163         struct ad5761_state *st = iio_priv(indio_dev);
 164         int ret;
 165 
 166         mutex_lock(&indio_dev->mlock);
 167         ret = _ad5761_spi_read(st, addr, val);
 168         mutex_unlock(&indio_dev->mlock);
 169 
 170         return ret;
 171 }
 172 
 173 static int ad5761_spi_set_range(struct ad5761_state *st,
 174                                 enum ad5761_voltage_range range)
 175 {
 176         u16 aux;
 177         int ret;
 178 
 179         aux = (range & 0x7) | AD5761_CTRL_ETS;
 180 
 181         if (st->use_intref)
 182                 aux |= AD5761_CTRL_USE_INTVREF;
 183 
 184         ret = _ad5761_spi_write(st, AD5761_ADDR_SW_FULL_RESET, 0);
 185         if (ret)
 186                 return ret;
 187 
 188         ret = _ad5761_spi_write(st, AD5761_ADDR_CTRL_WRITE_REG, aux);
 189         if (ret)
 190                 return ret;
 191 
 192         st->range = range;
 193 
 194         return 0;
 195 }
 196 
 197 static int ad5761_read_raw(struct iio_dev *indio_dev,
 198                            struct iio_chan_spec const *chan,
 199                            int *val,
 200                            int *val2,
 201                            long mask)
 202 {
 203         struct ad5761_state *st;
 204         int ret;
 205         u16 aux;
 206 
 207         switch (mask) {
 208         case IIO_CHAN_INFO_RAW:
 209                 ret = ad5761_spi_read(indio_dev, AD5761_ADDR_DAC_READ, &aux);
 210                 if (ret)
 211                         return ret;
 212                 *val = aux >> chan->scan_type.shift;
 213                 return IIO_VAL_INT;
 214         case IIO_CHAN_INFO_SCALE:
 215                 st = iio_priv(indio_dev);
 216                 *val = st->vref * ad5761_range_params[st->range].m;
 217                 *val /= 10;
 218                 *val2 = chan->scan_type.realbits;
 219                 return IIO_VAL_FRACTIONAL_LOG2;
 220         case IIO_CHAN_INFO_OFFSET:
 221                 st = iio_priv(indio_dev);
 222                 *val = -(1 << chan->scan_type.realbits);
 223                 *val *= ad5761_range_params[st->range].c;
 224                 *val /= ad5761_range_params[st->range].m;
 225                 return IIO_VAL_INT;
 226         default:
 227                 return -EINVAL;
 228         }
 229 }
 230 
 231 static int ad5761_write_raw(struct iio_dev *indio_dev,
 232                             struct iio_chan_spec const *chan,
 233                             int val,
 234                             int val2,
 235                             long mask)
 236 {
 237         u16 aux;
 238 
 239         if (mask != IIO_CHAN_INFO_RAW)
 240                 return -EINVAL;
 241 
 242         if (val2 || (val << chan->scan_type.shift) > 0xffff || val < 0)
 243                 return -EINVAL;
 244 
 245         aux = val << chan->scan_type.shift;
 246 
 247         return ad5761_spi_write(indio_dev, AD5761_ADDR_DAC_WRITE, aux);
 248 }
 249 
 250 static const struct iio_info ad5761_info = {
 251         .read_raw = &ad5761_read_raw,
 252         .write_raw = &ad5761_write_raw,
 253 };
 254 
 255 #define AD5761_CHAN(_bits) {                            \
 256         .type = IIO_VOLTAGE,                            \
 257         .output = 1,                                    \
 258         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
 259         .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |  \
 260                 BIT(IIO_CHAN_INFO_OFFSET),              \
 261         .scan_type = {                                  \
 262                 .sign = 'u',                            \
 263                 .realbits = (_bits),                    \
 264                 .storagebits = 16,                      \
 265                 .shift = 16 - (_bits),                  \
 266         },                                              \
 267 }
 268 
 269 static const struct ad5761_chip_info ad5761_chip_infos[] = {
 270         [ID_AD5721] = {
 271                 .int_vref = 0,
 272                 .channel = AD5761_CHAN(12),
 273         },
 274         [ID_AD5721R] = {
 275                 .int_vref = 2500,
 276                 .channel = AD5761_CHAN(12),
 277         },
 278         [ID_AD5761] = {
 279                 .int_vref = 0,
 280                 .channel = AD5761_CHAN(16),
 281         },
 282         [ID_AD5761R] = {
 283                 .int_vref = 2500,
 284                 .channel = AD5761_CHAN(16),
 285         },
 286 };
 287 
 288 static int ad5761_get_vref(struct ad5761_state *st,
 289                            const struct ad5761_chip_info *chip_info)
 290 {
 291         int ret;
 292 
 293         st->vref_reg = devm_regulator_get_optional(&st->spi->dev, "vref");
 294         if (PTR_ERR(st->vref_reg) == -ENODEV) {
 295                 /* Use Internal regulator */
 296                 if (!chip_info->int_vref) {
 297                         dev_err(&st->spi->dev,
 298                                 "Voltage reference not found\n");
 299                         return -EIO;
 300                 }
 301 
 302                 st->use_intref = true;
 303                 st->vref = chip_info->int_vref;
 304                 return 0;
 305         }
 306 
 307         if (IS_ERR(st->vref_reg)) {
 308                 dev_err(&st->spi->dev,
 309                         "Error getting voltage reference regulator\n");
 310                 return PTR_ERR(st->vref_reg);
 311         }
 312 
 313         ret = regulator_enable(st->vref_reg);
 314         if (ret) {
 315                 dev_err(&st->spi->dev,
 316                          "Failed to enable voltage reference\n");
 317                 return ret;
 318         }
 319 
 320         ret = regulator_get_voltage(st->vref_reg);
 321         if (ret < 0) {
 322                 dev_err(&st->spi->dev,
 323                          "Failed to get voltage reference value\n");
 324                 goto disable_regulator_vref;
 325         }
 326 
 327         if (ret < 2000000 || ret > 3000000) {
 328                 dev_warn(&st->spi->dev,
 329                          "Invalid external voltage ref. value %d uV\n", ret);
 330                 ret = -EIO;
 331                 goto disable_regulator_vref;
 332         }
 333 
 334         st->vref = ret / 1000;
 335         st->use_intref = false;
 336 
 337         return 0;
 338 
 339 disable_regulator_vref:
 340         regulator_disable(st->vref_reg);
 341         st->vref_reg = NULL;
 342         return ret;
 343 }
 344 
 345 static int ad5761_probe(struct spi_device *spi)
 346 {
 347         struct iio_dev *iio_dev;
 348         struct ad5761_state *st;
 349         int ret;
 350         const struct ad5761_chip_info *chip_info =
 351                 &ad5761_chip_infos[spi_get_device_id(spi)->driver_data];
 352         enum ad5761_voltage_range voltage_range = AD5761_VOLTAGE_RANGE_0V_5V;
 353         struct ad5761_platform_data *pdata = dev_get_platdata(&spi->dev);
 354 
 355         iio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 356         if (!iio_dev)
 357                 return -ENOMEM;
 358 
 359         st = iio_priv(iio_dev);
 360 
 361         st->spi = spi;
 362         spi_set_drvdata(spi, iio_dev);
 363 
 364         ret = ad5761_get_vref(st, chip_info);
 365         if (ret)
 366                 return ret;
 367 
 368         if (pdata)
 369                 voltage_range = pdata->voltage_range;
 370 
 371         ret = ad5761_spi_set_range(st, voltage_range);
 372         if (ret)
 373                 goto disable_regulator_err;
 374 
 375         iio_dev->dev.parent = &spi->dev;
 376         iio_dev->info = &ad5761_info;
 377         iio_dev->modes = INDIO_DIRECT_MODE;
 378         iio_dev->channels = &chip_info->channel;
 379         iio_dev->num_channels = 1;
 380         iio_dev->name = spi_get_device_id(st->spi)->name;
 381         ret = iio_device_register(iio_dev);
 382         if (ret)
 383                 goto disable_regulator_err;
 384 
 385         return 0;
 386 
 387 disable_regulator_err:
 388         if (!IS_ERR_OR_NULL(st->vref_reg))
 389                 regulator_disable(st->vref_reg);
 390 
 391         return ret;
 392 }
 393 
 394 static int ad5761_remove(struct spi_device *spi)
 395 {
 396         struct iio_dev *iio_dev = spi_get_drvdata(spi);
 397         struct ad5761_state *st = iio_priv(iio_dev);
 398 
 399         iio_device_unregister(iio_dev);
 400 
 401         if (!IS_ERR_OR_NULL(st->vref_reg))
 402                 regulator_disable(st->vref_reg);
 403 
 404         return 0;
 405 }
 406 
 407 static const struct spi_device_id ad5761_id[] = {
 408         {"ad5721", ID_AD5721},
 409         {"ad5721r", ID_AD5721R},
 410         {"ad5761", ID_AD5761},
 411         {"ad5761r", ID_AD5761R},
 412         {}
 413 };
 414 MODULE_DEVICE_TABLE(spi, ad5761_id);
 415 
 416 static struct spi_driver ad5761_driver = {
 417         .driver = {
 418                    .name = "ad5761",
 419                    },
 420         .probe = ad5761_probe,
 421         .remove = ad5761_remove,
 422         .id_table = ad5761_id,
 423 };
 424 module_spi_driver(ad5761_driver);
 425 
 426 MODULE_AUTHOR("Ricardo Ribalda <ricardo.ribalda@gmail.com>");
 427 MODULE_DESCRIPTION("Analog Devices AD5721, AD5721R, AD5761, AD5761R driver");
 428 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */