207 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * ad2s1200.c simple support for the ADI Resolver to Digital Converters:4 * AD2S1200/12055 *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/consumer.h>14#include <linux/module.h>15#include <linux/mod_devicetable.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 819200028/* 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 */39struct ad2s1200_state {40 struct mutex lock;41 struct spi_device *sdev;42 struct gpio_desc *sample;43 struct gpio_desc *rdvel;44 __be16 rx __aligned(IIO_DMA_MINALIGN);45};46 47static 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 112static 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 128static const struct iio_info ad2s1200_info = {129 .read_raw = ad2s1200_read_raw,130};131 132static 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->info = &ad2s1200_info;162 indio_dev->modes = INDIO_DIRECT_MODE;163 indio_dev->channels = ad2s1200_channels;164 indio_dev->num_channels = ARRAY_SIZE(ad2s1200_channels);165 indio_dev->name = spi_get_device_id(spi)->name;166 167 spi->max_speed_hz = AD2S1200_HZ;168 spi->mode = SPI_MODE_3;169 ret = spi_setup(spi);170 171 if (ret < 0) {172 dev_err(&spi->dev, "spi_setup failed!\n");173 return ret;174 }175 176 return devm_iio_device_register(&spi->dev, indio_dev);177}178 179static const struct of_device_id ad2s1200_of_match[] = {180 { .compatible = "adi,ad2s1200", },181 { .compatible = "adi,ad2s1205", },182 { }183};184MODULE_DEVICE_TABLE(of, ad2s1200_of_match);185 186static const struct spi_device_id ad2s1200_id[] = {187 { "ad2s1200" },188 { "ad2s1205" },189 {}190};191MODULE_DEVICE_TABLE(spi, ad2s1200_id);192 193static struct spi_driver ad2s1200_driver = {194 .driver = {195 .name = DRV_NAME,196 .of_match_table = ad2s1200_of_match,197 },198 .probe = ad2s1200_probe,199 .id_table = ad2s1200_id,200};201module_spi_driver(ad2s1200_driver);202 203MODULE_AUTHOR("David Veenstra <davidjulianveenstra@gmail.com>");204MODULE_AUTHOR("Graff Yang <graff.yang@gmail.com>");205MODULE_DESCRIPTION("Analog Devices AD2S1200/1205 Resolver to Digital SPI driver");206MODULE_LICENSE("GPL v2");207