Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * ad2s1200.c simple support for the ADI Resolver to Digital Converters:
0004  * AD2S1200/1205
0005  *
0006  * Copyright (c) 2018-2018 David Veenstra <davidjulianveenstra@gmail.com>
0007  * Copyright (c) 2010-2010 Analog Devices Inc.
0008  */
0009 
0010 #include <linux/bitops.h>
0011 #include <linux/delay.h>
0012 #include <linux/device.h>
0013 #include <linux/gpio/consumer.h>
0014 #include <linux/module.h>
0015 #include <linux/mod_devicetable.h>
0016 #include <linux/mutex.h>
0017 #include <linux/spi/spi.h>
0018 #include <linux/sysfs.h>
0019 #include <linux/types.h>
0020 
0021 #include <linux/iio/iio.h>
0022 #include <linux/iio/sysfs.h>
0023 
0024 #define DRV_NAME "ad2s1200"
0025 
0026 /* input clock on serial interface */
0027 #define AD2S1200_HZ 8192000
0028 /* clock period in nano second */
0029 #define AD2S1200_TSCLK  (1000000000 / AD2S1200_HZ)
0030 
0031 /**
0032  * struct ad2s1200_state - driver instance specific data.
0033  * @lock:   protects both the GPIO pins and the rx buffer.
0034  * @sdev:   spi device.
0035  * @sample: GPIO pin SAMPLE.
0036  * @rdvel:  GPIO pin RDVEL.
0037  * @rx:     buffer for spi transfers.
0038  */
0039 struct ad2s1200_state {
0040     struct mutex lock;
0041     struct spi_device *sdev;
0042     struct gpio_desc *sample;
0043     struct gpio_desc *rdvel;
0044     __be16 rx __aligned(IIO_DMA_MINALIGN);
0045 };
0046 
0047 static int ad2s1200_read_raw(struct iio_dev *indio_dev,
0048                  struct iio_chan_spec const *chan,
0049                  int *val,
0050                  int *val2,
0051                  long m)
0052 {
0053     struct ad2s1200_state *st = iio_priv(indio_dev);
0054     int ret;
0055 
0056     switch (m) {
0057     case IIO_CHAN_INFO_SCALE:
0058         switch (chan->type) {
0059         case IIO_ANGL:
0060             /* 2 * Pi / (2^12 - 1) ~= 0.001534355 */
0061             *val = 0;
0062             *val2 = 1534355;
0063             return IIO_VAL_INT_PLUS_NANO;
0064         case IIO_ANGL_VEL:
0065             /* 2 * Pi ~= 6.283185 */
0066             *val = 6;
0067             *val2 = 283185;
0068             return IIO_VAL_INT_PLUS_MICRO;
0069         default:
0070             return -EINVAL;
0071         }
0072         break;
0073     case IIO_CHAN_INFO_RAW:
0074         mutex_lock(&st->lock);
0075         gpiod_set_value(st->sample, 0);
0076 
0077         /* delay (6 * AD2S1200_TSCLK + 20) nano seconds */
0078         udelay(1);
0079         gpiod_set_value(st->sample, 1);
0080         gpiod_set_value(st->rdvel, !!(chan->type == IIO_ANGL));
0081 
0082         ret = spi_read(st->sdev, &st->rx, 2);
0083         if (ret < 0) {
0084             mutex_unlock(&st->lock);
0085             return ret;
0086         }
0087 
0088         switch (chan->type) {
0089         case IIO_ANGL:
0090             *val = be16_to_cpup(&st->rx) >> 4;
0091             break;
0092         case IIO_ANGL_VEL:
0093             *val = sign_extend32(be16_to_cpup(&st->rx) >> 4, 11);
0094             break;
0095         default:
0096             mutex_unlock(&st->lock);
0097             return -EINVAL;
0098         }
0099 
0100         /* delay (2 * AD2S1200_TSCLK + 20) ns for sample pulse */
0101         udelay(1);
0102         mutex_unlock(&st->lock);
0103 
0104         return IIO_VAL_INT;
0105     default:
0106         break;
0107     }
0108 
0109     return -EINVAL;
0110 }
0111 
0112 static const struct iio_chan_spec ad2s1200_channels[] = {
0113     {
0114         .type = IIO_ANGL,
0115         .indexed = 1,
0116         .channel = 0,
0117         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
0118         .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
0119     }, {
0120         .type = IIO_ANGL_VEL,
0121         .indexed = 1,
0122         .channel = 0,
0123         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
0124         .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
0125     }
0126 };
0127 
0128 static const struct iio_info ad2s1200_info = {
0129     .read_raw = ad2s1200_read_raw,
0130 };
0131 
0132 static int ad2s1200_probe(struct spi_device *spi)
0133 {
0134     struct ad2s1200_state *st;
0135     struct iio_dev *indio_dev;
0136     int ret;
0137 
0138     indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
0139     if (!indio_dev)
0140         return -ENOMEM;
0141 
0142     spi_set_drvdata(spi, indio_dev);
0143     st = iio_priv(indio_dev);
0144     mutex_init(&st->lock);
0145     st->sdev = spi;
0146 
0147     st->sample = devm_gpiod_get(&spi->dev, "adi,sample", GPIOD_OUT_LOW);
0148     if (IS_ERR(st->sample)) {
0149         dev_err(&spi->dev, "Failed to claim SAMPLE gpio: err=%ld\n",
0150             PTR_ERR(st->sample));
0151         return PTR_ERR(st->sample);
0152     }
0153 
0154     st->rdvel = devm_gpiod_get(&spi->dev, "adi,rdvel", GPIOD_OUT_LOW);
0155     if (IS_ERR(st->rdvel)) {
0156         dev_err(&spi->dev, "Failed to claim RDVEL gpio: err=%ld\n",
0157             PTR_ERR(st->rdvel));
0158         return PTR_ERR(st->rdvel);
0159     }
0160 
0161     indio_dev->info = &ad2s1200_info;
0162     indio_dev->modes = INDIO_DIRECT_MODE;
0163     indio_dev->channels = ad2s1200_channels;
0164     indio_dev->num_channels = ARRAY_SIZE(ad2s1200_channels);
0165     indio_dev->name = spi_get_device_id(spi)->name;
0166 
0167     spi->max_speed_hz = AD2S1200_HZ;
0168     spi->mode = SPI_MODE_3;
0169     ret = spi_setup(spi);
0170 
0171     if (ret < 0) {
0172         dev_err(&spi->dev, "spi_setup failed!\n");
0173         return ret;
0174     }
0175 
0176     return devm_iio_device_register(&spi->dev, indio_dev);
0177 }
0178 
0179 static const struct of_device_id ad2s1200_of_match[] = {
0180     { .compatible = "adi,ad2s1200", },
0181     { .compatible = "adi,ad2s1205", },
0182     { }
0183 };
0184 MODULE_DEVICE_TABLE(of, ad2s1200_of_match);
0185 
0186 static const struct spi_device_id ad2s1200_id[] = {
0187     { "ad2s1200" },
0188     { "ad2s1205" },
0189     {}
0190 };
0191 MODULE_DEVICE_TABLE(spi, ad2s1200_id);
0192 
0193 static struct spi_driver ad2s1200_driver = {
0194     .driver = {
0195         .name = DRV_NAME,
0196         .of_match_table = ad2s1200_of_match,
0197     },
0198     .probe = ad2s1200_probe,
0199     .id_table = ad2s1200_id,
0200 };
0201 module_spi_driver(ad2s1200_driver);
0202 
0203 MODULE_AUTHOR("David Veenstra <davidjulianveenstra@gmail.com>");
0204 MODULE_AUTHOR("Graff Yang <graff.yang@gmail.com>");
0205 MODULE_DESCRIPTION("Analog Devices AD2S1200/1205 Resolver to Digital SPI driver");
0206 MODULE_LICENSE("GPL v2");