linux/drivers/iio/dac/ad5686.c
<<
>>
Prefs
   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
  22static const char * const ad5686_powerdown_modes[] = {
  23        "1kohm_to_gnd",
  24        "100kohm_to_gnd",
  25        "three_state"
  26};
  27
  28static 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
  36static 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
  48static 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
  55static 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 sysfs_emit(buf, "%d\n", !!(st->pwr_down_mask &
  61                                       (0x3 << (chan->channel * 2))));
  62}
  63
  64static 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
 119static 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(&st->lock);
 131                ret = st->read(st, chan->address);
 132                mutex_unlock(&st->lock);
 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
 146static 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(&st->lock);
 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(&st->lock);
 166                break;
 167        default:
 168                ret = -EINVAL;
 169        }
 170
 171        return ret;
 172}
 173
 174static const struct iio_info ad5686_info = {
 175        .read_raw = ad5686_read_raw,
 176        .write_raw = ad5686_write_raw,
 177};
 178
 179static 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)             \
 209static const struct iio_chan_spec name[] = {                    \
 210                AD5868_CHANNEL(0, 0, bits, _shift),             \
 211}
 212
 213#define DECLARE_AD5338_CHANNELS(name, bits, _shift)             \
 214static const struct iio_chan_spec name[] = {                    \
 215                AD5868_CHANNEL(0, 1, bits, _shift),             \
 216                AD5868_CHANNEL(1, 8, bits, _shift),             \
 217}
 218
 219#define DECLARE_AD5686_CHANNELS(name, bits, _shift)             \
 220static const struct iio_chan_spec name[] = {                    \
 221                AD5868_CHANNEL(0, 1, bits, _shift),             \
 222                AD5868_CHANNEL(1, 2, bits, _shift),             \
 223                AD5868_CHANNEL(2, 4, bits, _shift),             \
 224                AD5868_CHANNEL(3, 8, bits, _shift),             \
 225}
 226
 227#define DECLARE_AD5676_CHANNELS(name, bits, _shift)             \
 228static const struct iio_chan_spec name[] = {                    \
 229                AD5868_CHANNEL(0, 0, bits, _shift),             \
 230                AD5868_CHANNEL(1, 1, bits, _shift),             \
 231                AD5868_CHANNEL(2, 2, bits, _shift),             \
 232                AD5868_CHANNEL(3, 3, bits, _shift),             \
 233                AD5868_CHANNEL(4, 4, bits, _shift),             \
 234                AD5868_CHANNEL(5, 5, bits, _shift),             \
 235                AD5868_CHANNEL(6, 6, bits, _shift),             \
 236                AD5868_CHANNEL(7, 7, bits, _shift),             \
 237}
 238
 239#define DECLARE_AD5679_CHANNELS(name, bits, _shift)             \
 240static const struct iio_chan_spec name[] = {                    \
 241                AD5868_CHANNEL(0, 0, bits, _shift),             \
 242                AD5868_CHANNEL(1, 1, bits, _shift),             \
 243                AD5868_CHANNEL(2, 2, bits, _shift),             \
 244                AD5868_CHANNEL(3, 3, bits, _shift),             \
 245                AD5868_CHANNEL(4, 4, bits, _shift),             \
 246                AD5868_CHANNEL(5, 5, bits, _shift),             \
 247                AD5868_CHANNEL(6, 6, bits, _shift),             \
 248                AD5868_CHANNEL(7, 7, bits, _shift),             \
 249                AD5868_CHANNEL(8, 8, bits, _shift),             \
 250                AD5868_CHANNEL(9, 9, bits, _shift),             \
 251                AD5868_CHANNEL(10, 10, bits, _shift),           \
 252                AD5868_CHANNEL(11, 11, bits, _shift),           \
 253                AD5868_CHANNEL(12, 12, bits, _shift),           \
 254                AD5868_CHANNEL(13, 13, bits, _shift),           \
 255                AD5868_CHANNEL(14, 14, bits, _shift),           \
 256                AD5868_CHANNEL(15, 15, bits, _shift),           \
 257}
 258
 259DECLARE_AD5693_CHANNELS(ad5310r_channels, 10, 2);
 260DECLARE_AD5693_CHANNELS(ad5311r_channels, 10, 6);
 261DECLARE_AD5338_CHANNELS(ad5338r_channels, 10, 6);
 262DECLARE_AD5676_CHANNELS(ad5672_channels, 12, 4);
 263DECLARE_AD5679_CHANNELS(ad5674r_channels, 12, 4);
 264DECLARE_AD5676_CHANNELS(ad5676_channels, 16, 0);
 265DECLARE_AD5679_CHANNELS(ad5679r_channels, 16, 0);
 266DECLARE_AD5686_CHANNELS(ad5684_channels, 12, 4);
 267DECLARE_AD5686_CHANNELS(ad5685r_channels, 14, 2);
 268DECLARE_AD5686_CHANNELS(ad5686_channels, 16, 0);
 269DECLARE_AD5693_CHANNELS(ad5693_channels, 16, 0);
 270DECLARE_AD5693_CHANNELS(ad5692r_channels, 14, 2);
 271DECLARE_AD5693_CHANNELS(ad5691r_channels, 12, 4);
 272
 273static const struct ad5686_chip_info ad5686_chip_info_tbl[] = {
 274        [ID_AD5310R] = {
 275                .channels = ad5310r_channels,
 276                .int_vref_mv = 2500,
 277                .num_channels = 1,
 278                .regmap_type = AD5310_REGMAP,
 279        },
 280        [ID_AD5311R] = {
 281                .channels = ad5311r_channels,
 282                .int_vref_mv = 2500,
 283                .num_channels = 1,
 284                .regmap_type = AD5693_REGMAP,
 285        },
 286        [ID_AD5338R] = {
 287                .channels = ad5338r_channels,
 288                .int_vref_mv = 2500,
 289                .num_channels = 2,
 290                .regmap_type = AD5686_REGMAP,
 291        },
 292        [ID_AD5671R] = {
 293                .channels = ad5672_channels,
 294                .int_vref_mv = 2500,
 295                .num_channels = 8,
 296                .regmap_type = AD5686_REGMAP,
 297        },
 298        [ID_AD5672R] = {
 299                .channels = ad5672_channels,
 300                .int_vref_mv = 2500,
 301                .num_channels = 8,
 302                .regmap_type = AD5686_REGMAP,
 303        },
 304        [ID_AD5673R] = {
 305                .channels = ad5674r_channels,
 306                .int_vref_mv = 2500,
 307                .num_channels = 16,
 308                .regmap_type = AD5686_REGMAP,
 309        },
 310        [ID_AD5674R] = {
 311                .channels = ad5674r_channels,
 312                .int_vref_mv = 2500,
 313                .num_channels = 16,
 314                .regmap_type = AD5686_REGMAP,
 315        },
 316        [ID_AD5675R] = {
 317                .channels = ad5676_channels,
 318                .int_vref_mv = 2500,
 319                .num_channels = 8,
 320                .regmap_type = AD5686_REGMAP,
 321        },
 322        [ID_AD5676] = {
 323                .channels = ad5676_channels,
 324                .num_channels = 8,
 325                .regmap_type = AD5686_REGMAP,
 326        },
 327        [ID_AD5676R] = {
 328                .channels = ad5676_channels,
 329                .int_vref_mv = 2500,
 330                .num_channels = 8,
 331                .regmap_type = AD5686_REGMAP,
 332        },
 333        [ID_AD5677R] = {
 334                .channels = ad5679r_channels,
 335                .int_vref_mv = 2500,
 336                .num_channels = 16,
 337                .regmap_type = AD5686_REGMAP,
 338        },
 339        [ID_AD5679R] = {
 340                .channels = ad5679r_channels,
 341                .int_vref_mv = 2500,
 342                .num_channels = 16,
 343                .regmap_type = AD5686_REGMAP,
 344        },
 345        [ID_AD5681R] = {
 346                .channels = ad5691r_channels,
 347                .int_vref_mv = 2500,
 348                .num_channels = 1,
 349                .regmap_type = AD5683_REGMAP,
 350        },
 351        [ID_AD5682R] = {
 352                .channels = ad5692r_channels,
 353                .int_vref_mv = 2500,
 354                .num_channels = 1,
 355                .regmap_type = AD5683_REGMAP,
 356        },
 357        [ID_AD5683] = {
 358                .channels = ad5693_channels,
 359                .num_channels = 1,
 360                .regmap_type = AD5683_REGMAP,
 361        },
 362        [ID_AD5683R] = {
 363                .channels = ad5693_channels,
 364                .int_vref_mv = 2500,
 365                .num_channels = 1,
 366                .regmap_type = AD5683_REGMAP,
 367        },
 368        [ID_AD5684] = {
 369                .channels = ad5684_channels,
 370                .num_channels = 4,
 371                .regmap_type = AD5686_REGMAP,
 372        },
 373        [ID_AD5684R] = {
 374                .channels = ad5684_channels,
 375                .int_vref_mv = 2500,
 376                .num_channels = 4,
 377                .regmap_type = AD5686_REGMAP,
 378        },
 379        [ID_AD5685R] = {
 380                .channels = ad5685r_channels,
 381                .int_vref_mv = 2500,
 382                .num_channels = 4,
 383                .regmap_type = AD5686_REGMAP,
 384        },
 385        [ID_AD5686] = {
 386                .channels = ad5686_channels,
 387                .num_channels = 4,
 388                .regmap_type = AD5686_REGMAP,
 389        },
 390        [ID_AD5686R] = {
 391                .channels = ad5686_channels,
 392                .int_vref_mv = 2500,
 393                .num_channels = 4,
 394                .regmap_type = AD5686_REGMAP,
 395        },
 396        [ID_AD5691R] = {
 397                .channels = ad5691r_channels,
 398                .int_vref_mv = 2500,
 399                .num_channels = 1,
 400                .regmap_type = AD5693_REGMAP,
 401        },
 402        [ID_AD5692R] = {
 403                .channels = ad5692r_channels,
 404                .int_vref_mv = 2500,
 405                .num_channels = 1,
 406                .regmap_type = AD5693_REGMAP,
 407        },
 408        [ID_AD5693] = {
 409                .channels = ad5693_channels,
 410                .num_channels = 1,
 411                .regmap_type = AD5693_REGMAP,
 412        },
 413        [ID_AD5693R] = {
 414                .channels = ad5693_channels,
 415                .int_vref_mv = 2500,
 416                .num_channels = 1,
 417                .regmap_type = AD5693_REGMAP,
 418        },
 419        [ID_AD5694] = {
 420                .channels = ad5684_channels,
 421                .num_channels = 4,
 422                .regmap_type = AD5686_REGMAP,
 423        },
 424        [ID_AD5694R] = {
 425                .channels = ad5684_channels,
 426                .int_vref_mv = 2500,
 427                .num_channels = 4,
 428                .regmap_type = AD5686_REGMAP,
 429        },
 430        [ID_AD5696] = {
 431                .channels = ad5686_channels,
 432                .num_channels = 4,
 433                .regmap_type = AD5686_REGMAP,
 434        },
 435        [ID_AD5696R] = {
 436                .channels = ad5686_channels,
 437                .int_vref_mv = 2500,
 438                .num_channels = 4,
 439                .regmap_type = AD5686_REGMAP,
 440        },
 441};
 442
 443int ad5686_probe(struct device *dev,
 444                 enum ad5686_supported_device_ids chip_type,
 445                 const char *name, ad5686_write_func write,
 446                 ad5686_read_func read)
 447{
 448        struct ad5686_state *st;
 449        struct iio_dev *indio_dev;
 450        unsigned int val, ref_bit_msk;
 451        u8 cmd;
 452        int ret, i, voltage_uv = 0;
 453
 454        indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
 455        if (indio_dev == NULL)
 456                return  -ENOMEM;
 457
 458        st = iio_priv(indio_dev);
 459        dev_set_drvdata(dev, indio_dev);
 460
 461        st->dev = dev;
 462        st->write = write;
 463        st->read = read;
 464
 465        st->reg = devm_regulator_get_optional(dev, "vcc");
 466        if (!IS_ERR(st->reg)) {
 467                ret = regulator_enable(st->reg);
 468                if (ret)
 469                        return ret;
 470
 471                ret = regulator_get_voltage(st->reg);
 472                if (ret < 0)
 473                        goto error_disable_reg;
 474
 475                voltage_uv = ret;
 476        }
 477
 478        st->chip_info = &ad5686_chip_info_tbl[chip_type];
 479
 480        if (voltage_uv)
 481                st->vref_mv = voltage_uv / 1000;
 482        else
 483                st->vref_mv = st->chip_info->int_vref_mv;
 484
 485        /* Set all the power down mode for all channels to 1K pulldown */
 486        for (i = 0; i < st->chip_info->num_channels; i++)
 487                st->pwr_down_mode |= (0x01 << (i * 2));
 488
 489        indio_dev->name = name;
 490        indio_dev->info = &ad5686_info;
 491        indio_dev->modes = INDIO_DIRECT_MODE;
 492        indio_dev->channels = st->chip_info->channels;
 493        indio_dev->num_channels = st->chip_info->num_channels;
 494
 495        mutex_init(&st->lock);
 496
 497        switch (st->chip_info->regmap_type) {
 498        case AD5310_REGMAP:
 499                cmd = AD5686_CMD_CONTROL_REG;
 500                ref_bit_msk = AD5310_REF_BIT_MSK;
 501                st->use_internal_vref = !voltage_uv;
 502                break;
 503        case AD5683_REGMAP:
 504                cmd = AD5686_CMD_CONTROL_REG;
 505                ref_bit_msk = AD5683_REF_BIT_MSK;
 506                st->use_internal_vref = !voltage_uv;
 507                break;
 508        case AD5686_REGMAP:
 509                cmd = AD5686_CMD_INTERNAL_REFER_SETUP;
 510                ref_bit_msk = 0;
 511                break;
 512        case AD5693_REGMAP:
 513                cmd = AD5686_CMD_CONTROL_REG;
 514                ref_bit_msk = AD5693_REF_BIT_MSK;
 515                st->use_internal_vref = !voltage_uv;
 516                break;
 517        default:
 518                ret = -EINVAL;
 519                goto error_disable_reg;
 520        }
 521
 522        val = (voltage_uv | ref_bit_msk);
 523
 524        ret = st->write(st, cmd, 0, !!val);
 525        if (ret)
 526                goto error_disable_reg;
 527
 528        ret = iio_device_register(indio_dev);
 529        if (ret)
 530                goto error_disable_reg;
 531
 532        return 0;
 533
 534error_disable_reg:
 535        if (!IS_ERR(st->reg))
 536                regulator_disable(st->reg);
 537        return ret;
 538}
 539EXPORT_SYMBOL_GPL(ad5686_probe);
 540
 541int ad5686_remove(struct device *dev)
 542{
 543        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 544        struct ad5686_state *st = iio_priv(indio_dev);
 545
 546        iio_device_unregister(indio_dev);
 547        if (!IS_ERR(st->reg))
 548                regulator_disable(st->reg);
 549
 550        return 0;
 551}
 552EXPORT_SYMBOL_GPL(ad5686_remove);
 553
 554MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 555MODULE_DESCRIPTION("Analog Devices AD5686/85/84 DAC");
 556MODULE_LICENSE("GPL v2");
 557