linux/drivers/staging/iio/frequency/ad9852.c
<<
>>
Prefs
   1/*
   2 * Driver for ADI Direct Digital Synthesis ad9852
   3 *
   4 * Copyright (c) 2010 Analog Devices Inc.
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 */
  11#include <linux/types.h>
  12#include <linux/mutex.h>
  13#include <linux/device.h>
  14#include <linux/spi/spi.h>
  15#include <linux/slab.h>
  16#include <linux/sysfs.h>
  17#include <linux/module.h>
  18
  19#include <linux/iio/iio.h>
  20#include <linux/iio/sysfs.h>
  21
  22#define DRV_NAME "ad9852"
  23
  24#define addr_phaad1 0x0
  25#define addr_phaad2 0x1
  26#define addr_fretu1 0x2
  27#define addr_fretu2 0x3
  28#define addr_delfre 0x4
  29#define addr_updclk 0x5
  30#define addr_ramclk 0x6
  31#define addr_contrl 0x7
  32#define addr_optskm 0x8
  33#define addr_optskr 0xa
  34#define addr_dacctl 0xb
  35
  36#define COMPPD          (1 << 4)
  37#define REFMULT2        (1 << 2)
  38#define BYPPLL          (1 << 5)
  39#define PLLRANG         (1 << 6)
  40#define IEUPCLK         (1)
  41#define OSKEN           (1 << 5)
  42
  43#define read_bit        (1 << 7)
  44
  45/* Register format: 1 byte addr + value */
  46struct ad9852_config {
  47        u8 phajst0[3];
  48        u8 phajst1[3];
  49        u8 fretun1[6];
  50        u8 fretun2[6];
  51        u8 dltafre[6];
  52        u8 updtclk[5];
  53        u8 ramprat[4];
  54        u8 control[5];
  55        u8 outpskm[3];
  56        u8 outpskr[2];
  57        u8 daccntl[3];
  58};
  59
  60struct ad9852_state {
  61        struct mutex lock;
  62        struct spi_device *sdev;
  63};
  64
  65static ssize_t ad9852_set_parameter(struct device *dev,
  66                                        struct device_attribute *attr,
  67                                        const char *buf,
  68                                        size_t len)
  69{
  70        struct spi_transfer xfer;
  71        int ret;
  72        struct ad9852_config *config = (struct ad9852_config *)buf;
  73        struct iio_dev *idev = dev_to_iio_dev(dev);
  74        struct ad9852_state *st = iio_priv(idev);
  75
  76        xfer.len = 3;
  77        xfer.tx_buf = &config->phajst0[0];
  78        mutex_lock(&st->lock);
  79
  80        ret = spi_sync_transfer(st->sdev, &xfer, 1);
  81        if (ret)
  82                goto error_ret;
  83
  84        xfer.len = 3;
  85        xfer.tx_buf = &config->phajst1[0];
  86
  87        ret = spi_sync_transfer(st->sdev, &xfer, 1);
  88        if (ret)
  89                goto error_ret;
  90
  91        xfer.len = 6;
  92        xfer.tx_buf = &config->fretun1[0];
  93
  94        ret = spi_sync_transfer(st->sdev, &xfer, 1);
  95        if (ret)
  96                goto error_ret;
  97
  98        xfer.len = 6;
  99        xfer.tx_buf = &config->fretun2[0];
 100
 101        ret = spi_sync_transfer(st->sdev, &xfer, 1);
 102        if (ret)
 103                goto error_ret;
 104
 105        xfer.len = 6;
 106        xfer.tx_buf = &config->dltafre[0];
 107
 108        ret = spi_sync_transfer(st->sdev, &xfer, 1);
 109        if (ret)
 110                goto error_ret;
 111
 112        xfer.len = 5;
 113        xfer.tx_buf = &config->updtclk[0];
 114
 115        ret = spi_sync_transfer(st->sdev, &xfer, 1);
 116        if (ret)
 117                goto error_ret;
 118
 119        xfer.len = 4;
 120        xfer.tx_buf = &config->ramprat[0];
 121
 122        ret = spi_sync_transfer(st->sdev, &xfer, 1);
 123        if (ret)
 124                goto error_ret;
 125
 126        xfer.len = 5;
 127        xfer.tx_buf = &config->control[0];
 128
 129        ret = spi_sync_transfer(st->sdev, &xfer, 1);
 130        if (ret)
 131                goto error_ret;
 132
 133        xfer.len = 3;
 134        xfer.tx_buf = &config->outpskm[0];
 135
 136        ret = spi_sync_transfer(st->sdev, &xfer, 1);
 137        if (ret)
 138                goto error_ret;
 139
 140        xfer.len = 2;
 141        xfer.tx_buf = &config->outpskr[0];
 142
 143        ret = spi_sync_transfer(st->sdev, &xfer, 1);
 144        if (ret)
 145                goto error_ret;
 146
 147        xfer.len = 3;
 148        xfer.tx_buf = &config->daccntl[0];
 149
 150        ret = spi_sync_transfer(st->sdev, &xfer, 1);
 151        if (ret)
 152                goto error_ret;
 153error_ret:
 154        mutex_unlock(&st->lock);
 155
 156        return ret ? ret : len;
 157}
 158
 159static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9852_set_parameter, 0);
 160
 161static void ad9852_init(struct ad9852_state *st)
 162{
 163        struct spi_transfer xfer;
 164        int ret;
 165        u8 config[5];
 166
 167        config[0] = addr_contrl;
 168        config[1] = COMPPD;
 169        config[2] = REFMULT2 | BYPPLL | PLLRANG;
 170        config[3] = IEUPCLK;
 171        config[4] = OSKEN;
 172
 173        mutex_lock(&st->lock);
 174
 175        xfer.len = 5;
 176        xfer.tx_buf = &config;
 177
 178        ret = spi_sync_transfer(st->sdev, &xfer, 1);
 179        if (ret)
 180                goto error_ret;
 181
 182error_ret:
 183        mutex_unlock(&st->lock);
 184
 185
 186
 187}
 188
 189static struct attribute *ad9852_attributes[] = {
 190        &iio_dev_attr_dds.dev_attr.attr,
 191        NULL,
 192};
 193
 194static const struct attribute_group ad9852_attribute_group = {
 195        .attrs = ad9852_attributes,
 196};
 197
 198static const struct iio_info ad9852_info = {
 199        .attrs = &ad9852_attribute_group,
 200        .driver_module = THIS_MODULE,
 201};
 202
 203static int ad9852_probe(struct spi_device *spi)
 204{
 205        struct ad9852_state *st;
 206        struct iio_dev *idev;
 207        int ret = 0;
 208
 209        idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 210        if (!idev)
 211                return -ENOMEM;
 212        st = iio_priv(idev);
 213        spi_set_drvdata(spi, idev);
 214        mutex_init(&st->lock);
 215        st->sdev = spi;
 216
 217        idev->dev.parent = &spi->dev;
 218        idev->info = &ad9852_info;
 219        idev->modes = INDIO_DIRECT_MODE;
 220
 221        ret = iio_device_register(idev);
 222        if (ret)
 223                return ret;
 224        spi->max_speed_hz = 2000000;
 225        spi->mode = SPI_MODE_3;
 226        spi->bits_per_word = 8;
 227        spi_setup(spi);
 228        ad9852_init(st);
 229
 230        return 0;
 231}
 232
 233static int ad9852_remove(struct spi_device *spi)
 234{
 235        iio_device_unregister(spi_get_drvdata(spi));
 236
 237        return 0;
 238}
 239
 240static struct spi_driver ad9852_driver = {
 241        .driver = {
 242                .name = DRV_NAME,
 243                .owner = THIS_MODULE,
 244        },
 245        .probe = ad9852_probe,
 246        .remove = ad9852_remove,
 247};
 248module_spi_driver(ad9852_driver);
 249
 250MODULE_AUTHOR("Cliff Cai");
 251MODULE_DESCRIPTION("Analog Devices ad9852 driver");
 252MODULE_LICENSE("GPL v2");
 253MODULE_ALIAS("spi:" DRV_NAME);
 254