linux/drivers/staging/iio/resolver/ad2s1200.c
<<
>>
Prefs
   1/*
   2 * ad2s1200.c simple support for the ADI Resolver to Digital Converters:
   3 * AD2S1200/1205
   4 *
   5 * Copyright (c) 2010-2010 Analog Devices Inc.
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 *
  11 */
  12#include <linux/types.h>
  13#include <linux/mutex.h>
  14#include <linux/device.h>
  15#include <linux/spi/spi.h>
  16#include <linux/slab.h>
  17#include <linux/sysfs.h>
  18#include <linux/delay.h>
  19#include <linux/gpio.h>
  20#include <linux/module.h>
  21#include <linux/bitops.h>
  22
  23#include <linux/iio/iio.h>
  24#include <linux/iio/sysfs.h>
  25
  26#define DRV_NAME "ad2s1200"
  27
  28/* input pin sample and rdvel is controlled by driver */
  29#define AD2S1200_PN     2
  30
  31/* input clock on serial interface */
  32#define AD2S1200_HZ     8192000
  33/* clock period in nano second */
  34#define AD2S1200_TSCLK  (1000000000 / AD2S1200_HZ)
  35
  36struct ad2s1200_state {
  37        struct mutex lock;
  38        struct spi_device *sdev;
  39        int sample;
  40        int rdvel;
  41        u8 rx[2] ____cacheline_aligned;
  42};
  43
  44static int ad2s1200_read_raw(struct iio_dev *indio_dev,
  45                             struct iio_chan_spec const *chan,
  46                             int *val,
  47                             int *val2,
  48                             long m)
  49{
  50        int ret = 0;
  51        s16 vel;
  52        struct ad2s1200_state *st = iio_priv(indio_dev);
  53
  54        mutex_lock(&st->lock);
  55        gpio_set_value(st->sample, 0);
  56        /* delay (6 * AD2S1200_TSCLK + 20) nano seconds */
  57        udelay(1);
  58        gpio_set_value(st->sample, 1);
  59        gpio_set_value(st->rdvel, !!(chan->type == IIO_ANGL));
  60        ret = spi_read(st->sdev, st->rx, 2);
  61        if (ret < 0) {
  62                mutex_unlock(&st->lock);
  63                return ret;
  64        }
  65
  66        switch (chan->type) {
  67        case IIO_ANGL:
  68                *val = (((u16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4);
  69                break;
  70        case IIO_ANGL_VEL:
  71                vel = (((s16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4);
  72                vel = sign_extend32(vel, 11);
  73                *val = vel;
  74                break;
  75        default:
  76                mutex_unlock(&st->lock);
  77                return -EINVAL;
  78        }
  79        /* delay (2 * AD2S1200_TSCLK + 20) ns for sample pulse */
  80        udelay(1);
  81        mutex_unlock(&st->lock);
  82        return IIO_VAL_INT;
  83}
  84
  85static const struct iio_chan_spec ad2s1200_channels[] = {
  86        {
  87                .type = IIO_ANGL,
  88                .indexed = 1,
  89                .channel = 0,
  90                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
  91        }, {
  92                .type = IIO_ANGL_VEL,
  93                .indexed = 1,
  94                .channel = 0,
  95                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
  96        }
  97};
  98
  99static const struct iio_info ad2s1200_info = {
 100        .read_raw = &ad2s1200_read_raw,
 101        .driver_module = THIS_MODULE,
 102};
 103
 104static int ad2s1200_probe(struct spi_device *spi)
 105{
 106        struct ad2s1200_state *st;
 107        struct iio_dev *indio_dev;
 108        int pn, ret = 0;
 109        unsigned short *pins = spi->dev.platform_data;
 110
 111        for (pn = 0; pn < AD2S1200_PN; pn++) {
 112                ret = devm_gpio_request_one(&spi->dev, pins[pn], GPIOF_DIR_OUT,
 113                                            DRV_NAME);
 114                if (ret) {
 115                        dev_err(&spi->dev, "request gpio pin %d failed\n",
 116                                pins[pn]);
 117                        return ret;
 118                }
 119        }
 120        indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 121        if (!indio_dev)
 122                return -ENOMEM;
 123        spi_set_drvdata(spi, indio_dev);
 124        st = iio_priv(indio_dev);
 125        mutex_init(&st->lock);
 126        st->sdev = spi;
 127        st->sample = pins[0];
 128        st->rdvel = pins[1];
 129
 130        indio_dev->dev.parent = &spi->dev;
 131        indio_dev->info = &ad2s1200_info;
 132        indio_dev->modes = INDIO_DIRECT_MODE;
 133        indio_dev->channels = ad2s1200_channels;
 134        indio_dev->num_channels = ARRAY_SIZE(ad2s1200_channels);
 135        indio_dev->name = spi_get_device_id(spi)->name;
 136
 137        ret = devm_iio_device_register(&spi->dev, indio_dev);
 138        if (ret)
 139                return ret;
 140
 141        spi->max_speed_hz = AD2S1200_HZ;
 142        spi->mode = SPI_MODE_3;
 143        spi_setup(spi);
 144
 145        return 0;
 146}
 147
 148static const struct spi_device_id ad2s1200_id[] = {
 149        { "ad2s1200" },
 150        { "ad2s1205" },
 151        {}
 152};
 153MODULE_DEVICE_TABLE(spi, ad2s1200_id);
 154
 155static struct spi_driver ad2s1200_driver = {
 156        .driver = {
 157                .name = DRV_NAME,
 158        },
 159        .probe = ad2s1200_probe,
 160        .id_table = ad2s1200_id,
 161};
 162module_spi_driver(ad2s1200_driver);
 163
 164MODULE_AUTHOR("Graff Yang <graff.yang@gmail.com>");
 165MODULE_DESCRIPTION("Analog Devices AD2S1200/1205 Resolver to Digital SPI driver");
 166MODULE_LICENSE("GPL v2");
 167