root/drivers/iio/resolver/ad2s1200.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ad2s1200_read_raw
  2. ad2s1200_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * ad2s1200.c simple support for the ADI Resolver to Digital Converters:
   4  * AD2S1200/1205
   5  *
   6  * Copyright (c) 2018-2018 David Veenstra <davidjulianveenstra@gmail.com>
   7  * Copyright (c) 2010-2010 Analog Devices Inc.
   8  */
   9 
  10 #include <linux/bitops.h>
  11 #include <linux/delay.h>
  12 #include <linux/device.h>
  13 #include <linux/gpio.h>
  14 #include <linux/gpio/consumer.h>
  15 #include <linux/module.h>
  16 #include <linux/mutex.h>
  17 #include <linux/spi/spi.h>
  18 #include <linux/sysfs.h>
  19 #include <linux/types.h>
  20 
  21 #include <linux/iio/iio.h>
  22 #include <linux/iio/sysfs.h>
  23 
  24 #define DRV_NAME "ad2s1200"
  25 
  26 /* input clock on serial interface */
  27 #define AD2S1200_HZ     8192000
  28 /* clock period in nano second */
  29 #define AD2S1200_TSCLK  (1000000000 / AD2S1200_HZ)
  30 
  31 /**
  32  * struct ad2s1200_state - driver instance specific data.
  33  * @lock:       protects both the GPIO pins and the rx buffer.
  34  * @sdev:       spi device.
  35  * @sample:     GPIO pin SAMPLE.
  36  * @rdvel:      GPIO pin RDVEL.
  37  * @rx:         buffer for spi transfers.
  38  */
  39 struct ad2s1200_state {
  40         struct mutex lock;
  41         struct spi_device *sdev;
  42         struct gpio_desc *sample;
  43         struct gpio_desc *rdvel;
  44         __be16 rx ____cacheline_aligned;
  45 };
  46 
  47 static int ad2s1200_read_raw(struct iio_dev *indio_dev,
  48                              struct iio_chan_spec const *chan,
  49                              int *val,
  50                              int *val2,
  51                              long m)
  52 {
  53         struct ad2s1200_state *st = iio_priv(indio_dev);
  54         int ret;
  55 
  56         switch (m) {
  57         case IIO_CHAN_INFO_SCALE:
  58                 switch (chan->type) {
  59                 case IIO_ANGL:
  60                         /* 2 * Pi / (2^12 - 1) ~= 0.001534355 */
  61                         *val = 0;
  62                         *val2 = 1534355;
  63                         return IIO_VAL_INT_PLUS_NANO;
  64                 case IIO_ANGL_VEL:
  65                         /* 2 * Pi ~= 6.283185 */
  66                         *val = 6;
  67                         *val2 = 283185;
  68                         return IIO_VAL_INT_PLUS_MICRO;
  69                 default:
  70                         return -EINVAL;
  71                 }
  72                 break;
  73         case IIO_CHAN_INFO_RAW:
  74                 mutex_lock(&st->lock);
  75                 gpiod_set_value(st->sample, 0);
  76 
  77                 /* delay (6 * AD2S1200_TSCLK + 20) nano seconds */
  78                 udelay(1);
  79                 gpiod_set_value(st->sample, 1);
  80                 gpiod_set_value(st->rdvel, !!(chan->type == IIO_ANGL));
  81 
  82                 ret = spi_read(st->sdev, &st->rx, 2);
  83                 if (ret < 0) {
  84                         mutex_unlock(&st->lock);
  85                         return ret;
  86                 }
  87 
  88                 switch (chan->type) {
  89                 case IIO_ANGL:
  90                         *val = be16_to_cpup(&st->rx) >> 4;
  91                         break;
  92                 case IIO_ANGL_VEL:
  93                         *val = sign_extend32(be16_to_cpup(&st->rx) >> 4, 11);
  94                         break;
  95                 default:
  96                         mutex_unlock(&st->lock);
  97                         return -EINVAL;
  98                 }
  99 
 100                 /* delay (2 * AD2S1200_TSCLK + 20) ns for sample pulse */
 101                 udelay(1);
 102                 mutex_unlock(&st->lock);
 103 
 104                 return IIO_VAL_INT;
 105         default:
 106                 break;
 107         }
 108 
 109         return -EINVAL;
 110 }
 111 
 112 static const struct iio_chan_spec ad2s1200_channels[] = {
 113         {
 114                 .type = IIO_ANGL,
 115                 .indexed = 1,
 116                 .channel = 0,
 117                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 118                 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
 119         }, {
 120                 .type = IIO_ANGL_VEL,
 121                 .indexed = 1,
 122                 .channel = 0,
 123                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 124                 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
 125         }
 126 };
 127 
 128 static const struct iio_info ad2s1200_info = {
 129         .read_raw = ad2s1200_read_raw,
 130 };
 131 
 132 static int ad2s1200_probe(struct spi_device *spi)
 133 {
 134         struct ad2s1200_state *st;
 135         struct iio_dev *indio_dev;
 136         int ret;
 137 
 138         indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 139         if (!indio_dev)
 140                 return -ENOMEM;
 141 
 142         spi_set_drvdata(spi, indio_dev);
 143         st = iio_priv(indio_dev);
 144         mutex_init(&st->lock);
 145         st->sdev = spi;
 146 
 147         st->sample = devm_gpiod_get(&spi->dev, "adi,sample", GPIOD_OUT_LOW);
 148         if (IS_ERR(st->sample)) {
 149                 dev_err(&spi->dev, "Failed to claim SAMPLE gpio: err=%ld\n",
 150                         PTR_ERR(st->sample));
 151                 return PTR_ERR(st->sample);
 152         }
 153 
 154         st->rdvel = devm_gpiod_get(&spi->dev, "adi,rdvel", GPIOD_OUT_LOW);
 155         if (IS_ERR(st->rdvel)) {
 156                 dev_err(&spi->dev, "Failed to claim RDVEL gpio: err=%ld\n",
 157                         PTR_ERR(st->rdvel));
 158                 return PTR_ERR(st->rdvel);
 159         }
 160 
 161         indio_dev->dev.parent = &spi->dev;
 162         indio_dev->info = &ad2s1200_info;
 163         indio_dev->modes = INDIO_DIRECT_MODE;
 164         indio_dev->channels = ad2s1200_channels;
 165         indio_dev->num_channels = ARRAY_SIZE(ad2s1200_channels);
 166         indio_dev->name = spi_get_device_id(spi)->name;
 167 
 168         spi->max_speed_hz = AD2S1200_HZ;
 169         spi->mode = SPI_MODE_3;
 170         ret = spi_setup(spi);
 171 
 172         if (ret < 0) {
 173                 dev_err(&spi->dev, "spi_setup failed!\n");
 174                 return ret;
 175         }
 176 
 177         return devm_iio_device_register(&spi->dev, indio_dev);
 178 }
 179 
 180 static const struct of_device_id ad2s1200_of_match[] = {
 181         { .compatible = "adi,ad2s1200", },
 182         { .compatible = "adi,ad2s1205", },
 183         { }
 184 };
 185 MODULE_DEVICE_TABLE(of, ad2s1200_of_match);
 186 
 187 static const struct spi_device_id ad2s1200_id[] = {
 188         { "ad2s1200" },
 189         { "ad2s1205" },
 190         {}
 191 };
 192 MODULE_DEVICE_TABLE(spi, ad2s1200_id);
 193 
 194 static struct spi_driver ad2s1200_driver = {
 195         .driver = {
 196                 .name = DRV_NAME,
 197                 .of_match_table = of_match_ptr(ad2s1200_of_match),
 198         },
 199         .probe = ad2s1200_probe,
 200         .id_table = ad2s1200_id,
 201 };
 202 module_spi_driver(ad2s1200_driver);
 203 
 204 MODULE_AUTHOR("David Veenstra <davidjulianveenstra@gmail.com>");
 205 MODULE_AUTHOR("Graff Yang <graff.yang@gmail.com>");
 206 MODULE_DESCRIPTION("Analog Devices AD2S1200/1205 Resolver to Digital SPI driver");
 207 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */