root/drivers/iio/dac/ad5686.c

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

DEFINITIONS

This source file includes following definitions.
  1. ad5686_get_powerdown_mode
  2. ad5686_set_powerdown_mode
  3. ad5686_read_dac_powerdown
  4. ad5686_write_dac_powerdown
  5. ad5686_read_raw
  6. ad5686_write_raw
  7. ad5686_probe
  8. ad5686_remove

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * AD5686R, AD5685R, AD5684R Digital to analog converters  driver
   4  *
   5  * Copyright 2011 Analog Devices Inc.
   6  */
   7 
   8 #include <linux/interrupt.h>
   9 #include <linux/fs.h>
  10 #include <linux/device.h>
  11 #include <linux/module.h>
  12 #include <linux/kernel.h>
  13 #include <linux/slab.h>
  14 #include <linux/sysfs.h>
  15 #include <linux/regulator/consumer.h>
  16 
  17 #include <linux/iio/iio.h>
  18 #include <linux/iio/sysfs.h>
  19 
  20 #include "ad5686.h"
  21 
  22 static const char * const ad5686_powerdown_modes[] = {
  23         "1kohm_to_gnd",
  24         "100kohm_to_gnd",
  25         "three_state"
  26 };
  27 
  28 static int ad5686_get_powerdown_mode(struct iio_dev *indio_dev,
  29                                      const struct iio_chan_spec *chan)
  30 {
  31         struct ad5686_state *st = iio_priv(indio_dev);
  32 
  33         return ((st->pwr_down_mode >> (chan->channel * 2)) & 0x3) - 1;
  34 }
  35 
  36 static int ad5686_set_powerdown_mode(struct iio_dev *indio_dev,
  37                                      const struct iio_chan_spec *chan,
  38                                      unsigned int mode)
  39 {
  40         struct ad5686_state *st = iio_priv(indio_dev);
  41 
  42         st->pwr_down_mode &= ~(0x3 << (chan->channel * 2));
  43         st->pwr_down_mode |= ((mode + 1) << (chan->channel * 2));
  44 
  45         return 0;
  46 }
  47 
  48 static const struct iio_enum ad5686_powerdown_mode_enum = {
  49         .items = ad5686_powerdown_modes,
  50         .num_items = ARRAY_SIZE(ad5686_powerdown_modes),
  51         .get = ad5686_get_powerdown_mode,
  52         .set = ad5686_set_powerdown_mode,
  53 };
  54 
  55 static ssize_t ad5686_read_dac_powerdown(struct iio_dev *indio_dev,
  56                 uintptr_t private, const struct iio_chan_spec *chan, char *buf)
  57 {
  58         struct ad5686_state *st = iio_priv(indio_dev);
  59 
  60         return sprintf(buf, "%d\n", !!(st->pwr_down_mask &
  61                                        (0x3 << (chan->channel * 2))));
  62 }
  63 
  64 static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev,
  65                                           uintptr_t private,
  66                                           const struct iio_chan_spec *chan,
  67                                           const char *buf,
  68                                           size_t len)
  69 {
  70         bool readin;
  71         int ret;
  72         struct ad5686_state *st = iio_priv(indio_dev);
  73         unsigned int val, ref_bit_msk;
  74         u8 shift, address = 0;
  75 
  76         ret = strtobool(buf, &readin);
  77         if (ret)
  78                 return ret;
  79 
  80         if (readin)
  81                 st->pwr_down_mask |= (0x3 << (chan->channel * 2));
  82         else
  83                 st->pwr_down_mask &= ~(0x3 << (chan->channel * 2));
  84 
  85         switch (st->chip_info->regmap_type) {
  86         case AD5310_REGMAP:
  87                 shift = 9;
  88                 ref_bit_msk = AD5310_REF_BIT_MSK;
  89                 break;
  90         case AD5683_REGMAP:
  91                 shift = 13;
  92                 ref_bit_msk = AD5683_REF_BIT_MSK;
  93                 break;
  94         case AD5686_REGMAP:
  95                 shift = 0;
  96                 ref_bit_msk = 0;
  97                 /* AD5674R/AD5679R have 16 channels and 2 powerdown registers */
  98                 if (chan->channel > 0x7)
  99                         address = 0x8;
 100                 break;
 101         case AD5693_REGMAP:
 102                 shift = 13;
 103                 ref_bit_msk = AD5693_REF_BIT_MSK;
 104                 break;
 105         default:
 106                 return -EINVAL;
 107         }
 108 
 109         val = ((st->pwr_down_mask & st->pwr_down_mode) << shift);
 110         if (!st->use_internal_vref)
 111                 val |= ref_bit_msk;
 112 
 113         ret = st->write(st, AD5686_CMD_POWERDOWN_DAC,
 114                         address, val >> (address * 2));
 115 
 116         return ret ? ret : len;
 117 }
 118 
 119 static int ad5686_read_raw(struct iio_dev *indio_dev,
 120                            struct iio_chan_spec const *chan,
 121                            int *val,
 122                            int *val2,
 123                            long m)
 124 {
 125         struct ad5686_state *st = iio_priv(indio_dev);
 126         int ret;
 127 
 128         switch (m) {
 129         case IIO_CHAN_INFO_RAW:
 130                 mutex_lock(&indio_dev->mlock);
 131                 ret = st->read(st, chan->address);
 132                 mutex_unlock(&indio_dev->mlock);
 133                 if (ret < 0)
 134                         return ret;
 135                 *val = (ret >> chan->scan_type.shift) &
 136                         GENMASK(chan->scan_type.realbits - 1, 0);
 137                 return IIO_VAL_INT;
 138         case IIO_CHAN_INFO_SCALE:
 139                 *val = st->vref_mv;
 140                 *val2 = chan->scan_type.realbits;
 141                 return IIO_VAL_FRACTIONAL_LOG2;
 142         }
 143         return -EINVAL;
 144 }
 145 
 146 static int ad5686_write_raw(struct iio_dev *indio_dev,
 147                             struct iio_chan_spec const *chan,
 148                             int val,
 149                             int val2,
 150                             long mask)
 151 {
 152         struct ad5686_state *st = iio_priv(indio_dev);
 153         int ret;
 154 
 155         switch (mask) {
 156         case IIO_CHAN_INFO_RAW:
 157                 if (val > (1 << chan->scan_type.realbits) || val < 0)
 158                         return -EINVAL;
 159 
 160                 mutex_lock(&indio_dev->mlock);
 161                 ret = st->write(st,
 162                                 AD5686_CMD_WRITE_INPUT_N_UPDATE_N,
 163                                 chan->address,
 164                                 val << chan->scan_type.shift);
 165                 mutex_unlock(&indio_dev->mlock);
 166                 break;
 167         default:
 168                 ret = -EINVAL;
 169         }
 170 
 171         return ret;
 172 }
 173 
 174 static const struct iio_info ad5686_info = {
 175         .read_raw = ad5686_read_raw,
 176         .write_raw = ad5686_write_raw,
 177 };
 178 
 179 static const struct iio_chan_spec_ext_info ad5686_ext_info[] = {
 180         {
 181                 .name = "powerdown",
 182                 .read = ad5686_read_dac_powerdown,
 183                 .write = ad5686_write_dac_powerdown,
 184                 .shared = IIO_SEPARATE,
 185         },
 186         IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad5686_powerdown_mode_enum),
 187         IIO_ENUM_AVAILABLE("powerdown_mode", &ad5686_powerdown_mode_enum),
 188         { },
 189 };
 190 
 191 #define AD5868_CHANNEL(chan, addr, bits, _shift) {              \
 192                 .type = IIO_VOLTAGE,                            \
 193                 .indexed = 1,                                   \
 194                 .output = 1,                                    \
 195                 .channel = chan,                                \
 196                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
 197                 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),\
 198                 .address = addr,                                \
 199                 .scan_type = {                                  \
 200                         .sign = 'u',                            \
 201                         .realbits = (bits),                     \
 202                         .storagebits = 16,                      \
 203                         .shift = (_shift),                      \
 204                 },                                              \
 205                 .ext_info = ad5686_ext_info,                    \
 206 }
 207 
 208 #define DECLARE_AD5693_CHANNELS(name, bits, _shift)             \
 209 static struct iio_chan_spec name[] = {                          \
 210                 AD5868_CHANNEL(0, 0, bits, _shift),             \
 211 }
 212 
 213 #define DECLARE_AD5686_CHANNELS(name, bits, _shift)             \
 214 static struct iio_chan_spec name[] = {                          \
 215                 AD5868_CHANNEL(0, 1, bits, _shift),             \
 216                 AD5868_CHANNEL(1, 2, bits, _shift),             \
 217                 AD5868_CHANNEL(2, 4, bits, _shift),             \
 218                 AD5868_CHANNEL(3, 8, bits, _shift),             \
 219 }
 220 
 221 #define DECLARE_AD5676_CHANNELS(name, bits, _shift)             \
 222 static struct iio_chan_spec name[] = {                          \
 223                 AD5868_CHANNEL(0, 0, bits, _shift),             \
 224                 AD5868_CHANNEL(1, 1, bits, _shift),             \
 225                 AD5868_CHANNEL(2, 2, bits, _shift),             \
 226                 AD5868_CHANNEL(3, 3, bits, _shift),             \
 227                 AD5868_CHANNEL(4, 4, bits, _shift),             \
 228                 AD5868_CHANNEL(5, 5, bits, _shift),             \
 229                 AD5868_CHANNEL(6, 6, bits, _shift),             \
 230                 AD5868_CHANNEL(7, 7, bits, _shift),             \
 231 }
 232 
 233 #define DECLARE_AD5679_CHANNELS(name, bits, _shift)             \
 234 static struct iio_chan_spec name[] = {                          \
 235                 AD5868_CHANNEL(0, 0, bits, _shift),             \
 236                 AD5868_CHANNEL(1, 1, bits, _shift),             \
 237                 AD5868_CHANNEL(2, 2, bits, _shift),             \
 238                 AD5868_CHANNEL(3, 3, bits, _shift),             \
 239                 AD5868_CHANNEL(4, 4, bits, _shift),             \
 240                 AD5868_CHANNEL(5, 5, bits, _shift),             \
 241                 AD5868_CHANNEL(6, 6, bits, _shift),             \
 242                 AD5868_CHANNEL(7, 7, bits, _shift),             \
 243                 AD5868_CHANNEL(8, 8, bits, _shift),             \
 244                 AD5868_CHANNEL(9, 9, bits, _shift),             \
 245                 AD5868_CHANNEL(10, 10, bits, _shift),           \
 246                 AD5868_CHANNEL(11, 11, bits, _shift),           \
 247                 AD5868_CHANNEL(12, 12, bits, _shift),           \
 248                 AD5868_CHANNEL(13, 13, bits, _shift),           \
 249                 AD5868_CHANNEL(14, 14, bits, _shift),           \
 250                 AD5868_CHANNEL(15, 15, bits, _shift),           \
 251 }
 252 
 253 DECLARE_AD5693_CHANNELS(ad5310r_channels, 10, 2);
 254 DECLARE_AD5693_CHANNELS(ad5311r_channels, 10, 6);
 255 DECLARE_AD5676_CHANNELS(ad5672_channels, 12, 4);
 256 DECLARE_AD5679_CHANNELS(ad5674r_channels, 12, 4);
 257 DECLARE_AD5676_CHANNELS(ad5676_channels, 16, 0);
 258 DECLARE_AD5679_CHANNELS(ad5679r_channels, 16, 0);
 259 DECLARE_AD5686_CHANNELS(ad5684_channels, 12, 4);
 260 DECLARE_AD5686_CHANNELS(ad5685r_channels, 14, 2);
 261 DECLARE_AD5686_CHANNELS(ad5686_channels, 16, 0);
 262 DECLARE_AD5693_CHANNELS(ad5693_channels, 16, 0);
 263 DECLARE_AD5693_CHANNELS(ad5692r_channels, 14, 2);
 264 DECLARE_AD5693_CHANNELS(ad5691r_channels, 12, 4);
 265 
 266 static const struct ad5686_chip_info ad5686_chip_info_tbl[] = {
 267         [ID_AD5310R] = {
 268                 .channels = ad5310r_channels,
 269                 .int_vref_mv = 2500,
 270                 .num_channels = 1,
 271                 .regmap_type = AD5310_REGMAP,
 272         },
 273         [ID_AD5311R] = {
 274                 .channels = ad5311r_channels,
 275                 .int_vref_mv = 2500,
 276                 .num_channels = 1,
 277                 .regmap_type = AD5693_REGMAP,
 278         },
 279         [ID_AD5671R] = {
 280                 .channels = ad5672_channels,
 281                 .int_vref_mv = 2500,
 282                 .num_channels = 8,
 283                 .regmap_type = AD5686_REGMAP,
 284         },
 285         [ID_AD5672R] = {
 286                 .channels = ad5672_channels,
 287                 .int_vref_mv = 2500,
 288                 .num_channels = 8,
 289                 .regmap_type = AD5686_REGMAP,
 290         },
 291         [ID_AD5674R] = {
 292                 .channels = ad5674r_channels,
 293                 .int_vref_mv = 2500,
 294                 .num_channels = 16,
 295                 .regmap_type = AD5686_REGMAP,
 296         },
 297         [ID_AD5675R] = {
 298                 .channels = ad5676_channels,
 299                 .int_vref_mv = 2500,
 300                 .num_channels = 8,
 301                 .regmap_type = AD5686_REGMAP,
 302         },
 303         [ID_AD5676] = {
 304                 .channels = ad5676_channels,
 305                 .num_channels = 8,
 306                 .regmap_type = AD5686_REGMAP,
 307         },
 308         [ID_AD5676R] = {
 309                 .channels = ad5676_channels,
 310                 .int_vref_mv = 2500,
 311                 .num_channels = 8,
 312                 .regmap_type = AD5686_REGMAP,
 313         },
 314         [ID_AD5679R] = {
 315                 .channels = ad5679r_channels,
 316                 .int_vref_mv = 2500,
 317                 .num_channels = 16,
 318                 .regmap_type = AD5686_REGMAP,
 319         },
 320         [ID_AD5681R] = {
 321                 .channels = ad5691r_channels,
 322                 .int_vref_mv = 2500,
 323                 .num_channels = 1,
 324                 .regmap_type = AD5683_REGMAP,
 325         },
 326         [ID_AD5682R] = {
 327                 .channels = ad5692r_channels,
 328                 .int_vref_mv = 2500,
 329                 .num_channels = 1,
 330                 .regmap_type = AD5683_REGMAP,
 331         },
 332         [ID_AD5683] = {
 333                 .channels = ad5693_channels,
 334                 .num_channels = 1,
 335                 .regmap_type = AD5683_REGMAP,
 336         },
 337         [ID_AD5683R] = {
 338                 .channels = ad5693_channels,
 339                 .int_vref_mv = 2500,
 340                 .num_channels = 1,
 341                 .regmap_type = AD5683_REGMAP,
 342         },
 343         [ID_AD5684] = {
 344                 .channels = ad5684_channels,
 345                 .num_channels = 4,
 346                 .regmap_type = AD5686_REGMAP,
 347         },
 348         [ID_AD5684R] = {
 349                 .channels = ad5684_channels,
 350                 .int_vref_mv = 2500,
 351                 .num_channels = 4,
 352                 .regmap_type = AD5686_REGMAP,
 353         },
 354         [ID_AD5685R] = {
 355                 .channels = ad5685r_channels,
 356                 .int_vref_mv = 2500,
 357                 .num_channels = 4,
 358                 .regmap_type = AD5686_REGMAP,
 359         },
 360         [ID_AD5686] = {
 361                 .channels = ad5686_channels,
 362                 .num_channels = 4,
 363                 .regmap_type = AD5686_REGMAP,
 364         },
 365         [ID_AD5686R] = {
 366                 .channels = ad5686_channels,
 367                 .int_vref_mv = 2500,
 368                 .num_channels = 4,
 369                 .regmap_type = AD5686_REGMAP,
 370         },
 371         [ID_AD5691R] = {
 372                 .channels = ad5691r_channels,
 373                 .int_vref_mv = 2500,
 374                 .num_channels = 1,
 375                 .regmap_type = AD5693_REGMAP,
 376         },
 377         [ID_AD5692R] = {
 378                 .channels = ad5692r_channels,
 379                 .int_vref_mv = 2500,
 380                 .num_channels = 1,
 381                 .regmap_type = AD5693_REGMAP,
 382         },
 383         [ID_AD5693] = {
 384                 .channels = ad5693_channels,
 385                 .num_channels = 1,
 386                 .regmap_type = AD5693_REGMAP,
 387         },
 388         [ID_AD5693R] = {
 389                 .channels = ad5693_channels,
 390                 .int_vref_mv = 2500,
 391                 .num_channels = 1,
 392                 .regmap_type = AD5693_REGMAP,
 393         },
 394         [ID_AD5694] = {
 395                 .channels = ad5684_channels,
 396                 .num_channels = 4,
 397                 .regmap_type = AD5686_REGMAP,
 398         },
 399         [ID_AD5694R] = {
 400                 .channels = ad5684_channels,
 401                 .int_vref_mv = 2500,
 402                 .num_channels = 4,
 403                 .regmap_type = AD5686_REGMAP,
 404         },
 405         [ID_AD5696] = {
 406                 .channels = ad5686_channels,
 407                 .num_channels = 4,
 408                 .regmap_type = AD5686_REGMAP,
 409         },
 410         [ID_AD5696R] = {
 411                 .channels = ad5686_channels,
 412                 .int_vref_mv = 2500,
 413                 .num_channels = 4,
 414                 .regmap_type = AD5686_REGMAP,
 415         },
 416 };
 417 
 418 int ad5686_probe(struct device *dev,
 419                  enum ad5686_supported_device_ids chip_type,
 420                  const char *name, ad5686_write_func write,
 421                  ad5686_read_func read)
 422 {
 423         struct ad5686_state *st;
 424         struct iio_dev *indio_dev;
 425         unsigned int val, ref_bit_msk;
 426         u8 cmd;
 427         int ret, i, voltage_uv = 0;
 428 
 429         indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
 430         if (indio_dev == NULL)
 431                 return  -ENOMEM;
 432 
 433         st = iio_priv(indio_dev);
 434         dev_set_drvdata(dev, indio_dev);
 435 
 436         st->dev = dev;
 437         st->write = write;
 438         st->read = read;
 439 
 440         st->reg = devm_regulator_get_optional(dev, "vcc");
 441         if (!IS_ERR(st->reg)) {
 442                 ret = regulator_enable(st->reg);
 443                 if (ret)
 444                         return ret;
 445 
 446                 ret = regulator_get_voltage(st->reg);
 447                 if (ret < 0)
 448                         goto error_disable_reg;
 449 
 450                 voltage_uv = ret;
 451         }
 452 
 453         st->chip_info = &ad5686_chip_info_tbl[chip_type];
 454 
 455         if (voltage_uv)
 456                 st->vref_mv = voltage_uv / 1000;
 457         else
 458                 st->vref_mv = st->chip_info->int_vref_mv;
 459 
 460         /* Set all the power down mode for all channels to 1K pulldown */
 461         for (i = 0; i < st->chip_info->num_channels; i++)
 462                 st->pwr_down_mode |= (0x01 << (i * 2));
 463 
 464         indio_dev->dev.parent = dev;
 465         indio_dev->name = name;
 466         indio_dev->info = &ad5686_info;
 467         indio_dev->modes = INDIO_DIRECT_MODE;
 468         indio_dev->channels = st->chip_info->channels;
 469         indio_dev->num_channels = st->chip_info->num_channels;
 470 
 471         switch (st->chip_info->regmap_type) {
 472         case AD5310_REGMAP:
 473                 cmd = AD5686_CMD_CONTROL_REG;
 474                 ref_bit_msk = AD5310_REF_BIT_MSK;
 475                 st->use_internal_vref = !voltage_uv;
 476                 break;
 477         case AD5683_REGMAP:
 478                 cmd = AD5686_CMD_CONTROL_REG;
 479                 ref_bit_msk = AD5683_REF_BIT_MSK;
 480                 st->use_internal_vref = !voltage_uv;
 481                 break;
 482         case AD5686_REGMAP:
 483                 cmd = AD5686_CMD_INTERNAL_REFER_SETUP;
 484                 ref_bit_msk = 0;
 485                 break;
 486         case AD5693_REGMAP:
 487                 cmd = AD5686_CMD_CONTROL_REG;
 488                 ref_bit_msk = AD5693_REF_BIT_MSK;
 489                 st->use_internal_vref = !voltage_uv;
 490                 break;
 491         default:
 492                 ret = -EINVAL;
 493                 goto error_disable_reg;
 494         }
 495 
 496         val = (voltage_uv | ref_bit_msk);
 497 
 498         ret = st->write(st, cmd, 0, !!val);
 499         if (ret)
 500                 goto error_disable_reg;
 501 
 502         ret = iio_device_register(indio_dev);
 503         if (ret)
 504                 goto error_disable_reg;
 505 
 506         return 0;
 507 
 508 error_disable_reg:
 509         if (!IS_ERR(st->reg))
 510                 regulator_disable(st->reg);
 511         return ret;
 512 }
 513 EXPORT_SYMBOL_GPL(ad5686_probe);
 514 
 515 int ad5686_remove(struct device *dev)
 516 {
 517         struct iio_dev *indio_dev = dev_get_drvdata(dev);
 518         struct ad5686_state *st = iio_priv(indio_dev);
 519 
 520         iio_device_unregister(indio_dev);
 521         if (!IS_ERR(st->reg))
 522                 regulator_disable(st->reg);
 523 
 524         return 0;
 525 }
 526 EXPORT_SYMBOL_GPL(ad5686_remove);
 527 
 528 MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 529 MODULE_DESCRIPTION("Analog Devices AD5686/85/84 DAC");
 530 MODULE_LICENSE("GPL v2");

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