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