linux/drivers/iio/dac/ad5791.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * AD5760, AD5780, AD5781, AD5790, AD5791 Voltage Output Digital to Analog
   4 * Converter
   5 *
   6 * Copyright 2011 Analog Devices Inc.
   7 */
   8
   9#include <linux/interrupt.h>
  10#include <linux/fs.h>
  11#include <linux/device.h>
  12#include <linux/kernel.h>
  13#include <linux/spi/spi.h>
  14#include <linux/slab.h>
  15#include <linux/sysfs.h>
  16#include <linux/regulator/consumer.h>
  17#include <linux/module.h>
  18#include <linux/bitops.h>
  19
  20#include <linux/iio/iio.h>
  21#include <linux/iio/sysfs.h>
  22#include <linux/iio/dac/ad5791.h>
  23
  24#define AD5791_DAC_MASK                 GENMASK(19, 0)
  25
  26#define AD5791_CMD_READ                 BIT(23)
  27#define AD5791_CMD_WRITE                0
  28#define AD5791_ADDR(addr)               ((addr) << 20)
  29
  30/* Registers */
  31#define AD5791_ADDR_NOOP                0
  32#define AD5791_ADDR_DAC0                1
  33#define AD5791_ADDR_CTRL                2
  34#define AD5791_ADDR_CLRCODE             3
  35#define AD5791_ADDR_SW_CTRL             4
  36
  37/* Control Register */
  38#define AD5791_CTRL_RBUF                BIT(1)
  39#define AD5791_CTRL_OPGND               BIT(2)
  40#define AD5791_CTRL_DACTRI              BIT(3)
  41#define AD5791_CTRL_BIN2SC              BIT(4)
  42#define AD5791_CTRL_SDODIS              BIT(5)
  43#define AD5761_CTRL_LINCOMP(x)          ((x) << 6)
  44
  45#define AD5791_LINCOMP_0_10             0
  46#define AD5791_LINCOMP_10_12            1
  47#define AD5791_LINCOMP_12_16            2
  48#define AD5791_LINCOMP_16_19            3
  49#define AD5791_LINCOMP_19_20            12
  50
  51#define AD5780_LINCOMP_0_10             0
  52#define AD5780_LINCOMP_10_20            12
  53
  54/* Software Control Register */
  55#define AD5791_SWCTRL_LDAC              BIT(0)
  56#define AD5791_SWCTRL_CLR               BIT(1)
  57#define AD5791_SWCTRL_RESET             BIT(2)
  58
  59#define AD5791_DAC_PWRDN_6K             0
  60#define AD5791_DAC_PWRDN_3STATE         1
  61
  62/**
  63 * struct ad5791_chip_info - chip specific information
  64 * @get_lin_comp:       function pointer to the device specific function
  65 */
  66
  67struct ad5791_chip_info {
  68        int (*get_lin_comp)     (unsigned int span);
  69};
  70
  71/**
  72 * struct ad5791_state - driver instance specific data
  73 * @spi:                        spi_device
  74 * @reg_vdd:            positive supply regulator
  75 * @reg_vss:            negative supply regulator
  76 * @chip_info:          chip model specific constants
  77 * @vref_mv:            actual reference voltage used
  78 * @vref_neg_mv:        voltage of the negative supply
  79 * @ctrl:               control register cache
  80 * @pwr_down_mode:      current power down mode
  81 * @pwr_down:           true if device is powered down
  82 * @data:               spi transfer buffers
  83 */
  84struct ad5791_state {
  85        struct spi_device               *spi;
  86        struct regulator                *reg_vdd;
  87        struct regulator                *reg_vss;
  88        const struct ad5791_chip_info   *chip_info;
  89        unsigned short                  vref_mv;
  90        unsigned int                    vref_neg_mv;
  91        unsigned                        ctrl;
  92        unsigned                        pwr_down_mode;
  93        bool                            pwr_down;
  94
  95        union {
  96                __be32 d32;
  97                u8 d8[4];
  98        } data[3] ____cacheline_aligned;
  99};
 100
 101enum ad5791_supported_device_ids {
 102        ID_AD5760,
 103        ID_AD5780,
 104        ID_AD5781,
 105        ID_AD5791,
 106};
 107
 108static int ad5791_spi_write(struct ad5791_state *st, u8 addr, u32 val)
 109{
 110        st->data[0].d32 = cpu_to_be32(AD5791_CMD_WRITE |
 111                              AD5791_ADDR(addr) |
 112                              (val & AD5791_DAC_MASK));
 113
 114        return spi_write(st->spi, &st->data[0].d8[1], 3);
 115}
 116
 117static int ad5791_spi_read(struct ad5791_state *st, u8 addr, u32 *val)
 118{
 119        int ret;
 120        struct spi_transfer xfers[] = {
 121                {
 122                        .tx_buf = &st->data[0].d8[1],
 123                        .bits_per_word = 8,
 124                        .len = 3,
 125                        .cs_change = 1,
 126                }, {
 127                        .tx_buf = &st->data[1].d8[1],
 128                        .rx_buf = &st->data[2].d8[1],
 129                        .bits_per_word = 8,
 130                        .len = 3,
 131                },
 132        };
 133
 134        st->data[0].d32 = cpu_to_be32(AD5791_CMD_READ |
 135                              AD5791_ADDR(addr));
 136        st->data[1].d32 = cpu_to_be32(AD5791_ADDR(AD5791_ADDR_NOOP));
 137
 138        ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
 139
 140        *val = be32_to_cpu(st->data[2].d32);
 141
 142        return ret;
 143}
 144
 145static const char * const ad5791_powerdown_modes[] = {
 146        "6kohm_to_gnd",
 147        "three_state",
 148};
 149
 150static int ad5791_get_powerdown_mode(struct iio_dev *indio_dev,
 151        const struct iio_chan_spec *chan)
 152{
 153        struct ad5791_state *st = iio_priv(indio_dev);
 154
 155        return st->pwr_down_mode;
 156}
 157
 158static int ad5791_set_powerdown_mode(struct iio_dev *indio_dev,
 159        const struct iio_chan_spec *chan, unsigned int mode)
 160{
 161        struct ad5791_state *st = iio_priv(indio_dev);
 162
 163        st->pwr_down_mode = mode;
 164
 165        return 0;
 166}
 167
 168static const struct iio_enum ad5791_powerdown_mode_enum = {
 169        .items = ad5791_powerdown_modes,
 170        .num_items = ARRAY_SIZE(ad5791_powerdown_modes),
 171        .get = ad5791_get_powerdown_mode,
 172        .set = ad5791_set_powerdown_mode,
 173};
 174
 175static ssize_t ad5791_read_dac_powerdown(struct iio_dev *indio_dev,
 176        uintptr_t private, const struct iio_chan_spec *chan, char *buf)
 177{
 178        struct ad5791_state *st = iio_priv(indio_dev);
 179
 180        return sysfs_emit(buf, "%d\n", st->pwr_down);
 181}
 182
 183static ssize_t ad5791_write_dac_powerdown(struct iio_dev *indio_dev,
 184         uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
 185         size_t len)
 186{
 187        bool pwr_down;
 188        int ret;
 189        struct ad5791_state *st = iio_priv(indio_dev);
 190
 191        ret = strtobool(buf, &pwr_down);
 192        if (ret)
 193                return ret;
 194
 195        if (!pwr_down) {
 196                st->ctrl &= ~(AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI);
 197        } else {
 198                if (st->pwr_down_mode == AD5791_DAC_PWRDN_6K)
 199                        st->ctrl |= AD5791_CTRL_OPGND;
 200                else if (st->pwr_down_mode == AD5791_DAC_PWRDN_3STATE)
 201                        st->ctrl |= AD5791_CTRL_DACTRI;
 202        }
 203        st->pwr_down = pwr_down;
 204
 205        ret = ad5791_spi_write(st, AD5791_ADDR_CTRL, st->ctrl);
 206
 207        return ret ? ret : len;
 208}
 209
 210static int ad5791_get_lin_comp(unsigned int span)
 211{
 212        if (span <= 10000)
 213                return AD5791_LINCOMP_0_10;
 214        else if (span <= 12000)
 215                return AD5791_LINCOMP_10_12;
 216        else if (span <= 16000)
 217                return AD5791_LINCOMP_12_16;
 218        else if (span <= 19000)
 219                return AD5791_LINCOMP_16_19;
 220        else
 221                return AD5791_LINCOMP_19_20;
 222}
 223
 224static int ad5780_get_lin_comp(unsigned int span)
 225{
 226        if (span <= 10000)
 227                return AD5780_LINCOMP_0_10;
 228        else
 229                return AD5780_LINCOMP_10_20;
 230}
 231static const struct ad5791_chip_info ad5791_chip_info_tbl[] = {
 232        [ID_AD5760] = {
 233                .get_lin_comp = ad5780_get_lin_comp,
 234        },
 235        [ID_AD5780] = {
 236                .get_lin_comp = ad5780_get_lin_comp,
 237        },
 238        [ID_AD5781] = {
 239                .get_lin_comp = ad5791_get_lin_comp,
 240        },
 241        [ID_AD5791] = {
 242                .get_lin_comp = ad5791_get_lin_comp,
 243        },
 244};
 245
 246static int ad5791_read_raw(struct iio_dev *indio_dev,
 247                           struct iio_chan_spec const *chan,
 248                           int *val,
 249                           int *val2,
 250                           long m)
 251{
 252        struct ad5791_state *st = iio_priv(indio_dev);
 253        u64 val64;
 254        int ret;
 255
 256        switch (m) {
 257        case IIO_CHAN_INFO_RAW:
 258                ret = ad5791_spi_read(st, chan->address, val);
 259                if (ret)
 260                        return ret;
 261                *val &= AD5791_DAC_MASK;
 262                *val >>= chan->scan_type.shift;
 263                return IIO_VAL_INT;
 264        case IIO_CHAN_INFO_SCALE:
 265                *val = st->vref_mv;
 266                *val2 = (1 << chan->scan_type.realbits) - 1;
 267                return IIO_VAL_FRACTIONAL;
 268        case IIO_CHAN_INFO_OFFSET:
 269                val64 = (((u64)st->vref_neg_mv) << chan->scan_type.realbits);
 270                do_div(val64, st->vref_mv);
 271                *val = -val64;
 272                return IIO_VAL_INT;
 273        default:
 274                return -EINVAL;
 275        }
 276
 277};
 278
 279static const struct iio_chan_spec_ext_info ad5791_ext_info[] = {
 280        {
 281                .name = "powerdown",
 282                .shared = IIO_SHARED_BY_TYPE,
 283                .read = ad5791_read_dac_powerdown,
 284                .write = ad5791_write_dac_powerdown,
 285        },
 286        IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
 287                 &ad5791_powerdown_mode_enum),
 288        IIO_ENUM_AVAILABLE("powerdown_mode", &ad5791_powerdown_mode_enum),
 289        { },
 290};
 291
 292#define AD5791_CHAN(bits, _shift) {                     \
 293        .type = IIO_VOLTAGE,                            \
 294        .output = 1,                                    \
 295        .indexed = 1,                                   \
 296        .address = AD5791_ADDR_DAC0,                    \
 297        .channel = 0,                                   \
 298        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
 299        .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |  \
 300                BIT(IIO_CHAN_INFO_OFFSET),              \
 301        .scan_type = {                                  \
 302                .sign = 'u',                            \
 303                .realbits = (bits),                     \
 304                .storagebits = 24,                      \
 305                .shift = (_shift),                      \
 306        },                                              \
 307        .ext_info = ad5791_ext_info,                    \
 308}
 309
 310static const struct iio_chan_spec ad5791_channels[] = {
 311        [ID_AD5760] = AD5791_CHAN(16, 4),
 312        [ID_AD5780] = AD5791_CHAN(18, 2),
 313        [ID_AD5781] = AD5791_CHAN(18, 2),
 314        [ID_AD5791] = AD5791_CHAN(20, 0)
 315};
 316
 317static int ad5791_write_raw(struct iio_dev *indio_dev,
 318                            struct iio_chan_spec const *chan,
 319                            int val,
 320                            int val2,
 321                            long mask)
 322{
 323        struct ad5791_state *st = iio_priv(indio_dev);
 324
 325        switch (mask) {
 326        case IIO_CHAN_INFO_RAW:
 327                val &= GENMASK(chan->scan_type.realbits - 1, 0);
 328                val <<= chan->scan_type.shift;
 329
 330                return ad5791_spi_write(st, chan->address, val);
 331
 332        default:
 333                return -EINVAL;
 334        }
 335}
 336
 337static const struct iio_info ad5791_info = {
 338        .read_raw = &ad5791_read_raw,
 339        .write_raw = &ad5791_write_raw,
 340};
 341
 342static int ad5791_probe(struct spi_device *spi)
 343{
 344        struct ad5791_platform_data *pdata = spi->dev.platform_data;
 345        struct iio_dev *indio_dev;
 346        struct ad5791_state *st;
 347        int ret, pos_voltage_uv = 0, neg_voltage_uv = 0;
 348
 349        indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 350        if (!indio_dev)
 351                return -ENOMEM;
 352        st = iio_priv(indio_dev);
 353        st->reg_vdd = devm_regulator_get(&spi->dev, "vdd");
 354        if (!IS_ERR(st->reg_vdd)) {
 355                ret = regulator_enable(st->reg_vdd);
 356                if (ret)
 357                        return ret;
 358
 359                ret = regulator_get_voltage(st->reg_vdd);
 360                if (ret < 0)
 361                        goto error_disable_reg_pos;
 362
 363                pos_voltage_uv = ret;
 364        }
 365
 366        st->reg_vss = devm_regulator_get(&spi->dev, "vss");
 367        if (!IS_ERR(st->reg_vss)) {
 368                ret = regulator_enable(st->reg_vss);
 369                if (ret)
 370                        goto error_disable_reg_pos;
 371
 372                ret = regulator_get_voltage(st->reg_vss);
 373                if (ret < 0)
 374                        goto error_disable_reg_neg;
 375
 376                neg_voltage_uv = ret;
 377        }
 378
 379        st->pwr_down = true;
 380        st->spi = spi;
 381
 382        if (!IS_ERR(st->reg_vss) && !IS_ERR(st->reg_vdd)) {
 383                st->vref_mv = (pos_voltage_uv + neg_voltage_uv) / 1000;
 384                st->vref_neg_mv = neg_voltage_uv / 1000;
 385        } else if (pdata) {
 386                st->vref_mv = pdata->vref_pos_mv + pdata->vref_neg_mv;
 387                st->vref_neg_mv = pdata->vref_neg_mv;
 388        } else {
 389                dev_warn(&spi->dev, "reference voltage unspecified\n");
 390        }
 391
 392        ret = ad5791_spi_write(st, AD5791_ADDR_SW_CTRL, AD5791_SWCTRL_RESET);
 393        if (ret)
 394                goto error_disable_reg_neg;
 395
 396        st->chip_info = &ad5791_chip_info_tbl[spi_get_device_id(spi)
 397                                              ->driver_data];
 398
 399
 400        st->ctrl = AD5761_CTRL_LINCOMP(st->chip_info->get_lin_comp(st->vref_mv))
 401                  | ((pdata && pdata->use_rbuf_gain2) ? 0 : AD5791_CTRL_RBUF) |
 402                  AD5791_CTRL_BIN2SC;
 403
 404        ret = ad5791_spi_write(st, AD5791_ADDR_CTRL, st->ctrl |
 405                AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI);
 406        if (ret)
 407                goto error_disable_reg_neg;
 408
 409        spi_set_drvdata(spi, indio_dev);
 410        indio_dev->info = &ad5791_info;
 411        indio_dev->modes = INDIO_DIRECT_MODE;
 412        indio_dev->channels
 413                = &ad5791_channels[spi_get_device_id(spi)->driver_data];
 414        indio_dev->num_channels = 1;
 415        indio_dev->name = spi_get_device_id(st->spi)->name;
 416        ret = iio_device_register(indio_dev);
 417        if (ret)
 418                goto error_disable_reg_neg;
 419
 420        return 0;
 421
 422error_disable_reg_neg:
 423        if (!IS_ERR(st->reg_vss))
 424                regulator_disable(st->reg_vss);
 425error_disable_reg_pos:
 426        if (!IS_ERR(st->reg_vdd))
 427                regulator_disable(st->reg_vdd);
 428        return ret;
 429}
 430
 431static int ad5791_remove(struct spi_device *spi)
 432{
 433        struct iio_dev *indio_dev = spi_get_drvdata(spi);
 434        struct ad5791_state *st = iio_priv(indio_dev);
 435
 436        iio_device_unregister(indio_dev);
 437        if (!IS_ERR(st->reg_vdd))
 438                regulator_disable(st->reg_vdd);
 439
 440        if (!IS_ERR(st->reg_vss))
 441                regulator_disable(st->reg_vss);
 442
 443        return 0;
 444}
 445
 446static const struct spi_device_id ad5791_id[] = {
 447        {"ad5760", ID_AD5760},
 448        {"ad5780", ID_AD5780},
 449        {"ad5781", ID_AD5781},
 450        {"ad5790", ID_AD5791},
 451        {"ad5791", ID_AD5791},
 452        {}
 453};
 454MODULE_DEVICE_TABLE(spi, ad5791_id);
 455
 456static struct spi_driver ad5791_driver = {
 457        .driver = {
 458                   .name = "ad5791",
 459                   },
 460        .probe = ad5791_probe,
 461        .remove = ad5791_remove,
 462        .id_table = ad5791_id,
 463};
 464module_spi_driver(ad5791_driver);
 465
 466MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 467MODULE_DESCRIPTION("Analog Devices AD5760/AD5780/AD5781/AD5790/AD5791 DAC");
 468MODULE_LICENSE("GPL v2");
 469