linux/drivers/iio/dac/ad5504.c
<<
>>
Prefs
   1/*
   2 * AD5504, AD5501 High Voltage 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 <linux/iio/iio.h>
  20#include <linux/iio/sysfs.h>
  21#include <linux/iio/events.h>
  22#include <linux/iio/dac/ad5504.h>
  23
  24#define AD5505_BITS                     12
  25#define AD5504_RES_MASK                 ((1 << (AD5505_BITS)) - 1)
  26
  27#define AD5504_CMD_READ                 (1 << 15)
  28#define AD5504_CMD_WRITE                (0 << 15)
  29#define AD5504_ADDR(addr)               ((addr) << 12)
  30
  31/* Registers */
  32#define AD5504_ADDR_NOOP                0
  33#define AD5504_ADDR_DAC(x)              ((x) + 1)
  34#define AD5504_ADDR_ALL_DAC             5
  35#define AD5504_ADDR_CTRL                7
  36
  37/* Control Register */
  38#define AD5504_DAC_PWR(ch)              ((ch) << 2)
  39#define AD5504_DAC_PWRDWN_MODE(mode)    ((mode) << 6)
  40#define AD5504_DAC_PWRDN_20K            0
  41#define AD5504_DAC_PWRDN_3STATE         1
  42
  43/**
  44 * struct ad5446_state - driver instance specific data
  45 * @us:                 spi_device
  46 * @reg:                supply regulator
  47 * @vref_mv:            actual reference voltage used
  48 * @pwr_down_mask       power down mask
  49 * @pwr_down_mode       current power down mode
  50 */
  51
  52struct ad5504_state {
  53        struct spi_device               *spi;
  54        struct regulator                *reg;
  55        unsigned short                  vref_mv;
  56        unsigned                        pwr_down_mask;
  57        unsigned                        pwr_down_mode;
  58};
  59
  60/**
  61 * ad5504_supported_device_ids:
  62 */
  63
  64enum ad5504_supported_device_ids {
  65        ID_AD5504,
  66        ID_AD5501,
  67};
  68
  69static int ad5504_spi_write(struct spi_device *spi, u8 addr, u16 val)
  70{
  71        u16 tmp = cpu_to_be16(AD5504_CMD_WRITE |
  72                              AD5504_ADDR(addr) |
  73                              (val & AD5504_RES_MASK));
  74
  75        return spi_write(spi, (u8 *)&tmp, 2);
  76}
  77
  78static int ad5504_spi_read(struct spi_device *spi, u8 addr)
  79{
  80        u16 tmp = cpu_to_be16(AD5504_CMD_READ | AD5504_ADDR(addr));
  81        u16 val;
  82        int ret;
  83        struct spi_transfer     t = {
  84                        .tx_buf         = &tmp,
  85                        .rx_buf         = &val,
  86                        .len            = 2,
  87                };
  88        ret = spi_sync_transfer(spi, &t, 1);
  89
  90        if (ret < 0)
  91                return ret;
  92
  93        return be16_to_cpu(val) & AD5504_RES_MASK;
  94}
  95
  96static int ad5504_read_raw(struct iio_dev *indio_dev,
  97                           struct iio_chan_spec const *chan,
  98                           int *val,
  99                           int *val2,
 100                           long m)
 101{
 102        struct ad5504_state *st = iio_priv(indio_dev);
 103        unsigned long scale_uv;
 104        int ret;
 105
 106        switch (m) {
 107        case IIO_CHAN_INFO_RAW:
 108                ret = ad5504_spi_read(st->spi, chan->address);
 109                if (ret < 0)
 110                        return ret;
 111
 112                *val = ret;
 113
 114                return IIO_VAL_INT;
 115        case IIO_CHAN_INFO_SCALE:
 116                scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits;
 117                *val =  scale_uv / 1000;
 118                *val2 = (scale_uv % 1000) * 1000;
 119                return IIO_VAL_INT_PLUS_MICRO;
 120
 121        }
 122        return -EINVAL;
 123}
 124
 125static int ad5504_write_raw(struct iio_dev *indio_dev,
 126                               struct iio_chan_spec const *chan,
 127                               int val,
 128                               int val2,
 129                               long mask)
 130{
 131        struct ad5504_state *st = iio_priv(indio_dev);
 132        int ret;
 133
 134        switch (mask) {
 135        case IIO_CHAN_INFO_RAW:
 136                if (val >= (1 << chan->scan_type.realbits) || val < 0)
 137                        return -EINVAL;
 138
 139                return ad5504_spi_write(st->spi, chan->address, val);
 140        default:
 141                ret = -EINVAL;
 142        }
 143
 144        return -EINVAL;
 145}
 146
 147static const char * const ad5504_powerdown_modes[] = {
 148        "20kohm_to_gnd",
 149        "three_state",
 150};
 151
 152static int ad5504_get_powerdown_mode(struct iio_dev *indio_dev,
 153        const struct iio_chan_spec *chan)
 154{
 155        struct ad5504_state *st = iio_priv(indio_dev);
 156
 157        return st->pwr_down_mode;
 158}
 159
 160static int ad5504_set_powerdown_mode(struct iio_dev *indio_dev,
 161        const struct iio_chan_spec *chan, unsigned int mode)
 162{
 163        struct ad5504_state *st = iio_priv(indio_dev);
 164
 165        st->pwr_down_mode = mode;
 166
 167        return 0;
 168}
 169
 170static const struct iio_enum ad5504_powerdown_mode_enum = {
 171        .items = ad5504_powerdown_modes,
 172        .num_items = ARRAY_SIZE(ad5504_powerdown_modes),
 173        .get = ad5504_get_powerdown_mode,
 174        .set = ad5504_set_powerdown_mode,
 175};
 176
 177static ssize_t ad5504_read_dac_powerdown(struct iio_dev *indio_dev,
 178        uintptr_t private, const struct iio_chan_spec *chan, char *buf)
 179{
 180        struct ad5504_state *st = iio_priv(indio_dev);
 181
 182        return sprintf(buf, "%d\n",
 183                        !(st->pwr_down_mask & (1 << chan->channel)));
 184}
 185
 186static ssize_t ad5504_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 ad5504_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->pwr_down_mask |= (1 << chan->channel);
 200        else
 201                st->pwr_down_mask &= ~(1 << chan->channel);
 202
 203        ret = ad5504_spi_write(st->spi, AD5504_ADDR_CTRL,
 204                                AD5504_DAC_PWRDWN_MODE(st->pwr_down_mode) |
 205                                AD5504_DAC_PWR(st->pwr_down_mask));
 206
 207        /* writes to the CTRL register must be followed by a NOOP */
 208        ad5504_spi_write(st->spi, AD5504_ADDR_NOOP, 0);
 209
 210        return ret ? ret : len;
 211}
 212
 213static IIO_CONST_ATTR(temp0_thresh_rising_value, "110000");
 214static IIO_CONST_ATTR(temp0_thresh_rising_en, "1");
 215
 216static struct attribute *ad5504_ev_attributes[] = {
 217        &iio_const_attr_temp0_thresh_rising_value.dev_attr.attr,
 218        &iio_const_attr_temp0_thresh_rising_en.dev_attr.attr,
 219        NULL,
 220};
 221
 222static struct attribute_group ad5504_ev_attribute_group = {
 223        .attrs = ad5504_ev_attributes,
 224        .name = "events",
 225};
 226
 227static irqreturn_t ad5504_event_handler(int irq, void *private)
 228{
 229        iio_push_event(private,
 230                       IIO_UNMOD_EVENT_CODE(IIO_TEMP,
 231                                            0,
 232                                            IIO_EV_TYPE_THRESH,
 233                                            IIO_EV_DIR_RISING),
 234                       iio_get_time_ns());
 235
 236        return IRQ_HANDLED;
 237}
 238
 239static const struct iio_info ad5504_info = {
 240        .write_raw = ad5504_write_raw,
 241        .read_raw = ad5504_read_raw,
 242        .event_attrs = &ad5504_ev_attribute_group,
 243        .driver_module = THIS_MODULE,
 244};
 245
 246static const struct iio_chan_spec_ext_info ad5504_ext_info[] = {
 247        {
 248                .name = "powerdown",
 249                .read = ad5504_read_dac_powerdown,
 250                .write = ad5504_write_dac_powerdown,
 251        },
 252        IIO_ENUM("powerdown_mode", true, &ad5504_powerdown_mode_enum),
 253        IIO_ENUM_AVAILABLE("powerdown_mode", &ad5504_powerdown_mode_enum),
 254        { },
 255};
 256
 257#define AD5504_CHANNEL(_chan) { \
 258        .type = IIO_VOLTAGE, \
 259        .indexed = 1, \
 260        .output = 1, \
 261        .channel = (_chan), \
 262        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
 263        .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
 264        .address = AD5504_ADDR_DAC(_chan), \
 265        .scan_type = IIO_ST('u', 12, 16, 0), \
 266        .ext_info = ad5504_ext_info, \
 267}
 268
 269static const struct iio_chan_spec ad5504_channels[] = {
 270        AD5504_CHANNEL(0),
 271        AD5504_CHANNEL(1),
 272        AD5504_CHANNEL(2),
 273        AD5504_CHANNEL(3),
 274};
 275
 276static int ad5504_probe(struct spi_device *spi)
 277{
 278        struct ad5504_platform_data *pdata = spi->dev.platform_data;
 279        struct iio_dev *indio_dev;
 280        struct ad5504_state *st;
 281        struct regulator *reg;
 282        int ret, voltage_uv = 0;
 283
 284        indio_dev = iio_device_alloc(sizeof(*st));
 285        if (indio_dev == NULL) {
 286                ret = -ENOMEM;
 287                goto error_ret;
 288        }
 289        reg = regulator_get(&spi->dev, "vcc");
 290        if (!IS_ERR(reg)) {
 291                ret = regulator_enable(reg);
 292                if (ret)
 293                        goto error_put_reg;
 294
 295                ret = regulator_get_voltage(reg);
 296                if (ret < 0)
 297                        goto error_disable_reg;
 298
 299                voltage_uv = ret;
 300        }
 301
 302        spi_set_drvdata(spi, indio_dev);
 303        st = iio_priv(indio_dev);
 304        if (voltage_uv)
 305                st->vref_mv = voltage_uv / 1000;
 306        else if (pdata)
 307                st->vref_mv = pdata->vref_mv;
 308        else
 309                dev_warn(&spi->dev, "reference voltage unspecified\n");
 310
 311        st->reg = reg;
 312        st->spi = spi;
 313        indio_dev->dev.parent = &spi->dev;
 314        indio_dev->name = spi_get_device_id(st->spi)->name;
 315        indio_dev->info = &ad5504_info;
 316        if (spi_get_device_id(st->spi)->driver_data == ID_AD5501)
 317                indio_dev->num_channels = 1;
 318        else
 319                indio_dev->num_channels = 4;
 320        indio_dev->channels = ad5504_channels;
 321        indio_dev->modes = INDIO_DIRECT_MODE;
 322
 323        if (spi->irq) {
 324                ret = request_threaded_irq(spi->irq,
 325                                           NULL,
 326                                           &ad5504_event_handler,
 327                                           IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 328                                           spi_get_device_id(st->spi)->name,
 329                                           indio_dev);
 330                if (ret)
 331                        goto error_disable_reg;
 332        }
 333
 334        ret = iio_device_register(indio_dev);
 335        if (ret)
 336                goto error_free_irq;
 337
 338        return 0;
 339
 340error_free_irq:
 341        if (spi->irq)
 342                free_irq(spi->irq, indio_dev);
 343error_disable_reg:
 344        if (!IS_ERR(reg))
 345                regulator_disable(reg);
 346error_put_reg:
 347        if (!IS_ERR(reg))
 348                regulator_put(reg);
 349
 350        iio_device_free(indio_dev);
 351error_ret:
 352        return ret;
 353}
 354
 355static int ad5504_remove(struct spi_device *spi)
 356{
 357        struct iio_dev *indio_dev = spi_get_drvdata(spi);
 358        struct ad5504_state *st = iio_priv(indio_dev);
 359
 360        iio_device_unregister(indio_dev);
 361        if (spi->irq)
 362                free_irq(spi->irq, indio_dev);
 363
 364        if (!IS_ERR(st->reg)) {
 365                regulator_disable(st->reg);
 366                regulator_put(st->reg);
 367        }
 368        iio_device_free(indio_dev);
 369
 370        return 0;
 371}
 372
 373static const struct spi_device_id ad5504_id[] = {
 374        {"ad5504", ID_AD5504},
 375        {"ad5501", ID_AD5501},
 376        {}
 377};
 378MODULE_DEVICE_TABLE(spi, ad5504_id);
 379
 380static struct spi_driver ad5504_driver = {
 381        .driver = {
 382                   .name = "ad5504",
 383                   .owner = THIS_MODULE,
 384                   },
 385        .probe = ad5504_probe,
 386        .remove = ad5504_remove,
 387        .id_table = ad5504_id,
 388};
 389module_spi_driver(ad5504_driver);
 390
 391MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
 392MODULE_DESCRIPTION("Analog Devices AD5501/AD5501 DAC");
 393MODULE_LICENSE("GPL v2");
 394