lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Thu, 2 Dec 2010 22:35:06 +0530
From:	"Datta, Shubhrajyoti" <shubhrajyoti@...com>
To:	"michael.hennerich@...log.com" <michael.hennerich@...log.com>,
	"linux-iio@...r.kernel.org" <linux-iio@...r.kernel.org>,
	"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
CC:	"drivers@...log.com" <drivers@...log.com>,
	"jic23@....ac.uk" <jic23@....ac.uk>,
	"device-drivers-devel@...ckfin.uclinux.org" 
	<device-drivers-devel@...ckfin.uclinux.org>
Subject: RE: [RFC 3/3] IIO: DDS: AD9833 / AD9834 driver



> -----Original Message-----
> From: linux-iio-owner@...r.kernel.org [mailto:linux-iio-
> owner@...r.kernel.org] On Behalf Of michael.hennerich@...log.com
> Sent: Thursday, December 02, 2010 5:51 PM
> To: linux-iio@...r.kernel.org; linux-kernel@...r.kernel.org
> Cc: drivers@...log.com; jic23@....ac.uk; device-drivers-
> devel@...ckfin.uclinux.org; Michael Hennerich
> Subject: [RFC 3/3] IIO: DDS: AD9833 / AD9834 driver
>
> From: Michael Hennerich <michael.hennerich@...log.com>
>
> Example driver using the proposed ABI
>
> Signed-off-by: Michael Hennerich <michael.hennerich@...log.com>
> ---
>  drivers/staging/iio/dds/Kconfig  |    7 +
>  drivers/staging/iio/dds/Makefile |    1 +
>  drivers/staging/iio/dds/ad9834.c |  483
> ++++++++++++++++++++++++++++++++++++++
>  drivers/staging/iio/dds/ad9834.h |  112 +++++++++
>  4 files changed, 603 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/staging/iio/dds/ad9834.c
>  create mode 100644 drivers/staging/iio/dds/ad9834.h
>
> diff --git a/drivers/staging/iio/dds/Kconfig
> b/drivers/staging/iio/dds/Kconfig
> index 7969be2..4c9cce3 100644
> --- a/drivers/staging/iio/dds/Kconfig
> +++ b/drivers/staging/iio/dds/Kconfig
> @@ -17,6 +17,13 @@ config AD9832
>         Say yes here to build support for Analog Devices DDS chip
>         ad9832 and ad9835, provides direct access via sysfs.
>
> +config AD9834
> +     tristate "Analog Devices ad9833/4/ driver"
> +     depends on SPI
> +     help
> +       Say yes here to build support for Analog Devices DDS chip
> +       AD9833 and AD9834, provides direct access via sysfs.
> +
>  config AD9850
>       tristate "Analog Devices ad9850/1 driver"
>       depends on SPI
> diff --git a/drivers/staging/iio/dds/Makefile
> b/drivers/staging/iio/dds/Makefile
> index 6f274ac..1477461 100644
> --- a/drivers/staging/iio/dds/Makefile
> +++ b/drivers/staging/iio/dds/Makefile
> @@ -4,6 +4,7 @@
>
>  obj-$(CONFIG_AD5930) += ad5930.o
>  obj-$(CONFIG_AD9832) += ad9832.o
> +obj-$(CONFIG_AD9834) += ad9834.o
>  obj-$(CONFIG_AD9850) += ad9850.o
>  obj-$(CONFIG_AD9852) += ad9852.o
>  obj-$(CONFIG_AD9910) += ad9910.o
> diff --git a/drivers/staging/iio/dds/ad9834.c
> b/drivers/staging/iio/dds/ad9834.c
> new file mode 100644
> index 0000000..eb1fabf
> --- /dev/null
> +++ b/drivers/staging/iio/dds/ad9834.c
> @@ -0,0 +1,483 @@
> +/*
> + * AD9834 SPI DAC driver
> + *
> + * Copyright 2010 Analog Devices Inc.
> + *
> + * Licensed under the GPL-2 or later.
> + */
> +
> +#include <linux/interrupt.h>
> +#include <linux/workqueue.h>
> +#include <linux/device.h>
> +#include <linux/kernel.h>
> +#include <linux/slab.h>
> +#include <linux/sysfs.h>
> +#include <linux/list.h>
> +#include <linux/spi/spi.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/err.h>
> +#include <asm/div64.h>
> +
> +#include "../iio.h"
> +#include "../sysfs.h"
> +#include "dds.h"
> +
> +#include "ad9834.h"
> +
> +static unsigned int ad9834_calc_freqreg(unsigned long mclk, unsigned long
> fout)
> +{
> +     unsigned long long freqreg = (u64) fout * (u64) (1 <<
> AD9834_FREQ_BITS);
> +     do_div(freqreg, mclk);
> +     return freqreg;
> +}
> +
> +static int ad9834_write_frequency(struct ad9834_state *st,
> +                               unsigned long addr, unsigned long fout)
> +{
> +     unsigned long regval;
> +
> +     if (fout > (st->mclk / 2))
> +             return -EINVAL;
> +
> +     regval = ad9834_calc_freqreg(st->mclk, fout);
> +
> +     st->freq_data[0] = cpu_to_be16(addr | (regval &
> +                                    RES_MASK(AD9834_FREQ_BITS / 2)));
> +     st->freq_data[1] = cpu_to_be16(addr | ((regval >>
> +                                    (AD9834_FREQ_BITS / 2)) &
> +                                    RES_MASK(AD9834_FREQ_BITS / 2)));
> +
> +     return spi_sync(st->spi, &st->freq_msg);;
> +}
> +
> +static int ad9834_write_phase(struct ad9834_state *st,
> +                               unsigned long addr, unsigned long phase)
> +{
> +     if (phase > (1 << AD9834_PHASE_BITS))
> +             return -EINVAL;
> +     st->data = cpu_to_be16(addr | phase);
> +
> +     return spi_sync(st->spi, &st->msg);
> +}
> +
> +static ssize_t ad9834_write(struct device *dev,
> +             struct device_attribute *attr,
> +             const char *buf,
> +             size_t len)
> +{
> +     struct iio_dev *dev_info = dev_get_drvdata(dev);
> +     struct ad9834_state *st = dev_info->dev_data;
> +     struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
> +     int ret;
> +     long val;
> +
> +     ret = strict_strtol(buf, 10, &val);
> +     if (ret)
> +             goto error_ret;
Could we do some bounds check.
> +
> +     mutex_lock(&dev_info->mlock);
> +     switch (this_attr->address) {
> +     case AD9834_REG_FREQ0:
> +     case AD9834_REG_FREQ1:
> +             ret = ad9834_write_frequency(st, this_attr->address, val);
> +             break;
> +     case AD9834_REG_PHASE0:
> +     case AD9834_REG_PHASE1:
> +             ret = ad9834_write_phase(st, this_attr->address, val);
> +             break;
> +
> +     case AD9834_OPBITEN:
> +             if (st->control & AD9834_MODE) {
> +                     ret = -EINVAL;  /* AD9843 reserved mode */
> +                     break;
> +             }
> +
> +             if (val)
> +                     st->control &= ~AD9834_OPBITEN;
> +             else
> +                     st->control |= AD9834_OPBITEN;
> +             st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
> +             ret = spi_sync(st->spi, &st->msg);
> +             break;
> +
> +     case AD9834_PIN_SW:
> +             if (val)
> +                     st->control |= AD9834_PIN_SW;
> +             else
> +                     st->control &= ~AD9834_PIN_SW;
> +             st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
> +             ret = spi_sync(st->spi, &st->msg);
> +             break;
> +     case AD9834_FSEL:
> +     case AD9834_PSEL:
> +             if (val == 0)
> +                     st->control &= ~(this_attr->address | AD9834_PIN_SW);
> +             else if (val == 1) {
> +                     st->control |= this_attr->address;
> +                     st->control &= ~AD9834_PIN_SW;
> +             } else {
> +                     ret = -EINVAL;
> +                     break;
> +             }
> +             st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
> +             ret = spi_sync(st->spi, &st->msg);
> +             break;
> +     case AD9834_RESET:
> +             if (val)
> +                     st->control |= AD9834_RESET;
> +             else
> +                     st->control &= ~AD9834_RESET;
> +             st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
> +             ret = spi_sync(st->spi, &st->msg);
> +             break;
> +     default:
> +             ret = -ENODEV;
> +     }
> +     mutex_unlock(&dev_info->mlock);
> +
> +error_ret:
> +     return ret ? ret : len;
> +}
> +
> +static ssize_t ad9834_store_wavetype(struct device *dev,
> +                              struct device_attribute *attr,
> +                              const char *buf,
> +                              size_t len)
> +{
> +     struct iio_dev *dev_info = dev_get_drvdata(dev);
> +     struct ad9834_state *st = dev_info->dev_data;
> +     struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
> +     int ret = 0;
> +     bool is_ad9833 = st->devid == ID_AD9833;
> +
> +     mutex_lock(&dev_info->mlock);
> +
> +     switch (this_attr->address) {
> +     case 0:
> +             if (sysfs_streq(buf, "sine")) {
> +                     st->control &= ~AD9834_MODE;
> +                     if (is_ad9833)
> +                             st->control &= ~AD9834_OPBITEN;
> +             } else if (sysfs_streq(buf, "triangle")) {
> +                     if (is_ad9833) {
> +                             st->control &= ~AD9834_OPBITEN;
> +                             st->control |= AD9834_MODE;
> +                     } else if (st->control & AD9834_OPBITEN) {
> +                             ret = -EINVAL;  /* AD9843 reserved mode */
> +                     } else {
> +                             st->control |= AD9834_MODE;
> +                     }
> +             } else if (is_ad9833 && sysfs_streq(buf, "square")) {
> +                     st->control &= ~AD9834_MODE;
> +                     st->control |= AD9834_OPBITEN;
> +             } else {
> +                     ret = -EINVAL;
> +             }
> +
> +             break;
> +     case 1:
> +             if (sysfs_streq(buf, "square") &&
> +                     !(st->control & AD9834_MODE)) {
> +                     st->control &= ~AD9834_MODE;
> +                     st->control |= AD9834_OPBITEN;
> +             } else {
> +                     ret = -EINVAL;
> +             }
> +             break;
> +     default:
> +             ret = -EINVAL;
> +             break;
> +     }
> +
> +     if (!ret) {
> +             st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
> +             ret = spi_sync(st->spi, &st->msg);
> +     }
> +             mutex_unlock(&dev_info->mlock);
> +
> +     return ret ? ret : len;
> +}
> +
> +static ssize_t ad9834_show_name(struct device *dev,
> +                              struct device_attribute *attr,
> +                              char *buf)
> +{
> +     struct iio_dev *dev_info = dev_get_drvdata(dev);
> +     struct ad9834_state *st = iio_dev_get_devdata(dev_info);
> +
> +     return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name);
> +}
> +static IIO_DEVICE_ATTR(name, S_IRUGO, ad9834_show_name, NULL, 0);
> +
> +static ssize_t ad9834_show_out0_available_wavetypes(struct device *dev,
> +                                             struct device_attribute *attr,
> +                                             char *buf)
> +{
> +     struct iio_dev *dev_info = dev_get_drvdata(dev);
> +     struct ad9834_state *st = iio_dev_get_devdata(dev_info);
> +     char *str;
> +
> +     if (st->devid == ID_AD9833)
> +             str = "sine triangle square";
> +     else if (st->control & AD9834_OPBITEN)
> +             str = "sine";
> +     else
> +             str = "sine triangle";
> +
> +     return sprintf(buf, "%s\n", str);
> +}
> +
> +
> +static IIO_DEVICE_ATTR(dds0_out0_available_wavetypes, S_IRUGO,
> +                    ad9834_show_out0_available_wavetypes, NULL, 0);
> +
> +static ssize_t ad9834_show_out1_available_wavetypes(struct device *dev,
> +                                             struct device_attribute *attr,
> +                                             char *buf)
> +{
> +     struct iio_dev *dev_info = dev_get_drvdata(dev);
> +     struct ad9834_state *st = iio_dev_get_devdata(dev_info);
> +     char *str;
> +
> +     if (st->control & AD9834_MODE)
> +             str = "";
> +     else
> +             str = "square";
> +
> +     return sprintf(buf, "%s\n", str);
> +}
> +
> +static IIO_DEVICE_ATTR(dds0_out1_available_wavetypes, S_IRUGO,
> +                    ad9834_show_out1_available_wavetypes, NULL, 0);
> +
> +/**
> + * see dds.h for further information
> + */
> +
> +
> +static IIO_DEV_ATTR_FREQ(0, 0, ad9834_write, AD9834_REG_FREQ0);
> +static IIO_DEV_ATTR_FREQ(0, 1, ad9834_write, AD9834_REG_FREQ1);
> +static IIO_DEV_ATTR_FREQSYMBOL(0, ad9834_write, AD9834_FSEL);
> +static IIO_CONST_ATTR_FREQ_SCALE(0, "1"); /* 1Hz */
> +
> +static IIO_DEV_ATTR_PHASE(0, 0, ad9834_write, AD9834_REG_PHASE0);
> +static IIO_DEV_ATTR_PHASE(0, 1, ad9834_write, AD9834_REG_PHASE1);
> +static IIO_DEV_ATTR_PHASESYMBOL(0, ad9834_write, AD9834_PSEL);
> +static IIO_CONST_ATTR_PHASE_SCALE(0, "0.0015339808"); /* 2PI/2^12 rad*/
> +
> +static IIO_DEV_ATTR_PINCONTROL_EN(0, ad9834_write, AD9834_PIN_SW);
> +static IIO_DEV_ATTR_OUT_DISABLE(0, ad9834_write, AD9834_RESET);
> +static IIO_DEV_ATTR_OUTY_DISABLE(0, 1, ad9834_write, AD9834_OPBITEN);
> +static IIO_DEV_ATTR_OUT_WAVETYPE(0, 0, ad9834_store_wavetype, 0);
> +static IIO_DEV_ATTR_OUT_WAVETYPE(0, 1, ad9834_store_wavetype, 1);
> +
> +static struct attribute *ad9834_attributes[] = {
> +     &iio_dev_attr_dds0_freq0.dev_attr.attr,
> +     &iio_dev_attr_dds0_freq1.dev_attr.attr,
> +     &iio_const_attr_dds0_freq_scale.dev_attr.attr,
> +     &iio_dev_attr_dds0_phase0.dev_attr.attr,
> +     &iio_dev_attr_dds0_phase1.dev_attr.attr,
> +     &iio_const_attr_dds0_phase_scale.dev_attr.attr,
> +     &iio_dev_attr_dds0_pincontrol_en.dev_attr.attr,
> +     &iio_dev_attr_dds0_freqsymbol.dev_attr.attr,
> +     &iio_dev_attr_dds0_phasesymbol.dev_attr.attr,
> +     &iio_dev_attr_dds0_out_disable.dev_attr.attr,
> +     &iio_dev_attr_dds0_out1_disable.dev_attr.attr,
> +     &iio_dev_attr_dds0_out0_wavetype.dev_attr.attr,
> +     &iio_dev_attr_dds0_out1_wavetype.dev_attr.attr,
> +     &iio_dev_attr_dds0_out0_available_wavetypes.dev_attr.attr,
> +     &iio_dev_attr_dds0_out1_available_wavetypes.dev_attr.attr,
> +     &iio_dev_attr_name.dev_attr.attr,
> +     NULL,
> +};
> +
> +static mode_t ad9834_attr_is_visible(struct kobject *kobj,
> +                                  struct attribute *attr, int n)
> +{
> +     struct device *dev = container_of(kobj, struct device, kobj);
> +     struct iio_dev *dev_info = dev_get_drvdata(dev);
> +     struct ad9834_state *st = iio_dev_get_devdata(dev_info);
> +
> +     mode_t mode = attr->mode;
> +
> +     if (st->devid == ID_AD9834)
> +             return mode;
> +
> +     if ((attr == &iio_dev_attr_dds0_out1_disable.dev_attr.attr) ||
> +             (attr == &iio_dev_attr_dds0_out1_wavetype.dev_attr.attr) ||
> +             (attr ==
> +             &iio_dev_attr_dds0_out1_available_wavetypes.dev_attr.attr))
> +             mode = 0;
> +
> +     return mode;
> +}
> +
> +static const struct attribute_group ad9834_attribute_group = {
> +     .attrs = ad9834_attributes,
> +     .is_visible = ad9834_attr_is_visible,
> +};
> +
> +static int __devinit ad9834_probe(struct spi_device *spi)
> +{
> +     struct ad9834_platform_data *pdata = spi->dev.platform_data;
> +     struct ad9834_state *st;
> +     int ret;
> +
> +     if (!pdata) {
> +             dev_dbg(&spi->dev, "no platform data?\n");
> +             return -ENODEV;
> +     }
> +
> +     st = kzalloc(sizeof(*st), GFP_KERNEL);
> +     if (st == NULL) {
> +             ret = -ENOMEM;
> +             goto error_ret;
> +     }
> +
> +     st->reg = regulator_get(&spi->dev, "vcc");
> +     if (!IS_ERR(st->reg)) {
> +             ret = regulator_enable(st->reg);
> +             if (ret)
> +                     goto error_put_reg;
> +     }
> +
> +     st->mclk = pdata->mclk;
> +
> +     spi_set_drvdata(spi, st);
> +
> +     st->spi = spi;
> +     st->devid = spi_get_device_id(spi)->driver_data;
> +
> +     st->indio_dev = iio_allocate_device();
> +     if (st->indio_dev == NULL) {
> +             ret = -ENOMEM;
> +             goto error_disable_reg;
> +     }
> +
> +     st->indio_dev->dev.parent = &spi->dev;
> +     st->indio_dev->attrs = &ad9834_attribute_group;
> +     st->indio_dev->dev_data = (void *)(st);
> +     st->indio_dev->driver_module = THIS_MODULE;
> +     st->indio_dev->modes = INDIO_DIRECT_MODE;
> +
> +     /* Setup default messages */
> +
> +     st->xfer.tx_buf = &st->data;
> +     st->xfer.len = 2;
> +
> +     spi_message_init(&st->msg);
> +     spi_message_add_tail(&st->xfer, &st->msg);
> +
> +     st->freq_xfer[0].tx_buf = &st->freq_data[0];
> +     st->freq_xfer[0].len = 2;
> +     st->freq_xfer[0].cs_change = 1;
> +     st->freq_xfer[1].tx_buf = &st->freq_data[1];
> +     st->freq_xfer[1].len = 2;
> +
> +     spi_message_init(&st->freq_msg);
> +     spi_message_add_tail(&st->freq_xfer[0], &st->freq_msg);
> +     spi_message_add_tail(&st->freq_xfer[1], &st->freq_msg);
> +
> +     st->control = AD9834_B28 | AD9834_RESET;
> +
> +     if (!pdata->en_div2)
> +             st->control |= AD9834_DIV2;
> +
> +     if (!pdata->en_signbit_msb_out && (st->devid == ID_AD9834))
> +             st->control |= AD9834_SIGN_PIB;
> +
> +     st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
> +     ret = spi_sync(st->spi, &st->msg);
> +     if (ret) {
> +             dev_err(&spi->dev, "device init failed\n");
> +             goto error_free_device;
> +     }
> +
> +     ret = ad9834_write_frequency(st, AD9834_REG_FREQ0, pdata->freq0);
> +     if (ret)
> +             goto error_free_device;
> +
> +     ret = ad9834_write_frequency(st, AD9834_REG_FREQ1, pdata->freq1);
> +     if (ret)
> +             goto error_free_device;
> +
> +     ret = ad9834_write_phase(st, AD9834_REG_PHASE0, pdata->phase0);
> +     if (ret)
> +             goto error_free_device;
> +
> +     ret = ad9834_write_phase(st, AD9834_REG_PHASE1, pdata->phase1);
> +     if (ret)
> +             goto error_free_device;
> +
> +     st->control &= ~AD9834_RESET;
> +     st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
> +     ret = spi_sync(st->spi, &st->msg);
> +     if (ret)
> +             goto error_free_device;
> +
> +     ret = iio_device_register(st->indio_dev);
> +     if (ret)
> +             goto error_free_device;
> +
> +     return 0;
> +
> +error_free_device:
> +     iio_free_device(st->indio_dev);
> +error_disable_reg:
> +     if (!IS_ERR(st->reg))
> +             regulator_disable(st->reg);
> +error_put_reg:
> +     if (!IS_ERR(st->reg))
> +             regulator_put(st->reg);
> +     kfree(st);
> +error_ret:
> +     return ret;
> +}
> +
> +static int ad9834_remove(struct spi_device *spi)
Could we consider __devexit here
> +{
> +     struct ad9834_state *st = spi_get_drvdata(spi);
> +     struct iio_dev *indio_dev = st->indio_dev;
> +
> +     iio_device_unregister(indio_dev);
> +     if (!IS_ERR(st->reg)) {
> +             regulator_disable(st->reg);
> +             regulator_put(st->reg);
> +     }
> +     kfree(st);
> +     return 0;
> +}
> +
> +static const struct spi_device_id ad9834_id[] = {
> +     {"ad9833", ID_AD9833},
> +     {"ad9834", ID_AD9834},
> +     {}
> +};
> +
> +static struct spi_driver ad9834_driver = {
> +     .driver = {
> +             .name   = "ad9834",
> +             .bus    = &spi_bus_type,
> +             .owner  = THIS_MODULE,
> +     },
> +     .probe          = ad9834_probe,
> +     .remove         = __devexit_p(ad9834_remove),
> +     .id_table       = ad9834_id,
> +};
> +
> +static int __init ad9834_init(void)
> +{
> +     return spi_register_driver(&ad9834_driver);
> +}
> +module_init(ad9834_init);
> +
> +static void __exit ad9834_exit(void)
> +{
> +     spi_unregister_driver(&ad9834_driver);
> +}
> +module_exit(ad9834_exit);
> +
> +MODULE_AUTHOR("Michael Hennerich <hennerich@...ckfin.uclinux.org>");
> +MODULE_DESCRIPTION("Analog Devices AD9833/AD9834 DDS");
> +MODULE_LICENSE("GPL v2");
> +MODULE_ALIAS("spi:ad9834");
> diff --git a/drivers/staging/iio/dds/ad9834.h
> b/drivers/staging/iio/dds/ad9834.h
> new file mode 100644
> index 0000000..0fc3b88
> --- /dev/null
> +++ b/drivers/staging/iio/dds/ad9834.h
> @@ -0,0 +1,112 @@
> +/*
> + * AD9834 SPI DDS driver
> + *
> + * Copyright 2010 Analog Devices Inc.
> + *
> + * Licensed under the GPL-2 or later.
> + */
> +#ifndef IIO_DDS_AD9834_H_
> +#define IIO_DDS_AD9834_H_
> +
> +/* Registers */
> +
> +#define AD9834_REG_CMD               (0 << 14)
> +#define AD9834_REG_FREQ0     (1 << 14)
> +#define AD9834_REG_FREQ1     (2 << 14)
> +#define AD9834_REG_PHASE0    (6 << 13)
> +#define AD9834_REG_PHASE1    (7 << 13)
> +
> +/* Command Control Bits */
> +
> +#define AD9834_B28           (1 << 13)
> +#define AD9834_HLB           (1 << 12)
> +#define AD9834_FSEL          (1 << 11)
> +#define AD9834_PSEL          (1 << 10)
> +#define AD9834_PIN_SW                (1 << 9)
> +#define AD9834_RESET         (1 << 8)
> +#define AD9834_SLEEP1                (1 << 7)
> +#define AD9834_SLEEP12               (1 << 6)
> +#define AD9834_OPBITEN               (1 << 5)
> +#define AD9834_SIGN_PIB              (1 << 4)
> +#define AD9834_DIV2          (1 << 3)
> +#define AD9834_MODE          (1 << 1)
> +
> +#define AD9834_FREQ_BITS     28
> +#define AD9834_PHASE_BITS    12
> +
> +#define RES_MASK(bits)       ((1 << (bits)) - 1)
> +
> +/**
> + * struct ad9834_state - driver instance specific data
> + * @indio_dev:               the industrial I/O device
> + * @spi:             spi_device
> + * @reg:             supply regulator
> + * @mclk:            external master clock
> + * @control:         cached control word
> + * @xfer:            default spi transfer
> + * @msg:             default spi message
> + * @freq_xfer:               tuning word spi transfer
> + * @freq_msg:                tuning word spi message
> + * @data:            spi transmit buffer
> + * @freq_data:               tuning word spi transmit buffer
> + */
> +
> +struct ad9834_state {
> +     struct iio_dev                  *indio_dev;
> +     struct spi_device               *spi;
> +     struct regulator                *reg;
> +     unsigned int                    mclk;
> +     unsigned short                  control;
> +     unsigned short                  devid;
> +     struct spi_transfer             xfer;
> +     struct spi_message              msg;
> +     struct spi_transfer             freq_xfer[2];
> +     struct spi_message              freq_msg;
> +
> +     /*
> +      * DMA (thus cache coherency maintenance) requires the
> +      * transfer buffers to live in their own cache lines.
> +      */
> +     unsigned short                  data ____cacheline_aligned;
> +     unsigned short                  freq_data[2] ;
> +};
> +
> +
> +/*
> + * TODO: struct ad7887_platform_data needs to go into include/linux/iio
> + */
> +
> +/**
> + * struct ad9834_platform_data - platform specific information
> + * @mclk:            master clock in Hz
> + * @freq0:           power up freq0 tuning word in Hz
> + * @freq1:           power up freq1 tuning word in Hz
> + * @phase0:          power up phase0 value [0..4095] correlates with
> 0..2PI
> + * @phase1:          power up phase1 value [0..4095] correlates with
> 0..2PI
> + * @en_div2:         digital output/2 is passed to the SIGN BIT OUT pin
> + * @en_signbit_msb_out:      the MSB (or MSB/2) of the DAC data is
> connected to the
> + *                   SIGN BIT OUT pin. en_div2 controls whether it is the MSB
> + *                   or MSB/2 that is output. if en_signbit_msb_out=false,
> + *                   the on-board comparator is connected to SIGN BIT OUT
> + */
> +
> +struct ad9834_platform_data {
> +     unsigned int            mclk;
> +     unsigned int            freq0;
> +     unsigned int            freq1;
> +     unsigned short          phase0;
> +     unsigned short          phase1;
> +     bool                    en_div2;
> +     bool                    en_signbit_msb_out;
> +};
> +
> +/**
> + * ad9834_supported_device_ids:
> + */
> +
> +enum ad9834_supported_device_ids {
> +     ID_AD9833,
> +     ID_AD9834,
> +};
> +
> +#endif /* IIO_DDS_AD9834_H_ */
> --
> 1.6.0.2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@...r.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists