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