linux/drivers/staging/iio/dac/ad5791.c
<<
>>
Prefs
   1/*
   2 * AD5760, AD5780, AD5781, AD5791 Voltage Output Digital to Analog Converter
   3 *
   4 * Copyright 2011 Analog Devices Inc.
   5 *
   6 * Licensed under the GPL-2.
   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
  19#include "../iio.h"
  20#include "../sysfs.h"
  21#include "dac.h"
  22#include "ad5791.h"
  23
  24static int ad5791_spi_write(struct spi_device *spi, u8 addr, u32 val)
  25{
  26        union {
  27                u32 d32;
  28                u8 d8[4];
  29        } data;
  30
  31        data.d32 = cpu_to_be32(AD5791_CMD_WRITE |
  32                              AD5791_ADDR(addr) |
  33                              (val & AD5791_DAC_MASK));
  34
  35        return spi_write(spi, &data.d8[1], 3);
  36}
  37
  38static int ad5791_spi_read(struct spi_device *spi, u8 addr, u32 *val)
  39{
  40        union {
  41                u32 d32;
  42                u8 d8[4];
  43        } data[3];
  44        int ret;
  45        struct spi_message msg;
  46        struct spi_transfer xfers[] = {
  47                {
  48                        .tx_buf = &data[0].d8[1],
  49                        .bits_per_word = 8,
  50                        .len = 3,
  51                        .cs_change = 1,
  52                }, {
  53                        .tx_buf = &data[1].d8[1],
  54                        .rx_buf = &data[2].d8[1],
  55                        .bits_per_word = 8,
  56                        .len = 3,
  57                },
  58        };
  59
  60        data[0].d32 = cpu_to_be32(AD5791_CMD_READ |
  61                              AD5791_ADDR(addr));
  62        data[1].d32 = cpu_to_be32(AD5791_ADDR(AD5791_ADDR_NOOP));
  63
  64        spi_message_init(&msg);
  65        spi_message_add_tail(&xfers[0], &msg);
  66        spi_message_add_tail(&xfers[1], &msg);
  67        ret = spi_sync(spi, &msg);
  68
  69        *val = be32_to_cpu(data[2].d32);
  70
  71        return ret;
  72}
  73
  74#define AD5791_CHAN(bits, shift) {                      \
  75        .type = IIO_VOLTAGE,                            \
  76        .output = 1,                                    \
  77        .indexed = 1,                                   \
  78        .address = AD5791_ADDR_DAC0,                    \
  79        .channel = 0,                                   \
  80        .info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED) | \
  81                (1 << IIO_CHAN_INFO_OFFSET_SHARED),     \
  82        .scan_type = IIO_ST('u', bits, 24, shift)       \
  83}
  84
  85static const struct iio_chan_spec ad5791_channels[] = {
  86        [ID_AD5760] = AD5791_CHAN(16, 4),
  87        [ID_AD5780] = AD5791_CHAN(18, 2),
  88        [ID_AD5781] = AD5791_CHAN(18, 2),
  89        [ID_AD5791] = AD5791_CHAN(20, 0)
  90};
  91
  92static ssize_t ad5791_read_powerdown_mode(struct device *dev,
  93                                      struct device_attribute *attr, char *buf)
  94{
  95        struct iio_dev *indio_dev = dev_get_drvdata(dev);
  96        struct ad5791_state *st = iio_priv(indio_dev);
  97
  98        const char mode[][14] = {"6kohm_to_gnd", "three_state"};
  99
 100        return sprintf(buf, "%s\n", mode[st->pwr_down_mode]);
 101}
 102
 103static ssize_t ad5791_write_powerdown_mode(struct device *dev,
 104                                       struct device_attribute *attr,
 105                                       const char *buf, size_t len)
 106{
 107        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 108        struct ad5791_state *st = iio_priv(indio_dev);
 109        int ret;
 110
 111        if (sysfs_streq(buf, "6kohm_to_gnd"))
 112                st->pwr_down_mode = AD5791_DAC_PWRDN_6K;
 113        else if (sysfs_streq(buf, "three_state"))
 114                st->pwr_down_mode = AD5791_DAC_PWRDN_3STATE;
 115        else
 116                ret = -EINVAL;
 117
 118        return ret ? ret : len;
 119}
 120
 121static ssize_t ad5791_read_dac_powerdown(struct device *dev,
 122                                           struct device_attribute *attr,
 123                                           char *buf)
 124{
 125        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 126        struct ad5791_state *st = iio_priv(indio_dev);
 127
 128        return sprintf(buf, "%d\n", st->pwr_down);
 129}
 130
 131static ssize_t ad5791_write_dac_powerdown(struct device *dev,
 132                                            struct device_attribute *attr,
 133                                            const char *buf, size_t len)
 134{
 135        long readin;
 136        int ret;
 137        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 138        struct ad5791_state *st = iio_priv(indio_dev);
 139
 140        ret = strict_strtol(buf, 10, &readin);
 141        if (ret)
 142                return ret;
 143
 144        if (readin == 0) {
 145                st->pwr_down = false;
 146                st->ctrl &= ~(AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI);
 147        } else if (readin == 1) {
 148                st->pwr_down = true;
 149                if (st->pwr_down_mode == AD5791_DAC_PWRDN_6K)
 150                        st->ctrl |= AD5791_CTRL_OPGND;
 151                else if (st->pwr_down_mode == AD5791_DAC_PWRDN_3STATE)
 152                        st->ctrl |= AD5791_CTRL_DACTRI;
 153        } else
 154                ret = -EINVAL;
 155
 156        ret = ad5791_spi_write(st->spi, AD5791_ADDR_CTRL, st->ctrl);
 157
 158        return ret ? ret : len;
 159}
 160
 161static IIO_DEVICE_ATTR(out_voltage_powerdown_mode, S_IRUGO |
 162                        S_IWUSR, ad5791_read_powerdown_mode,
 163                        ad5791_write_powerdown_mode, 0);
 164
 165static IIO_CONST_ATTR(out_voltage_powerdown_mode_available,
 166                        "6kohm_to_gnd three_state");
 167
 168#define IIO_DEV_ATTR_DAC_POWERDOWN(_num, _show, _store, _addr)          \
 169        IIO_DEVICE_ATTR(out_voltage##_num##_powerdown,                  \
 170                        S_IRUGO | S_IWUSR, _show, _store, _addr)
 171
 172static IIO_DEV_ATTR_DAC_POWERDOWN(0, ad5791_read_dac_powerdown,
 173                                   ad5791_write_dac_powerdown, 0);
 174
 175static struct attribute *ad5791_attributes[] = {
 176        &iio_dev_attr_out_voltage0_powerdown.dev_attr.attr,
 177        &iio_dev_attr_out_voltage_powerdown_mode.dev_attr.attr,
 178        &iio_const_attr_out_voltage_powerdown_mode_available.dev_attr.attr,
 179        NULL,
 180};
 181
 182static const struct attribute_group ad5791_attribute_group = {
 183        .attrs = ad5791_attributes,
 184};
 185
 186static int ad5791_get_lin_comp(unsigned int span)
 187{
 188        if (span <= 10000)
 189                return AD5791_LINCOMP_0_10;
 190        else if (span <= 12000)
 191                return AD5791_LINCOMP_10_12;
 192        else if (span <= 16000)
 193                return AD5791_LINCOMP_12_16;
 194        else if (span <= 19000)
 195                return AD5791_LINCOMP_16_19;
 196        else
 197                return AD5791_LINCOMP_19_20;
 198}
 199
 200static int ad5780_get_lin_comp(unsigned int span)
 201{
 202        if (span <= 10000)
 203                return AD5780_LINCOMP_0_10;
 204        else
 205                return AD5780_LINCOMP_10_20;
 206}
 207static const struct ad5791_chip_info ad5791_chip_info_tbl[] = {
 208        [ID_AD5760] = {
 209                .get_lin_comp = ad5780_get_lin_comp,
 210        },
 211        [ID_AD5780] = {
 212                .get_lin_comp = ad5780_get_lin_comp,
 213        },
 214        [ID_AD5781] = {
 215                .get_lin_comp = ad5791_get_lin_comp,
 216        },
 217        [ID_AD5791] = {
 218                .get_lin_comp = ad5791_get_lin_comp,
 219        },
 220};
 221
 222static int ad5791_read_raw(struct iio_dev *indio_dev,
 223                           struct iio_chan_spec const *chan,
 224                           int *val,
 225                           int *val2,
 226                           long m)
 227{
 228        struct ad5791_state *st = iio_priv(indio_dev);
 229        u64 val64;
 230        int ret;
 231
 232        switch (m) {
 233        case 0:
 234                ret = ad5791_spi_read(st->spi, chan->address, val);
 235                if (ret)
 236                        return ret;
 237                *val &= AD5791_DAC_MASK;
 238                *val >>= chan->scan_type.shift;
 239                return IIO_VAL_INT;
 240        case (1 << IIO_CHAN_INFO_SCALE_SHARED):
 241                *val = 0;
 242                *val2 = (((u64)st->vref_mv) * 1000000ULL) >> chan->scan_type.realbits;
 243                return IIO_VAL_INT_PLUS_MICRO;
 244        case (1 << IIO_CHAN_INFO_OFFSET_SHARED):
 245                val64 = (((u64)st->vref_neg_mv) << chan->scan_type.realbits);
 246                do_div(val64, st->vref_mv);
 247                *val = -val64;
 248                return IIO_VAL_INT;
 249        default:
 250                return -EINVAL;
 251        }
 252
 253};
 254
 255
 256static int ad5791_write_raw(struct iio_dev *indio_dev,
 257                            struct iio_chan_spec const *chan,
 258                            int val,
 259                            int val2,
 260                            long mask)
 261{
 262        struct ad5791_state *st = iio_priv(indio_dev);
 263
 264        switch (mask) {
 265        case 0:
 266                val &= AD5791_RES_MASK(chan->scan_type.realbits);
 267                val <<= chan->scan_type.shift;
 268
 269                return ad5791_spi_write(st->spi, chan->address, val);
 270
 271        default:
 272                return -EINVAL;
 273        }
 274}
 275
 276static const struct iio_info ad5791_info = {
 277        .read_raw = &ad5791_read_raw,
 278        .write_raw = &ad5791_write_raw,
 279        .attrs = &ad5791_attribute_group,
 280        .driver_module = THIS_MODULE,
 281};
 282
 283static int __devinit ad5791_probe(struct spi_device *spi)
 284{
 285        struct ad5791_platform_data *pdata = spi->dev.platform_data;
 286        struct iio_dev *indio_dev;
 287        struct ad5791_state *st;
 288        int ret, pos_voltage_uv = 0, neg_voltage_uv = 0;
 289
 290        indio_dev = iio_allocate_device(sizeof(*st));
 291        if (indio_dev == NULL) {
 292                ret = -ENOMEM;
 293                goto error_ret;
 294        }
 295        st = iio_priv(indio_dev);
 296        st->reg_vdd = regulator_get(&spi->dev, "vdd");
 297        if (!IS_ERR(st->reg_vdd)) {
 298                ret = regulator_enable(st->reg_vdd);
 299                if (ret)
 300                        goto error_put_reg_pos;
 301
 302                pos_voltage_uv = regulator_get_voltage(st->reg_vdd);
 303        }
 304
 305        st->reg_vss = regulator_get(&spi->dev, "vss");
 306        if (!IS_ERR(st->reg_vss)) {
 307                ret = regulator_enable(st->reg_vss);
 308                if (ret)
 309                        goto error_put_reg_neg;
 310
 311                neg_voltage_uv = regulator_get_voltage(st->reg_vss);
 312        }
 313
 314        st->pwr_down = true;
 315        st->spi = spi;
 316
 317        if (!IS_ERR(st->reg_vss) && !IS_ERR(st->reg_vdd)) {
 318                st->vref_mv = (pos_voltage_uv + neg_voltage_uv) / 1000;
 319                st->vref_neg_mv = neg_voltage_uv / 1000;
 320        } else if (pdata) {
 321                st->vref_mv = pdata->vref_pos_mv + pdata->vref_neg_mv;
 322                st->vref_neg_mv = pdata->vref_neg_mv;
 323        } else {
 324                dev_warn(&spi->dev, "reference voltage unspecified\n");
 325        }
 326
 327        ret = ad5791_spi_write(spi, AD5791_ADDR_SW_CTRL, AD5791_SWCTRL_RESET);
 328        if (ret)
 329                goto error_disable_reg_neg;
 330
 331        st->chip_info = &ad5791_chip_info_tbl[spi_get_device_id(spi)
 332                                              ->driver_data];
 333
 334
 335        st->ctrl = AD5761_CTRL_LINCOMP(st->chip_info->get_lin_comp(st->vref_mv))
 336                  | ((pdata && pdata->use_rbuf_gain2) ? 0 : AD5791_CTRL_RBUF) |
 337                  AD5791_CTRL_BIN2SC;
 338
 339        ret = ad5791_spi_write(spi, AD5791_ADDR_CTRL, st->ctrl |
 340                AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI);
 341        if (ret)
 342                goto error_disable_reg_neg;
 343
 344        spi_set_drvdata(spi, indio_dev);
 345        indio_dev->dev.parent = &spi->dev;
 346        indio_dev->info = &ad5791_info;
 347        indio_dev->modes = INDIO_DIRECT_MODE;
 348        indio_dev->channels
 349                = &ad5791_channels[spi_get_device_id(spi)->driver_data];
 350        indio_dev->num_channels = 1;
 351        indio_dev->name = spi_get_device_id(st->spi)->name;
 352        ret = iio_device_register(indio_dev);
 353        if (ret)
 354                goto error_disable_reg_neg;
 355
 356        return 0;
 357
 358error_disable_reg_neg:
 359        if (!IS_ERR(st->reg_vss))
 360                regulator_disable(st->reg_vss);
 361error_put_reg_neg:
 362        if (!IS_ERR(st->reg_vss))
 363                regulator_put(st->reg_vss);
 364
 365        if (!IS_ERR(st->reg_vdd))
 366                regulator_disable(st->reg_vdd);
 367error_put_reg_pos:
 368        if (!IS_ERR(st->reg_vdd))
 369                regulator_put(st->reg_vdd);
 370        iio_free_device(indio_dev);
 371error_ret:
 372
 373        return ret;
 374}
 375
 376static int __devexit ad5791_remove(struct spi_device *spi)
 377{
 378        struct iio_dev *indio_dev = spi_get_drvdata(spi);
 379        struct ad5791_state *st = iio_priv(indio_dev);
 380
 381        iio_device_unregister(indio_dev);
 382        if (!IS_ERR(st->reg_vdd)) {
 383                regulator_disable(st->reg_vdd);
 384                regulator_put(st->reg_vdd);
 385        }
 386
 387        if (!IS_ERR(st->reg_vss)) {
 388                regulator_disable(st->reg_vss);
 389                regulator_put(st->reg_vss);
 390        }
 391        iio_free_device(indio_dev);
 392
 393        return 0;
 394}
 395
 396static const struct spi_device_id ad5791_id[] = {
 397        {"ad5760", ID_AD5760},
 398        {"ad5780", ID_AD5780},
 399        {"ad5781", ID_AD5781},
 400        {"ad5791", ID_AD5791},
 401        {}
 402};
 403
 404static struct spi_driver ad5791_driver = {
 405        .driver = {
 406                   .name = "ad5791",
 407                   .owner = THIS_MODULE,
 408                   },
 409        .probe = ad5791_probe,
 410        .remove = __devexit_p(ad5791_remove),
 411        .id_table = ad5791_id,
 412};
 413
 414static __init int ad5791_spi_init(void)
 415{
 416        return spi_register_driver(&ad5791_driver);
 417}
 418module_init(ad5791_spi_init);
 419
 420static __exit void ad5791_spi_exit(void)
 421{
 422        spi_unregister_driver(&ad5791_driver);
 423}
 424module_exit(ad5791_spi_exit);
 425
 426MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
 427MODULE_DESCRIPTION("Analog Devices AD5760/AD5780/AD5781/AD5791 DAC");
 428MODULE_LICENSE("GPL v2");
 429