root/drivers/iio/gyro/adis16080.c

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

DEFINITIONS

This source file includes following definitions.
  1. adis16080_read_sample
  2. adis16080_read_raw
  3. adis16080_probe
  4. adis16080_remove

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * ADIS16080/100 Yaw Rate Gyroscope with SPI driver
   4  *
   5  * Copyright 2010 Analog Devices Inc.
   6  */
   7 #include <linux/delay.h>
   8 #include <linux/mutex.h>
   9 #include <linux/device.h>
  10 #include <linux/kernel.h>
  11 #include <linux/spi/spi.h>
  12 #include <linux/slab.h>
  13 #include <linux/sysfs.h>
  14 #include <linux/module.h>
  15 
  16 #include <linux/iio/iio.h>
  17 #include <linux/iio/sysfs.h>
  18 
  19 #define ADIS16080_DIN_GYRO   (0 << 10) /* Gyroscope output */
  20 #define ADIS16080_DIN_TEMP   (1 << 10) /* Temperature output */
  21 #define ADIS16080_DIN_AIN1   (2 << 10)
  22 #define ADIS16080_DIN_AIN2   (3 << 10)
  23 
  24 /*
  25  * 1: Write contents on DIN to control register.
  26  * 0: No changes to control register.
  27  */
  28 
  29 #define ADIS16080_DIN_WRITE  (1 << 15)
  30 
  31 struct adis16080_chip_info {
  32         int scale_val;
  33         int scale_val2;
  34 };
  35 
  36 /**
  37  * struct adis16080_state - device instance specific data
  38  * @us:                 actual spi_device to write data
  39  * @info:               chip specific parameters
  40  * @buf:                transmit or receive buffer
  41  **/
  42 struct adis16080_state {
  43         struct spi_device               *us;
  44         const struct adis16080_chip_info *info;
  45 
  46         __be16 buf ____cacheline_aligned;
  47 };
  48 
  49 static int adis16080_read_sample(struct iio_dev *indio_dev,
  50                 u16 addr, int *val)
  51 {
  52         struct adis16080_state *st = iio_priv(indio_dev);
  53         int ret;
  54         struct spi_transfer     t[] = {
  55                 {
  56                         .tx_buf         = &st->buf,
  57                         .len            = 2,
  58                         .cs_change      = 1,
  59                 }, {
  60                         .rx_buf         = &st->buf,
  61                         .len            = 2,
  62                 },
  63         };
  64 
  65         st->buf = cpu_to_be16(addr | ADIS16080_DIN_WRITE);
  66 
  67         ret = spi_sync_transfer(st->us, t, ARRAY_SIZE(t));
  68         if (ret == 0)
  69                 *val = sign_extend32(be16_to_cpu(st->buf), 11);
  70 
  71         return ret;
  72 }
  73 
  74 static int adis16080_read_raw(struct iio_dev *indio_dev,
  75                              struct iio_chan_spec const *chan,
  76                              int *val,
  77                              int *val2,
  78                              long mask)
  79 {
  80         struct adis16080_state *st = iio_priv(indio_dev);
  81         int ret;
  82 
  83         switch (mask) {
  84         case IIO_CHAN_INFO_RAW:
  85                 mutex_lock(&indio_dev->mlock);
  86                 ret = adis16080_read_sample(indio_dev, chan->address, val);
  87                 mutex_unlock(&indio_dev->mlock);
  88                 return ret ? ret : IIO_VAL_INT;
  89         case IIO_CHAN_INFO_SCALE:
  90                 switch (chan->type) {
  91                 case IIO_ANGL_VEL:
  92                         *val = st->info->scale_val;
  93                         *val2 = st->info->scale_val2;
  94                         return IIO_VAL_FRACTIONAL;
  95                 case IIO_VOLTAGE:
  96                         /* VREF = 5V, 12 bits */
  97                         *val = 5000;
  98                         *val2 = 12;
  99                         return IIO_VAL_FRACTIONAL_LOG2;
 100                 case IIO_TEMP:
 101                         /* 85 C = 585, 25 C = 0 */
 102                         *val = 85000 - 25000;
 103                         *val2 = 585;
 104                         return IIO_VAL_FRACTIONAL;
 105                 default:
 106                         return -EINVAL;
 107                 }
 108         case IIO_CHAN_INFO_OFFSET:
 109                 switch (chan->type) {
 110                 case IIO_VOLTAGE:
 111                         /* 2.5 V = 0 */
 112                         *val = 2048;
 113                         return IIO_VAL_INT;
 114                 case IIO_TEMP:
 115                         /* 85 C = 585, 25 C = 0 */
 116                         *val = DIV_ROUND_CLOSEST(25 * 585, 85 - 25);
 117                         return IIO_VAL_INT;
 118                 default:
 119                         return -EINVAL;
 120                 }
 121         default:
 122                 break;
 123         }
 124 
 125         return -EINVAL;
 126 }
 127 
 128 static const struct iio_chan_spec adis16080_channels[] = {
 129         {
 130                 .type = IIO_ANGL_VEL,
 131                 .modified = 1,
 132                 .channel2 = IIO_MOD_Z,
 133                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 134                         BIT(IIO_CHAN_INFO_SCALE),
 135                 .address = ADIS16080_DIN_GYRO,
 136         }, {
 137                 .type = IIO_VOLTAGE,
 138                 .indexed = 1,
 139                 .channel = 0,
 140                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 141                         BIT(IIO_CHAN_INFO_SCALE) |
 142                         BIT(IIO_CHAN_INFO_OFFSET),
 143                 .address = ADIS16080_DIN_AIN1,
 144         }, {
 145                 .type = IIO_VOLTAGE,
 146                 .indexed = 1,
 147                 .channel = 1,
 148                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 149                         BIT(IIO_CHAN_INFO_SCALE) |
 150                         BIT(IIO_CHAN_INFO_OFFSET),
 151                 .address = ADIS16080_DIN_AIN2,
 152         }, {
 153                 .type = IIO_TEMP,
 154                 .indexed = 1,
 155                 .channel = 0,
 156                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 157                         BIT(IIO_CHAN_INFO_SCALE) |
 158                         BIT(IIO_CHAN_INFO_OFFSET),
 159                 .address = ADIS16080_DIN_TEMP,
 160         }
 161 };
 162 
 163 static const struct iio_info adis16080_info = {
 164         .read_raw = &adis16080_read_raw,
 165 };
 166 
 167 enum {
 168         ID_ADIS16080,
 169         ID_ADIS16100,
 170 };
 171 
 172 static const struct adis16080_chip_info adis16080_chip_info[] = {
 173         [ID_ADIS16080] = {
 174                 /* 80 degree = 819, 819 rad = 46925 degree */
 175                 .scale_val = 80,
 176                 .scale_val2 = 46925,
 177         },
 178         [ID_ADIS16100] = {
 179                 /* 300 degree = 1230, 1230 rad = 70474 degree */
 180                 .scale_val = 300,
 181                 .scale_val2 = 70474,
 182         },
 183 };
 184 
 185 static int adis16080_probe(struct spi_device *spi)
 186 {
 187         const struct spi_device_id *id = spi_get_device_id(spi);
 188         struct adis16080_state *st;
 189         struct iio_dev *indio_dev;
 190 
 191         /* setup the industrialio driver allocated elements */
 192         indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 193         if (!indio_dev)
 194                 return -ENOMEM;
 195         st = iio_priv(indio_dev);
 196         /* this is only used for removal purposes */
 197         spi_set_drvdata(spi, indio_dev);
 198 
 199         /* Allocate the comms buffers */
 200         st->us = spi;
 201         st->info = &adis16080_chip_info[id->driver_data];
 202 
 203         indio_dev->name = spi->dev.driver->name;
 204         indio_dev->channels = adis16080_channels;
 205         indio_dev->num_channels = ARRAY_SIZE(adis16080_channels);
 206         indio_dev->dev.parent = &spi->dev;
 207         indio_dev->info = &adis16080_info;
 208         indio_dev->modes = INDIO_DIRECT_MODE;
 209 
 210         return iio_device_register(indio_dev);
 211 }
 212 
 213 static int adis16080_remove(struct spi_device *spi)
 214 {
 215         iio_device_unregister(spi_get_drvdata(spi));
 216         return 0;
 217 }
 218 
 219 static const struct spi_device_id adis16080_ids[] = {
 220         { "adis16080", ID_ADIS16080 },
 221         { "adis16100", ID_ADIS16100 },
 222         {},
 223 };
 224 MODULE_DEVICE_TABLE(spi, adis16080_ids);
 225 
 226 static struct spi_driver adis16080_driver = {
 227         .driver = {
 228                 .name = "adis16080",
 229         },
 230         .probe = adis16080_probe,
 231         .remove = adis16080_remove,
 232         .id_table = adis16080_ids,
 233 };
 234 module_spi_driver(adis16080_driver);
 235 
 236 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
 237 MODULE_DESCRIPTION("Analog Devices ADIS16080/100 Yaw Rate Gyroscope Driver");
 238 MODULE_LICENSE("GPL v2");

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