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