linux/drivers/staging/iio/dds/ad9834.c
<<
>>
Prefs
   1/*
   2 * AD9834 SPI DAC driver
   3 *
   4 * Copyright 2010 Analog Devices Inc.
   5 *
   6 * Licensed under the GPL-2 or later.
   7 */
   8
   9#include <linux/interrupt.h>
  10#include <linux/workqueue.h>
  11#include <linux/device.h>
  12#include <linux/kernel.h>
  13#include <linux/slab.h>
  14#include <linux/sysfs.h>
  15#include <linux/list.h>
  16#include <linux/spi/spi.h>
  17#include <linux/regulator/consumer.h>
  18#include <linux/err.h>
  19#include <asm/div64.h>
  20
  21#include "../iio.h"
  22#include "../sysfs.h"
  23#include "dds.h"
  24
  25#include "ad9834.h"
  26
  27static unsigned int ad9834_calc_freqreg(unsigned long mclk, unsigned long fout)
  28{
  29        unsigned long long freqreg = (u64) fout * (u64) (1 << AD9834_FREQ_BITS);
  30        do_div(freqreg, mclk);
  31        return freqreg;
  32}
  33
  34static int ad9834_write_frequency(struct ad9834_state *st,
  35                                  unsigned long addr, unsigned long fout)
  36{
  37        unsigned long regval;
  38
  39        if (fout > (st->mclk / 2))
  40                return -EINVAL;
  41
  42        regval = ad9834_calc_freqreg(st->mclk, fout);
  43
  44        st->freq_data[0] = cpu_to_be16(addr | (regval &
  45                                       RES_MASK(AD9834_FREQ_BITS / 2)));
  46        st->freq_data[1] = cpu_to_be16(addr | ((regval >>
  47                                       (AD9834_FREQ_BITS / 2)) &
  48                                       RES_MASK(AD9834_FREQ_BITS / 2)));
  49
  50        return spi_sync(st->spi, &st->freq_msg);;
  51}
  52
  53static int ad9834_write_phase(struct ad9834_state *st,
  54                                  unsigned long addr, unsigned long phase)
  55{
  56        if (phase > (1 << AD9834_PHASE_BITS))
  57                return -EINVAL;
  58        st->data = cpu_to_be16(addr | phase);
  59
  60        return spi_sync(st->spi, &st->msg);
  61}
  62
  63static ssize_t ad9834_write(struct device *dev,
  64                struct device_attribute *attr,
  65                const char *buf,
  66                size_t len)
  67{
  68        struct iio_dev *dev_info = dev_get_drvdata(dev);
  69        struct ad9834_state *st = dev_info->dev_data;
  70        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
  71        int ret;
  72        long val;
  73
  74        ret = strict_strtoul(buf, 10, &val);
  75        if (ret)
  76                goto error_ret;
  77
  78        mutex_lock(&dev_info->mlock);
  79        switch (this_attr->address) {
  80        case AD9834_REG_FREQ0:
  81        case AD9834_REG_FREQ1:
  82                ret = ad9834_write_frequency(st, this_attr->address, val);
  83                break;
  84        case AD9834_REG_PHASE0:
  85        case AD9834_REG_PHASE1:
  86                ret = ad9834_write_phase(st, this_attr->address, val);
  87                break;
  88        case AD9834_OPBITEN:
  89                if (st->control & AD9834_MODE) {
  90                        ret = -EINVAL;  /* AD9843 reserved mode */
  91                        break;
  92                }
  93
  94                if (val)
  95                        st->control |= AD9834_OPBITEN;
  96                else
  97                        st->control &= ~AD9834_OPBITEN;
  98
  99                st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
 100                ret = spi_sync(st->spi, &st->msg);
 101                break;
 102        case AD9834_PIN_SW:
 103                if (val)
 104                        st->control |= AD9834_PIN_SW;
 105                else
 106                        st->control &= ~AD9834_PIN_SW;
 107                st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
 108                ret = spi_sync(st->spi, &st->msg);
 109                break;
 110        case AD9834_FSEL:
 111        case AD9834_PSEL:
 112                if (val == 0)
 113                        st->control &= ~(this_attr->address | AD9834_PIN_SW);
 114                else if (val == 1) {
 115                        st->control |= this_attr->address;
 116                        st->control &= ~AD9834_PIN_SW;
 117                } else {
 118                        ret = -EINVAL;
 119                        break;
 120                }
 121                st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
 122                ret = spi_sync(st->spi, &st->msg);
 123                break;
 124        case AD9834_RESET:
 125                if (val)
 126                        st->control &= ~AD9834_RESET;
 127                else
 128                        st->control |= AD9834_RESET;
 129
 130                st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
 131                ret = spi_sync(st->spi, &st->msg);
 132                break;
 133        default:
 134                ret = -ENODEV;
 135        }
 136        mutex_unlock(&dev_info->mlock);
 137
 138error_ret:
 139        return ret ? ret : len;
 140}
 141
 142static ssize_t ad9834_store_wavetype(struct device *dev,
 143                                 struct device_attribute *attr,
 144                                 const char *buf,
 145                                 size_t len)
 146{
 147        struct iio_dev *dev_info = dev_get_drvdata(dev);
 148        struct ad9834_state *st = dev_info->dev_data;
 149        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 150        int ret = 0;
 151        bool is_ad9833 = st->devid == ID_AD9833;
 152
 153        mutex_lock(&dev_info->mlock);
 154
 155        switch (this_attr->address) {
 156        case 0:
 157                if (sysfs_streq(buf, "sine")) {
 158                        st->control &= ~AD9834_MODE;
 159                        if (is_ad9833)
 160                                st->control &= ~AD9834_OPBITEN;
 161                } else if (sysfs_streq(buf, "triangle")) {
 162                        if (is_ad9833) {
 163                                st->control &= ~AD9834_OPBITEN;
 164                                st->control |= AD9834_MODE;
 165                        } else if (st->control & AD9834_OPBITEN) {
 166                                ret = -EINVAL;  /* AD9843 reserved mode */
 167                        } else {
 168                                st->control |= AD9834_MODE;
 169                        }
 170                } else if (is_ad9833 && sysfs_streq(buf, "square")) {
 171                        st->control &= ~AD9834_MODE;
 172                        st->control |= AD9834_OPBITEN;
 173                } else {
 174                        ret = -EINVAL;
 175                }
 176
 177                break;
 178        case 1:
 179                if (sysfs_streq(buf, "square") &&
 180                        !(st->control & AD9834_MODE)) {
 181                        st->control &= ~AD9834_MODE;
 182                        st->control |= AD9834_OPBITEN;
 183                } else {
 184                        ret = -EINVAL;
 185                }
 186                break;
 187        default:
 188                ret = -EINVAL;
 189                break;
 190        }
 191
 192        if (!ret) {
 193                st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
 194                ret = spi_sync(st->spi, &st->msg);
 195        }
 196        mutex_unlock(&dev_info->mlock);
 197
 198        return ret ? ret : len;
 199}
 200
 201static ssize_t ad9834_show_name(struct device *dev,
 202                                 struct device_attribute *attr,
 203                                 char *buf)
 204{
 205        struct iio_dev *dev_info = dev_get_drvdata(dev);
 206        struct ad9834_state *st = iio_dev_get_devdata(dev_info);
 207
 208        return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name);
 209}
 210static IIO_DEVICE_ATTR(name, S_IRUGO, ad9834_show_name, NULL, 0);
 211
 212static ssize_t ad9834_show_out0_wavetype_available(struct device *dev,
 213                                                struct device_attribute *attr,
 214                                                char *buf)
 215{
 216        struct iio_dev *dev_info = dev_get_drvdata(dev);
 217        struct ad9834_state *st = iio_dev_get_devdata(dev_info);
 218        char *str;
 219
 220        if (st->devid == ID_AD9833)
 221                str = "sine triangle square";
 222        else if (st->control & AD9834_OPBITEN)
 223                str = "sine";
 224        else
 225                str = "sine triangle";
 226
 227        return sprintf(buf, "%s\n", str);
 228}
 229
 230
 231static IIO_DEVICE_ATTR(dds0_out0_wavetype_available, S_IRUGO,
 232                       ad9834_show_out0_wavetype_available, NULL, 0);
 233
 234static ssize_t ad9834_show_out1_wavetype_available(struct device *dev,
 235                                                struct device_attribute *attr,
 236                                                char *buf)
 237{
 238        struct iio_dev *dev_info = dev_get_drvdata(dev);
 239        struct ad9834_state *st = iio_dev_get_devdata(dev_info);
 240        char *str;
 241
 242        if (st->control & AD9834_MODE)
 243                str = "";
 244        else
 245                str = "square";
 246
 247        return sprintf(buf, "%s\n", str);
 248}
 249
 250static IIO_DEVICE_ATTR(dds0_out1_wavetype_available, S_IRUGO,
 251                       ad9834_show_out1_wavetype_available, NULL, 0);
 252
 253/**
 254 * see dds.h for further information
 255 */
 256
 257static IIO_DEV_ATTR_FREQ(0, 0, S_IWUSR, NULL, ad9834_write, AD9834_REG_FREQ0);
 258static IIO_DEV_ATTR_FREQ(0, 1, S_IWUSR, NULL, ad9834_write, AD9834_REG_FREQ1);
 259static IIO_DEV_ATTR_FREQSYMBOL(0, S_IWUSR, NULL, ad9834_write, AD9834_FSEL);
 260static IIO_CONST_ATTR_FREQ_SCALE(0, "1"); /* 1Hz */
 261
 262static IIO_DEV_ATTR_PHASE(0, 0, S_IWUSR, NULL, ad9834_write, AD9834_REG_PHASE0);
 263static IIO_DEV_ATTR_PHASE(0, 1, S_IWUSR, NULL, ad9834_write, AD9834_REG_PHASE1);
 264static IIO_DEV_ATTR_PHASESYMBOL(0, S_IWUSR, NULL, ad9834_write, AD9834_PSEL);
 265static IIO_CONST_ATTR_PHASE_SCALE(0, "0.0015339808"); /* 2PI/2^12 rad*/
 266
 267static IIO_DEV_ATTR_PINCONTROL_EN(0, S_IWUSR, NULL,
 268        ad9834_write, AD9834_PIN_SW);
 269static IIO_DEV_ATTR_OUT_ENABLE(0, S_IWUSR, NULL, ad9834_write, AD9834_RESET);
 270static IIO_DEV_ATTR_OUTY_ENABLE(0, 1, S_IWUSR, NULL,
 271        ad9834_write, AD9834_OPBITEN);
 272static IIO_DEV_ATTR_OUT_WAVETYPE(0, 0, ad9834_store_wavetype, 0);
 273static IIO_DEV_ATTR_OUT_WAVETYPE(0, 1, ad9834_store_wavetype, 1);
 274
 275static struct attribute *ad9834_attributes[] = {
 276        &iio_dev_attr_dds0_freq0.dev_attr.attr,
 277        &iio_dev_attr_dds0_freq1.dev_attr.attr,
 278        &iio_const_attr_dds0_freq_scale.dev_attr.attr,
 279        &iio_dev_attr_dds0_phase0.dev_attr.attr,
 280        &iio_dev_attr_dds0_phase1.dev_attr.attr,
 281        &iio_const_attr_dds0_phase_scale.dev_attr.attr,
 282        &iio_dev_attr_dds0_pincontrol_en.dev_attr.attr,
 283        &iio_dev_attr_dds0_freqsymbol.dev_attr.attr,
 284        &iio_dev_attr_dds0_phasesymbol.dev_attr.attr,
 285        &iio_dev_attr_dds0_out_enable.dev_attr.attr,
 286        &iio_dev_attr_dds0_out1_enable.dev_attr.attr,
 287        &iio_dev_attr_dds0_out0_wavetype.dev_attr.attr,
 288        &iio_dev_attr_dds0_out1_wavetype.dev_attr.attr,
 289        &iio_dev_attr_dds0_out0_wavetype_available.dev_attr.attr,
 290        &iio_dev_attr_dds0_out1_wavetype_available.dev_attr.attr,
 291        &iio_dev_attr_name.dev_attr.attr,
 292        NULL,
 293};
 294
 295static mode_t ad9834_attr_is_visible(struct kobject *kobj,
 296                                     struct attribute *attr, int n)
 297{
 298        struct device *dev = container_of(kobj, struct device, kobj);
 299        struct iio_dev *dev_info = dev_get_drvdata(dev);
 300        struct ad9834_state *st = iio_dev_get_devdata(dev_info);
 301
 302        mode_t mode = attr->mode;
 303
 304        if (st->devid == ID_AD9834)
 305                return mode;
 306
 307        if ((attr == &iio_dev_attr_dds0_out1_enable.dev_attr.attr) ||
 308                (attr == &iio_dev_attr_dds0_out1_wavetype.dev_attr.attr) ||
 309                (attr ==
 310                &iio_dev_attr_dds0_out1_wavetype_available.dev_attr.attr))
 311                mode = 0;
 312
 313        return mode;
 314}
 315
 316static const struct attribute_group ad9834_attribute_group = {
 317        .attrs = ad9834_attributes,
 318        .is_visible = ad9834_attr_is_visible,
 319};
 320
 321static int __devinit ad9834_probe(struct spi_device *spi)
 322{
 323        struct ad9834_platform_data *pdata = spi->dev.platform_data;
 324        struct ad9834_state *st;
 325        int ret;
 326
 327        if (!pdata) {
 328                dev_dbg(&spi->dev, "no platform data?\n");
 329                return -ENODEV;
 330        }
 331
 332        st = kzalloc(sizeof(*st), GFP_KERNEL);
 333        if (st == NULL) {
 334                ret = -ENOMEM;
 335                goto error_ret;
 336        }
 337
 338        st->reg = regulator_get(&spi->dev, "vcc");
 339        if (!IS_ERR(st->reg)) {
 340                ret = regulator_enable(st->reg);
 341                if (ret)
 342                        goto error_put_reg;
 343        }
 344
 345        st->mclk = pdata->mclk;
 346
 347        spi_set_drvdata(spi, st);
 348
 349        st->spi = spi;
 350        st->devid = spi_get_device_id(spi)->driver_data;
 351
 352        st->indio_dev = iio_allocate_device();
 353        if (st->indio_dev == NULL) {
 354                ret = -ENOMEM;
 355                goto error_disable_reg;
 356        }
 357
 358        st->indio_dev->dev.parent = &spi->dev;
 359        st->indio_dev->attrs = &ad9834_attribute_group;
 360        st->indio_dev->dev_data = (void *) st;
 361        st->indio_dev->driver_module = THIS_MODULE;
 362        st->indio_dev->modes = INDIO_DIRECT_MODE;
 363
 364        /* Setup default messages */
 365
 366        st->xfer.tx_buf = &st->data;
 367        st->xfer.len = 2;
 368
 369        spi_message_init(&st->msg);
 370        spi_message_add_tail(&st->xfer, &st->msg);
 371
 372        st->freq_xfer[0].tx_buf = &st->freq_data[0];
 373        st->freq_xfer[0].len = 2;
 374        st->freq_xfer[0].cs_change = 1;
 375        st->freq_xfer[1].tx_buf = &st->freq_data[1];
 376        st->freq_xfer[1].len = 2;
 377
 378        spi_message_init(&st->freq_msg);
 379        spi_message_add_tail(&st->freq_xfer[0], &st->freq_msg);
 380        spi_message_add_tail(&st->freq_xfer[1], &st->freq_msg);
 381
 382        st->control = AD9834_B28 | AD9834_RESET;
 383
 384        if (!pdata->en_div2)
 385                st->control |= AD9834_DIV2;
 386
 387        if (!pdata->en_signbit_msb_out && (st->devid == ID_AD9834))
 388                st->control |= AD9834_SIGN_PIB;
 389
 390        st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
 391        ret = spi_sync(st->spi, &st->msg);
 392        if (ret) {
 393                dev_err(&spi->dev, "device init failed\n");
 394                goto error_free_device;
 395        }
 396
 397        ret = ad9834_write_frequency(st, AD9834_REG_FREQ0, pdata->freq0);
 398        if (ret)
 399                goto error_free_device;
 400
 401        ret = ad9834_write_frequency(st, AD9834_REG_FREQ1, pdata->freq1);
 402        if (ret)
 403                goto error_free_device;
 404
 405        ret = ad9834_write_phase(st, AD9834_REG_PHASE0, pdata->phase0);
 406        if (ret)
 407                goto error_free_device;
 408
 409        ret = ad9834_write_phase(st, AD9834_REG_PHASE1, pdata->phase1);
 410        if (ret)
 411                goto error_free_device;
 412
 413        ret = iio_device_register(st->indio_dev);
 414        if (ret)
 415                goto error_free_device;
 416
 417        return 0;
 418
 419error_free_device:
 420        iio_free_device(st->indio_dev);
 421error_disable_reg:
 422        if (!IS_ERR(st->reg))
 423                regulator_disable(st->reg);
 424error_put_reg:
 425        if (!IS_ERR(st->reg))
 426                regulator_put(st->reg);
 427        kfree(st);
 428error_ret:
 429        return ret;
 430}
 431
 432static int __devexit ad9834_remove(struct spi_device *spi)
 433{
 434        struct ad9834_state *st = spi_get_drvdata(spi);
 435
 436        iio_device_unregister(st->indio_dev);
 437        if (!IS_ERR(st->reg)) {
 438                regulator_disable(st->reg);
 439                regulator_put(st->reg);
 440        }
 441        kfree(st);
 442        return 0;
 443}
 444
 445static const struct spi_device_id ad9834_id[] = {
 446        {"ad9833", ID_AD9833},
 447        {"ad9834", ID_AD9834},
 448        {}
 449};
 450
 451static struct spi_driver ad9834_driver = {
 452        .driver = {
 453                .name   = "ad9834",
 454                .bus    = &spi_bus_type,
 455                .owner  = THIS_MODULE,
 456        },
 457        .probe          = ad9834_probe,
 458        .remove         = __devexit_p(ad9834_remove),
 459        .id_table       = ad9834_id,
 460};
 461
 462static int __init ad9834_init(void)
 463{
 464        return spi_register_driver(&ad9834_driver);
 465}
 466module_init(ad9834_init);
 467
 468static void __exit ad9834_exit(void)
 469{
 470        spi_unregister_driver(&ad9834_driver);
 471}
 472module_exit(ad9834_exit);
 473
 474MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
 475MODULE_DESCRIPTION("Analog Devices AD9833/AD9834 DDS");
 476MODULE_LICENSE("GPL v2");
 477MODULE_ALIAS("spi:ad9834");
 478