linux/drivers/staging/iio/frequency/ad9832.c
<<
>>
Prefs
   1/*
   2 * AD9832 SPI DDS driver
   3 *
   4 * Copyright 2011 Analog Devices Inc.
   5 *
   6 * Licensed under the GPL-2.
   7 */
   8
   9#include <linux/device.h>
  10#include <linux/kernel.h>
  11#include <linux/slab.h>
  12#include <linux/sysfs.h>
  13#include <linux/spi/spi.h>
  14#include <linux/regulator/consumer.h>
  15#include <linux/err.h>
  16#include <linux/module.h>
  17#include <asm/div64.h>
  18
  19#include <linux/iio/iio.h>
  20#include <linux/iio/sysfs.h>
  21#include "dds.h"
  22
  23#include "ad9832.h"
  24
  25/* Registers */
  26
  27#define AD9832_FREQ0LL          0x0
  28#define AD9832_FREQ0HL          0x1
  29#define AD9832_FREQ0LM          0x2
  30#define AD9832_FREQ0HM          0x3
  31#define AD9832_FREQ1LL          0x4
  32#define AD9832_FREQ1HL          0x5
  33#define AD9832_FREQ1LM          0x6
  34#define AD9832_FREQ1HM          0x7
  35#define AD9832_PHASE0L          0x8
  36#define AD9832_PHASE0H          0x9
  37#define AD9832_PHASE1L          0xA
  38#define AD9832_PHASE1H          0xB
  39#define AD9832_PHASE2L          0xC
  40#define AD9832_PHASE2H          0xD
  41#define AD9832_PHASE3L          0xE
  42#define AD9832_PHASE3H          0xF
  43
  44#define AD9832_PHASE_SYM        0x10
  45#define AD9832_FREQ_SYM         0x11
  46#define AD9832_PINCTRL_EN       0x12
  47#define AD9832_OUTPUT_EN        0x13
  48
  49/* Command Control Bits */
  50
  51#define AD9832_CMD_PHA8BITSW    0x1
  52#define AD9832_CMD_PHA16BITSW   0x0
  53#define AD9832_CMD_FRE8BITSW    0x3
  54#define AD9832_CMD_FRE16BITSW   0x2
  55#define AD9832_CMD_FPSELECT     0x6
  56#define AD9832_CMD_SYNCSELSRC   0x8
  57#define AD9832_CMD_SLEEPRESCLR  0xC
  58
  59#define AD9832_FREQ             BIT(11)
  60#define AD9832_PHASE(x)         (((x) & 3) << 9)
  61#define AD9832_SYNC             BIT(13)
  62#define AD9832_SELSRC           BIT(12)
  63#define AD9832_SLEEP            BIT(13)
  64#define AD9832_RESET            BIT(12)
  65#define AD9832_CLR              BIT(11)
  66#define CMD_SHIFT               12
  67#define ADD_SHIFT               8
  68#define AD9832_FREQ_BITS        32
  69#define AD9832_PHASE_BITS       12
  70#define RES_MASK(bits)          ((1 << (bits)) - 1)
  71
  72/**
  73 * struct ad9832_state - driver instance specific data
  74 * @spi:                spi_device
  75 * @avdd:               supply regulator for the analog section
  76 * @dvdd:               supply regulator for the digital section
  77 * @mclk:               external master clock
  78 * @ctrl_fp:            cached frequency/phase control word
  79 * @ctrl_ss:            cached sync/selsrc control word
  80 * @ctrl_src:           cached sleep/reset/clr word
  81 * @xfer:               default spi transfer
  82 * @msg:                default spi message
  83 * @freq_xfer:          tuning word spi transfer
  84 * @freq_msg:           tuning word spi message
  85 * @phase_xfer:         tuning word spi transfer
  86 * @phase_msg:          tuning word spi message
  87 * @lock                protect sensor state
  88 * @data:               spi transmit buffer
  89 * @phase_data:         tuning word spi transmit buffer
  90 * @freq_data:          tuning word spi transmit buffer
  91 */
  92
  93struct ad9832_state {
  94        struct spi_device               *spi;
  95        struct regulator                *avdd;
  96        struct regulator                *dvdd;
  97        unsigned long                   mclk;
  98        unsigned short                  ctrl_fp;
  99        unsigned short                  ctrl_ss;
 100        unsigned short                  ctrl_src;
 101        struct spi_transfer             xfer;
 102        struct spi_message              msg;
 103        struct spi_transfer             freq_xfer[4];
 104        struct spi_message              freq_msg;
 105        struct spi_transfer             phase_xfer[2];
 106        struct spi_message              phase_msg;
 107        struct mutex                    lock;   /* protect sensor state */
 108        /*
 109         * DMA (thus cache coherency maintenance) requires the
 110         * transfer buffers to live in their own cache lines.
 111         */
 112        union {
 113                __be16                  freq_data[4]____cacheline_aligned;
 114                __be16                  phase_data[2];
 115                __be16                  data;
 116        };
 117};
 118
 119static unsigned long ad9832_calc_freqreg(unsigned long mclk, unsigned long fout)
 120{
 121        unsigned long long freqreg = (u64)fout *
 122                                     (u64)((u64)1L << AD9832_FREQ_BITS);
 123        do_div(freqreg, mclk);
 124        return freqreg;
 125}
 126
 127static int ad9832_write_frequency(struct ad9832_state *st,
 128                                  unsigned int addr, unsigned long fout)
 129{
 130        unsigned long regval;
 131
 132        if (fout > (st->mclk / 2))
 133                return -EINVAL;
 134
 135        regval = ad9832_calc_freqreg(st->mclk, fout);
 136
 137        st->freq_data[0] = cpu_to_be16((AD9832_CMD_FRE8BITSW << CMD_SHIFT) |
 138                                        (addr << ADD_SHIFT) |
 139                                        ((regval >> 24) & 0xFF));
 140        st->freq_data[1] = cpu_to_be16((AD9832_CMD_FRE16BITSW << CMD_SHIFT) |
 141                                        ((addr - 1) << ADD_SHIFT) |
 142                                        ((regval >> 16) & 0xFF));
 143        st->freq_data[2] = cpu_to_be16((AD9832_CMD_FRE8BITSW << CMD_SHIFT) |
 144                                        ((addr - 2) << ADD_SHIFT) |
 145                                        ((regval >> 8) & 0xFF));
 146        st->freq_data[3] = cpu_to_be16((AD9832_CMD_FRE16BITSW << CMD_SHIFT) |
 147                                        ((addr - 3) << ADD_SHIFT) |
 148                                        ((regval >> 0) & 0xFF));
 149
 150        return spi_sync(st->spi, &st->freq_msg);
 151}
 152
 153static int ad9832_write_phase(struct ad9832_state *st,
 154                              unsigned long addr, unsigned long phase)
 155{
 156        if (phase > BIT(AD9832_PHASE_BITS))
 157                return -EINVAL;
 158
 159        st->phase_data[0] = cpu_to_be16((AD9832_CMD_PHA8BITSW << CMD_SHIFT) |
 160                                        (addr << ADD_SHIFT) |
 161                                        ((phase >> 8) & 0xFF));
 162        st->phase_data[1] = cpu_to_be16((AD9832_CMD_PHA16BITSW << CMD_SHIFT) |
 163                                        ((addr - 1) << ADD_SHIFT) |
 164                                        (phase & 0xFF));
 165
 166        return spi_sync(st->spi, &st->phase_msg);
 167}
 168
 169static ssize_t ad9832_write(struct device *dev, struct device_attribute *attr,
 170                            const char *buf, size_t len)
 171{
 172        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 173        struct ad9832_state *st = iio_priv(indio_dev);
 174        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 175        int ret;
 176        unsigned long val;
 177
 178        ret = kstrtoul(buf, 10, &val);
 179        if (ret)
 180                goto error_ret;
 181
 182        mutex_lock(&st->lock);
 183        switch ((u32)this_attr->address) {
 184        case AD9832_FREQ0HM:
 185        case AD9832_FREQ1HM:
 186                ret = ad9832_write_frequency(st, this_attr->address, val);
 187                break;
 188        case AD9832_PHASE0H:
 189        case AD9832_PHASE1H:
 190        case AD9832_PHASE2H:
 191        case AD9832_PHASE3H:
 192                ret = ad9832_write_phase(st, this_attr->address, val);
 193                break;
 194        case AD9832_PINCTRL_EN:
 195                if (val)
 196                        st->ctrl_ss &= ~AD9832_SELSRC;
 197                else
 198                        st->ctrl_ss |= AD9832_SELSRC;
 199                st->data = cpu_to_be16((AD9832_CMD_SYNCSELSRC << CMD_SHIFT) |
 200                                        st->ctrl_ss);
 201                ret = spi_sync(st->spi, &st->msg);
 202                break;
 203        case AD9832_FREQ_SYM:
 204                if (val == 1) {
 205                        st->ctrl_fp |= AD9832_FREQ;
 206                } else if (val == 0) {
 207                        st->ctrl_fp &= ~AD9832_FREQ;
 208                } else {
 209                        ret = -EINVAL;
 210                        break;
 211                }
 212                st->data = cpu_to_be16((AD9832_CMD_FPSELECT << CMD_SHIFT) |
 213                                        st->ctrl_fp);
 214                ret = spi_sync(st->spi, &st->msg);
 215                break;
 216        case AD9832_PHASE_SYM:
 217                if (val > 3) {
 218                        ret = -EINVAL;
 219                        break;
 220                }
 221
 222                st->ctrl_fp &= ~AD9832_PHASE(3);
 223                st->ctrl_fp |= AD9832_PHASE(val);
 224
 225                st->data = cpu_to_be16((AD9832_CMD_FPSELECT << CMD_SHIFT) |
 226                                        st->ctrl_fp);
 227                ret = spi_sync(st->spi, &st->msg);
 228                break;
 229        case AD9832_OUTPUT_EN:
 230                if (val)
 231                        st->ctrl_src &= ~(AD9832_RESET | AD9832_SLEEP |
 232                                        AD9832_CLR);
 233                else
 234                        st->ctrl_src |= AD9832_RESET;
 235
 236                st->data = cpu_to_be16((AD9832_CMD_SLEEPRESCLR << CMD_SHIFT) |
 237                                        st->ctrl_src);
 238                ret = spi_sync(st->spi, &st->msg);
 239                break;
 240        default:
 241                ret = -ENODEV;
 242        }
 243        mutex_unlock(&st->lock);
 244
 245error_ret:
 246        return ret ? ret : len;
 247}
 248
 249/**
 250 * see dds.h for further information
 251 */
 252
 253static IIO_DEV_ATTR_FREQ(0, 0, 0200, NULL, ad9832_write, AD9832_FREQ0HM);
 254static IIO_DEV_ATTR_FREQ(0, 1, 0200, NULL, ad9832_write, AD9832_FREQ1HM);
 255static IIO_DEV_ATTR_FREQSYMBOL(0, 0200, NULL, ad9832_write, AD9832_FREQ_SYM);
 256static IIO_CONST_ATTR_FREQ_SCALE(0, "1"); /* 1Hz */
 257
 258static IIO_DEV_ATTR_PHASE(0, 0, 0200, NULL, ad9832_write, AD9832_PHASE0H);
 259static IIO_DEV_ATTR_PHASE(0, 1, 0200, NULL, ad9832_write, AD9832_PHASE1H);
 260static IIO_DEV_ATTR_PHASE(0, 2, 0200, NULL, ad9832_write, AD9832_PHASE2H);
 261static IIO_DEV_ATTR_PHASE(0, 3, 0200, NULL, ad9832_write, AD9832_PHASE3H);
 262static IIO_DEV_ATTR_PHASESYMBOL(0, 0200, NULL,
 263                                ad9832_write, AD9832_PHASE_SYM);
 264static IIO_CONST_ATTR_PHASE_SCALE(0, "0.0015339808"); /* 2PI/2^12 rad*/
 265
 266static IIO_DEV_ATTR_PINCONTROL_EN(0, 0200, NULL,
 267                                ad9832_write, AD9832_PINCTRL_EN);
 268static IIO_DEV_ATTR_OUT_ENABLE(0, 0200, NULL,
 269                                ad9832_write, AD9832_OUTPUT_EN);
 270
 271static struct attribute *ad9832_attributes[] = {
 272        &iio_dev_attr_out_altvoltage0_frequency0.dev_attr.attr,
 273        &iio_dev_attr_out_altvoltage0_frequency1.dev_attr.attr,
 274        &iio_const_attr_out_altvoltage0_frequency_scale.dev_attr.attr,
 275        &iio_dev_attr_out_altvoltage0_phase0.dev_attr.attr,
 276        &iio_dev_attr_out_altvoltage0_phase1.dev_attr.attr,
 277        &iio_dev_attr_out_altvoltage0_phase2.dev_attr.attr,
 278        &iio_dev_attr_out_altvoltage0_phase3.dev_attr.attr,
 279        &iio_const_attr_out_altvoltage0_phase_scale.dev_attr.attr,
 280        &iio_dev_attr_out_altvoltage0_pincontrol_en.dev_attr.attr,
 281        &iio_dev_attr_out_altvoltage0_frequencysymbol.dev_attr.attr,
 282        &iio_dev_attr_out_altvoltage0_phasesymbol.dev_attr.attr,
 283        &iio_dev_attr_out_altvoltage0_out_enable.dev_attr.attr,
 284        NULL,
 285};
 286
 287static const struct attribute_group ad9832_attribute_group = {
 288        .attrs = ad9832_attributes,
 289};
 290
 291static const struct iio_info ad9832_info = {
 292        .attrs = &ad9832_attribute_group,
 293};
 294
 295static int ad9832_probe(struct spi_device *spi)
 296{
 297        struct ad9832_platform_data *pdata = dev_get_platdata(&spi->dev);
 298        struct iio_dev *indio_dev;
 299        struct ad9832_state *st;
 300        int ret;
 301
 302        if (!pdata) {
 303                dev_dbg(&spi->dev, "no platform data?\n");
 304                return -ENODEV;
 305        }
 306
 307        indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 308        if (!indio_dev)
 309                return -ENOMEM;
 310
 311        spi_set_drvdata(spi, indio_dev);
 312        st = iio_priv(indio_dev);
 313
 314        st->avdd = devm_regulator_get(&spi->dev, "avdd");
 315        if (IS_ERR(st->avdd))
 316                return PTR_ERR(st->avdd);
 317
 318        ret = regulator_enable(st->avdd);
 319        if (ret) {
 320                dev_err(&spi->dev, "Failed to enable specified AVDD supply\n");
 321                return ret;
 322        }
 323
 324        st->dvdd = devm_regulator_get(&spi->dev, "dvdd");
 325        if (IS_ERR(st->dvdd)) {
 326                ret = PTR_ERR(st->dvdd);
 327                goto error_disable_avdd;
 328        }
 329
 330        ret = regulator_enable(st->dvdd);
 331        if (ret) {
 332                dev_err(&spi->dev, "Failed to enable specified DVDD supply\n");
 333                goto error_disable_avdd;
 334        }
 335
 336        st->mclk = pdata->mclk;
 337        st->spi = spi;
 338        mutex_init(&st->lock);
 339
 340        indio_dev->dev.parent = &spi->dev;
 341        indio_dev->name = spi_get_device_id(spi)->name;
 342        indio_dev->info = &ad9832_info;
 343        indio_dev->modes = INDIO_DIRECT_MODE;
 344
 345        /* Setup default messages */
 346
 347        st->xfer.tx_buf = &st->data;
 348        st->xfer.len = 2;
 349
 350        spi_message_init(&st->msg);
 351        spi_message_add_tail(&st->xfer, &st->msg);
 352
 353        st->freq_xfer[0].tx_buf = &st->freq_data[0];
 354        st->freq_xfer[0].len = 2;
 355        st->freq_xfer[0].cs_change = 1;
 356        st->freq_xfer[1].tx_buf = &st->freq_data[1];
 357        st->freq_xfer[1].len = 2;
 358        st->freq_xfer[1].cs_change = 1;
 359        st->freq_xfer[2].tx_buf = &st->freq_data[2];
 360        st->freq_xfer[2].len = 2;
 361        st->freq_xfer[2].cs_change = 1;
 362        st->freq_xfer[3].tx_buf = &st->freq_data[3];
 363        st->freq_xfer[3].len = 2;
 364
 365        spi_message_init(&st->freq_msg);
 366        spi_message_add_tail(&st->freq_xfer[0], &st->freq_msg);
 367        spi_message_add_tail(&st->freq_xfer[1], &st->freq_msg);
 368        spi_message_add_tail(&st->freq_xfer[2], &st->freq_msg);
 369        spi_message_add_tail(&st->freq_xfer[3], &st->freq_msg);
 370
 371        st->phase_xfer[0].tx_buf = &st->phase_data[0];
 372        st->phase_xfer[0].len = 2;
 373        st->phase_xfer[0].cs_change = 1;
 374        st->phase_xfer[1].tx_buf = &st->phase_data[1];
 375        st->phase_xfer[1].len = 2;
 376
 377        spi_message_init(&st->phase_msg);
 378        spi_message_add_tail(&st->phase_xfer[0], &st->phase_msg);
 379        spi_message_add_tail(&st->phase_xfer[1], &st->phase_msg);
 380
 381        st->ctrl_src = AD9832_SLEEP | AD9832_RESET | AD9832_CLR;
 382        st->data = cpu_to_be16((AD9832_CMD_SLEEPRESCLR << CMD_SHIFT) |
 383                                        st->ctrl_src);
 384        ret = spi_sync(st->spi, &st->msg);
 385        if (ret) {
 386                dev_err(&spi->dev, "device init failed\n");
 387                goto error_disable_dvdd;
 388        }
 389
 390        ret = ad9832_write_frequency(st, AD9832_FREQ0HM, pdata->freq0);
 391        if (ret)
 392                goto error_disable_dvdd;
 393
 394        ret = ad9832_write_frequency(st, AD9832_FREQ1HM, pdata->freq1);
 395        if (ret)
 396                goto error_disable_dvdd;
 397
 398        ret = ad9832_write_phase(st, AD9832_PHASE0H, pdata->phase0);
 399        if (ret)
 400                goto error_disable_dvdd;
 401
 402        ret = ad9832_write_phase(st, AD9832_PHASE1H, pdata->phase1);
 403        if (ret)
 404                goto error_disable_dvdd;
 405
 406        ret = ad9832_write_phase(st, AD9832_PHASE2H, pdata->phase2);
 407        if (ret)
 408                goto error_disable_dvdd;
 409
 410        ret = ad9832_write_phase(st, AD9832_PHASE3H, pdata->phase3);
 411        if (ret)
 412                goto error_disable_dvdd;
 413
 414        ret = iio_device_register(indio_dev);
 415        if (ret)
 416                goto error_disable_dvdd;
 417
 418        return 0;
 419
 420error_disable_dvdd:
 421        regulator_disable(st->dvdd);
 422error_disable_avdd:
 423        regulator_disable(st->avdd);
 424
 425        return ret;
 426}
 427
 428static int ad9832_remove(struct spi_device *spi)
 429{
 430        struct iio_dev *indio_dev = spi_get_drvdata(spi);
 431        struct ad9832_state *st = iio_priv(indio_dev);
 432
 433        iio_device_unregister(indio_dev);
 434        regulator_disable(st->dvdd);
 435        regulator_disable(st->avdd);
 436
 437        return 0;
 438}
 439
 440static const struct spi_device_id ad9832_id[] = {
 441        {"ad9832", 0},
 442        {"ad9835", 0},
 443        {}
 444};
 445MODULE_DEVICE_TABLE(spi, ad9832_id);
 446
 447static struct spi_driver ad9832_driver = {
 448        .driver = {
 449                .name   = "ad9832",
 450        },
 451        .probe          = ad9832_probe,
 452        .remove         = ad9832_remove,
 453        .id_table       = ad9832_id,
 454};
 455module_spi_driver(ad9832_driver);
 456
 457MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
 458MODULE_DESCRIPTION("Analog Devices AD9832/AD9835 DDS");
 459MODULE_LICENSE("GPL v2");
 460