linux/drivers/staging/iio/dds/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
  18#include "../iio.h"
  19#include "../sysfs.h"
  20
  21#define DRV_NAME "ad9852"
  22
  23#define addr_phaad1 0x0
  24#define addr_phaad2 0x1
  25#define addr_fretu1 0x2
  26#define addr_fretu2 0x3
  27#define addr_delfre 0x4
  28#define addr_updclk 0x5
  29#define addr_ramclk 0x6
  30#define addr_contrl 0x7
  31#define addr_optskm 0x8
  32#define addr_optskr 0xa
  33#define addr_dacctl 0xb
  34
  35#define COMPPD          (1 << 4)
  36#define REFMULT2        (1 << 2)
  37#define BYPPLL          (1 << 5)
  38#define PLLRANG         (1 << 6)
  39#define IEUPCLK         (1)
  40#define OSKEN           (1 << 5)
  41
  42#define read_bit        (1 << 7)
  43
  44/* Register format: 1 byte addr + value */
  45struct ad9852_config {
  46        u8 phajst0[3];
  47        u8 phajst1[3];
  48        u8 fretun1[6];
  49        u8 fretun2[6];
  50        u8 dltafre[6];
  51        u8 updtclk[5];
  52        u8 ramprat[4];
  53        u8 control[5];
  54        u8 outpskm[3];
  55        u8 outpskr[2];
  56        u8 daccntl[3];
  57};
  58
  59struct ad9852_state {
  60        struct mutex lock;
  61        struct iio_dev *idev;
  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_message msg;
  71        struct spi_transfer xfer;
  72        int ret;
  73        struct ad9852_config *config = (struct ad9852_config *)buf;
  74        struct iio_dev *idev = dev_get_drvdata(dev);
  75        struct ad9852_state *st = idev->dev_data;
  76
  77        xfer.len = 3;
  78        xfer.tx_buf = &config->phajst0[0];
  79        mutex_lock(&st->lock);
  80
  81        spi_message_init(&msg);
  82        spi_message_add_tail(&xfer, &msg);
  83        ret = spi_sync(st->sdev, &msg);
  84        if (ret)
  85                goto error_ret;
  86
  87        xfer.len = 3;
  88        xfer.tx_buf = &config->phajst1[0];
  89
  90        spi_message_init(&msg);
  91        spi_message_add_tail(&xfer, &msg);
  92        ret = spi_sync(st->sdev, &msg);
  93        if (ret)
  94                goto error_ret;
  95
  96        xfer.len = 6;
  97        xfer.tx_buf = &config->fretun1[0];
  98
  99        spi_message_init(&msg);
 100        spi_message_add_tail(&xfer, &msg);
 101        ret = spi_sync(st->sdev, &msg);
 102        if (ret)
 103                goto error_ret;
 104
 105        xfer.len = 6;
 106        xfer.tx_buf = &config->fretun2[0];
 107
 108        spi_message_init(&msg);
 109        spi_message_add_tail(&xfer, &msg);
 110        ret = spi_sync(st->sdev, &msg);
 111        if (ret)
 112                goto error_ret;
 113
 114        xfer.len = 6;
 115        xfer.tx_buf = &config->dltafre[0];
 116
 117        spi_message_init(&msg);
 118        spi_message_add_tail(&xfer, &msg);
 119        ret = spi_sync(st->sdev, &msg);
 120        if (ret)
 121                goto error_ret;
 122
 123        xfer.len = 5;
 124        xfer.tx_buf = &config->updtclk[0];
 125
 126        spi_message_init(&msg);
 127        spi_message_add_tail(&xfer, &msg);
 128        ret = spi_sync(st->sdev, &msg);
 129        if (ret)
 130                goto error_ret;
 131
 132        xfer.len = 4;
 133        xfer.tx_buf = &config->ramprat[0];
 134
 135        spi_message_init(&msg);
 136        spi_message_add_tail(&xfer, &msg);
 137        ret = spi_sync(st->sdev, &msg);
 138        if (ret)
 139                goto error_ret;
 140
 141        xfer.len = 5;
 142        xfer.tx_buf = &config->control[0];
 143
 144        spi_message_init(&msg);
 145        spi_message_add_tail(&xfer, &msg);
 146        ret = spi_sync(st->sdev, &msg);
 147        if (ret)
 148                goto error_ret;
 149
 150        xfer.len = 3;
 151        xfer.tx_buf = &config->outpskm[0];
 152
 153        spi_message_init(&msg);
 154        spi_message_add_tail(&xfer, &msg);
 155        ret = spi_sync(st->sdev, &msg);
 156        if (ret)
 157                goto error_ret;
 158
 159        xfer.len = 2;
 160        xfer.tx_buf = &config->outpskr[0];
 161
 162        spi_message_init(&msg);
 163        spi_message_add_tail(&xfer, &msg);
 164        ret = spi_sync(st->sdev, &msg);
 165        if (ret)
 166                goto error_ret;
 167
 168        xfer.len = 3;
 169        xfer.tx_buf = &config->daccntl[0];
 170
 171        spi_message_init(&msg);
 172        spi_message_add_tail(&xfer, &msg);
 173        ret = spi_sync(st->sdev, &msg);
 174        if (ret)
 175                goto error_ret;
 176error_ret:
 177        mutex_unlock(&st->lock);
 178
 179        return ret ? ret : len;
 180}
 181
 182static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9852_set_parameter, 0);
 183
 184static void ad9852_init(struct ad9852_state *st)
 185{
 186        struct spi_message msg;
 187        struct spi_transfer xfer;
 188        int ret;
 189        u8 config[5];
 190
 191        config[0] = addr_contrl;
 192        config[1] = COMPPD;
 193        config[2] = REFMULT2 | BYPPLL | PLLRANG;
 194        config[3] = IEUPCLK;
 195        config[4] = OSKEN;
 196
 197        mutex_lock(&st->lock);
 198
 199        xfer.len = 5;
 200        xfer.tx_buf = &config;
 201
 202        spi_message_init(&msg);
 203        spi_message_add_tail(&xfer, &msg);
 204        ret = spi_sync(st->sdev, &msg);
 205        if (ret)
 206                goto error_ret;
 207
 208error_ret:
 209        mutex_unlock(&st->lock);
 210
 211
 212
 213}
 214
 215static struct attribute *ad9852_attributes[] = {
 216        &iio_dev_attr_dds.dev_attr.attr,
 217        NULL,
 218};
 219
 220static const struct attribute_group ad9852_attribute_group = {
 221        .name = DRV_NAME,
 222        .attrs = ad9852_attributes,
 223};
 224
 225static int __devinit ad9852_probe(struct spi_device *spi)
 226{
 227        struct ad9852_state *st;
 228        int ret = 0;
 229
 230        st = kzalloc(sizeof(*st), GFP_KERNEL);
 231        if (st == NULL) {
 232                ret = -ENOMEM;
 233                goto error_ret;
 234        }
 235        spi_set_drvdata(spi, st);
 236
 237        mutex_init(&st->lock);
 238        st->sdev = spi;
 239
 240        st->idev = iio_allocate_device();
 241        if (st->idev == NULL) {
 242                ret = -ENOMEM;
 243                goto error_free_st;
 244        }
 245        st->idev->dev.parent = &spi->dev;
 246        st->idev->num_interrupt_lines = 0;
 247        st->idev->event_attrs = NULL;
 248
 249        st->idev->attrs = &ad9852_attribute_group;
 250        st->idev->dev_data = (void *)(st);
 251        st->idev->driver_module = THIS_MODULE;
 252        st->idev->modes = INDIO_DIRECT_MODE;
 253
 254        ret = iio_device_register(st->idev);
 255        if (ret)
 256                goto error_free_dev;
 257        spi->max_speed_hz = 2000000;
 258        spi->mode = SPI_MODE_3;
 259        spi->bits_per_word = 8;
 260        spi_setup(spi);
 261        ad9852_init(st);
 262        return 0;
 263
 264error_free_dev:
 265        iio_free_device(st->idev);
 266error_free_st:
 267        kfree(st);
 268error_ret:
 269        return ret;
 270}
 271
 272static int __devexit ad9852_remove(struct spi_device *spi)
 273{
 274        struct ad9852_state *st = spi_get_drvdata(spi);
 275
 276        iio_device_unregister(st->idev);
 277        kfree(st);
 278
 279        return 0;
 280}
 281
 282static struct spi_driver ad9852_driver = {
 283        .driver = {
 284                .name = DRV_NAME,
 285                .owner = THIS_MODULE,
 286        },
 287        .probe = ad9852_probe,
 288        .remove = __devexit_p(ad9852_remove),
 289};
 290
 291static __init int ad9852_spi_init(void)
 292{
 293        return spi_register_driver(&ad9852_driver);
 294}
 295module_init(ad9852_spi_init);
 296
 297static __exit void ad9852_spi_exit(void)
 298{
 299        spi_unregister_driver(&ad9852_driver);
 300}
 301module_exit(ad9852_spi_exit);
 302
 303MODULE_AUTHOR("Cliff Cai");
 304MODULE_DESCRIPTION("Analog Devices ad9852 driver");
 305MODULE_LICENSE("GPL v2");
 306