Commit d6b09bd85d57752395c6407bd8a9b32eb7b279ff

Authored by Lars-Peter Clausen
Committed by Jonathan Cameron
1 parent f4c6d64bcf

staging:iio: Move adis16400 out of staging

This adis16400 driver is in pretty good shape now, so move it out of staging.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>

Showing 12 changed files with 1126 additions and 1138 deletions Side-by-side Diff

drivers/iio/imu/Kconfig
... ... @@ -3,6 +3,17 @@
3 3 #
4 4 menu "Inertial measurement units"
5 5  
  6 +config ADIS16400
  7 + tristate "Analog Devices ADIS16400 and similar IMU SPI driver"
  8 + depends on SPI
  9 + select IIO_ADIS_LIB
  10 + select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
  11 + help
  12 + Say yes here to build support for Analog Devices adis16300, adis16344,
  13 + adis16350, adis16354, adis16355, adis16360, adis16362, adis16364,
  14 + adis16365, adis16400 and adis16405 triaxial inertial sensors
  15 + (adis16400 series also have magnetometers).
  16 +
6 17 config ADIS16480
7 18 tristate "Analog Devices ADIS16480 and similar IMU driver"
8 19 depends on SPI
drivers/iio/imu/Makefile
... ... @@ -2,6 +2,9 @@
2 2 # Makefile for Inertial Measurement Units
3 3 #
4 4  
  5 +adis16400-y := adis16400_core.o
  6 +adis16400-$(CONFIG_IIO_BUFFER) += adis16400_buffer.o
  7 +obj-$(CONFIG_ADIS16400) += adis16400.o
5 8 obj-$(CONFIG_ADIS16480) += adis16480.o
6 9  
7 10 adis_lib-y += adis.o
drivers/iio/imu/adis16400.h
  1 +/*
  2 + * adis16400.h support Analog Devices ADIS16400
  3 + * 3d 18g accelerometers,
  4 + * 3d gyroscopes,
  5 + * 3d 2.5gauss magnetometers via SPI
  6 + *
  7 + * Copyright (c) 2009 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
  8 + * Copyright (c) 2007 Jonathan Cameron <jic23@kernel.org>
  9 + *
  10 + * Loosely based upon lis3l02dq.h
  11 + *
  12 + * This program is free software; you can redistribute it and/or modify
  13 + * it under the terms of the GNU General Public License version 2 as
  14 + * published by the Free Software Foundation.
  15 + */
  16 +
  17 +#ifndef SPI_ADIS16400_H_
  18 +#define SPI_ADIS16400_H_
  19 +
  20 +#include <linux/iio/imu/adis.h>
  21 +
  22 +#define ADIS16400_STARTUP_DELAY 290 /* ms */
  23 +#define ADIS16400_MTEST_DELAY 90 /* ms */
  24 +
  25 +#define ADIS16400_FLASH_CNT 0x00 /* Flash memory write count */
  26 +#define ADIS16400_SUPPLY_OUT 0x02 /* Power supply measurement */
  27 +#define ADIS16400_XGYRO_OUT 0x04 /* X-axis gyroscope output */
  28 +#define ADIS16400_YGYRO_OUT 0x06 /* Y-axis gyroscope output */
  29 +#define ADIS16400_ZGYRO_OUT 0x08 /* Z-axis gyroscope output */
  30 +#define ADIS16400_XACCL_OUT 0x0A /* X-axis accelerometer output */
  31 +#define ADIS16400_YACCL_OUT 0x0C /* Y-axis accelerometer output */
  32 +#define ADIS16400_ZACCL_OUT 0x0E /* Z-axis accelerometer output */
  33 +#define ADIS16400_XMAGN_OUT 0x10 /* X-axis magnetometer measurement */
  34 +#define ADIS16400_YMAGN_OUT 0x12 /* Y-axis magnetometer measurement */
  35 +#define ADIS16400_ZMAGN_OUT 0x14 /* Z-axis magnetometer measurement */
  36 +#define ADIS16400_TEMP_OUT 0x16 /* Temperature output */
  37 +#define ADIS16400_AUX_ADC 0x18 /* Auxiliary ADC measurement */
  38 +
  39 +#define ADIS16350_XTEMP_OUT 0x10 /* X-axis gyroscope temperature measurement */
  40 +#define ADIS16350_YTEMP_OUT 0x12 /* Y-axis gyroscope temperature measurement */
  41 +#define ADIS16350_ZTEMP_OUT 0x14 /* Z-axis gyroscope temperature measurement */
  42 +
  43 +#define ADIS16300_PITCH_OUT 0x12 /* X axis inclinometer output measurement */
  44 +#define ADIS16300_ROLL_OUT 0x14 /* Y axis inclinometer output measurement */
  45 +#define ADIS16300_AUX_ADC 0x16 /* Auxiliary ADC measurement */
  46 +
  47 +/* Calibration parameters */
  48 +#define ADIS16400_XGYRO_OFF 0x1A /* X-axis gyroscope bias offset factor */
  49 +#define ADIS16400_YGYRO_OFF 0x1C /* Y-axis gyroscope bias offset factor */
  50 +#define ADIS16400_ZGYRO_OFF 0x1E /* Z-axis gyroscope bias offset factor */
  51 +#define ADIS16400_XACCL_OFF 0x20 /* X-axis acceleration bias offset factor */
  52 +#define ADIS16400_YACCL_OFF 0x22 /* Y-axis acceleration bias offset factor */
  53 +#define ADIS16400_ZACCL_OFF 0x24 /* Z-axis acceleration bias offset factor */
  54 +#define ADIS16400_XMAGN_HIF 0x26 /* X-axis magnetometer, hard-iron factor */
  55 +#define ADIS16400_YMAGN_HIF 0x28 /* Y-axis magnetometer, hard-iron factor */
  56 +#define ADIS16400_ZMAGN_HIF 0x2A /* Z-axis magnetometer, hard-iron factor */
  57 +#define ADIS16400_XMAGN_SIF 0x2C /* X-axis magnetometer, soft-iron factor */
  58 +#define ADIS16400_YMAGN_SIF 0x2E /* Y-axis magnetometer, soft-iron factor */
  59 +#define ADIS16400_ZMAGN_SIF 0x30 /* Z-axis magnetometer, soft-iron factor */
  60 +
  61 +#define ADIS16400_GPIO_CTRL 0x32 /* Auxiliary digital input/output control */
  62 +#define ADIS16400_MSC_CTRL 0x34 /* Miscellaneous control */
  63 +#define ADIS16400_SMPL_PRD 0x36 /* Internal sample period (rate) control */
  64 +#define ADIS16400_SENS_AVG 0x38 /* Dynamic range and digital filter control */
  65 +#define ADIS16400_SLP_CNT 0x3A /* Sleep mode control */
  66 +#define ADIS16400_DIAG_STAT 0x3C /* System status */
  67 +
  68 +/* Alarm functions */
  69 +#define ADIS16400_GLOB_CMD 0x3E /* System command */
  70 +#define ADIS16400_ALM_MAG1 0x40 /* Alarm 1 amplitude threshold */
  71 +#define ADIS16400_ALM_MAG2 0x42 /* Alarm 2 amplitude threshold */
  72 +#define ADIS16400_ALM_SMPL1 0x44 /* Alarm 1 sample size */
  73 +#define ADIS16400_ALM_SMPL2 0x46 /* Alarm 2 sample size */
  74 +#define ADIS16400_ALM_CTRL 0x48 /* Alarm control */
  75 +#define ADIS16400_AUX_DAC 0x4A /* Auxiliary DAC data */
  76 +
  77 +#define ADIS16400_PRODUCT_ID 0x56 /* Product identifier */
  78 +
  79 +#define ADIS16400_ERROR_ACTIVE (1<<14)
  80 +#define ADIS16400_NEW_DATA (1<<14)
  81 +
  82 +/* MSC_CTRL */
  83 +#define ADIS16400_MSC_CTRL_MEM_TEST (1<<11)
  84 +#define ADIS16400_MSC_CTRL_INT_SELF_TEST (1<<10)
  85 +#define ADIS16400_MSC_CTRL_NEG_SELF_TEST (1<<9)
  86 +#define ADIS16400_MSC_CTRL_POS_SELF_TEST (1<<8)
  87 +#define ADIS16400_MSC_CTRL_GYRO_BIAS (1<<7)
  88 +#define ADIS16400_MSC_CTRL_ACCL_ALIGN (1<<6)
  89 +#define ADIS16400_MSC_CTRL_DATA_RDY_EN (1<<2)
  90 +#define ADIS16400_MSC_CTRL_DATA_RDY_POL_HIGH (1<<1)
  91 +#define ADIS16400_MSC_CTRL_DATA_RDY_DIO2 (1<<0)
  92 +
  93 +/* SMPL_PRD */
  94 +#define ADIS16400_SMPL_PRD_TIME_BASE (1<<7)
  95 +#define ADIS16400_SMPL_PRD_DIV_MASK 0x7F
  96 +
  97 +/* DIAG_STAT */
  98 +#define ADIS16400_DIAG_STAT_ZACCL_FAIL 15
  99 +#define ADIS16400_DIAG_STAT_YACCL_FAIL 14
  100 +#define ADIS16400_DIAG_STAT_XACCL_FAIL 13
  101 +#define ADIS16400_DIAG_STAT_XGYRO_FAIL 12
  102 +#define ADIS16400_DIAG_STAT_YGYRO_FAIL 11
  103 +#define ADIS16400_DIAG_STAT_ZGYRO_FAIL 10
  104 +#define ADIS16400_DIAG_STAT_ALARM2 9
  105 +#define ADIS16400_DIAG_STAT_ALARM1 8
  106 +#define ADIS16400_DIAG_STAT_FLASH_CHK 6
  107 +#define ADIS16400_DIAG_STAT_SELF_TEST 5
  108 +#define ADIS16400_DIAG_STAT_OVERFLOW 4
  109 +#define ADIS16400_DIAG_STAT_SPI_FAIL 3
  110 +#define ADIS16400_DIAG_STAT_FLASH_UPT 2
  111 +#define ADIS16400_DIAG_STAT_POWER_HIGH 1
  112 +#define ADIS16400_DIAG_STAT_POWER_LOW 0
  113 +
  114 +/* GLOB_CMD */
  115 +#define ADIS16400_GLOB_CMD_SW_RESET (1<<7)
  116 +#define ADIS16400_GLOB_CMD_P_AUTO_NULL (1<<4)
  117 +#define ADIS16400_GLOB_CMD_FLASH_UPD (1<<3)
  118 +#define ADIS16400_GLOB_CMD_DAC_LATCH (1<<2)
  119 +#define ADIS16400_GLOB_CMD_FAC_CALIB (1<<1)
  120 +#define ADIS16400_GLOB_CMD_AUTO_NULL (1<<0)
  121 +
  122 +/* SLP_CNT */
  123 +#define ADIS16400_SLP_CNT_POWER_OFF (1<<8)
  124 +
  125 +#define ADIS16334_RATE_DIV_SHIFT 8
  126 +#define ADIS16334_RATE_INT_CLK BIT(0)
  127 +
  128 +#define ADIS16400_SPI_SLOW (u32)(300 * 1000)
  129 +#define ADIS16400_SPI_BURST (u32)(1000 * 1000)
  130 +#define ADIS16400_SPI_FAST (u32)(2000 * 1000)
  131 +
  132 +#define ADIS16400_HAS_PROD_ID BIT(0)
  133 +#define ADIS16400_NO_BURST BIT(1)
  134 +#define ADIS16400_HAS_SLOW_MODE BIT(2)
  135 +
  136 +struct adis16400_state;
  137 +
  138 +struct adis16400_chip_info {
  139 + const struct iio_chan_spec *channels;
  140 + const int num_channels;
  141 + const long flags;
  142 + unsigned int gyro_scale_micro;
  143 + unsigned int accel_scale_micro;
  144 + int temp_scale_nano;
  145 + int temp_offset;
  146 + int (*set_freq)(struct adis16400_state *st, unsigned int freq);
  147 + int (*get_freq)(struct adis16400_state *st);
  148 +};
  149 +
  150 +/**
  151 + * struct adis16400_state - device instance specific data
  152 + * @variant: chip variant info
  153 + * @filt_int: integer part of requested filter frequency
  154 + * @adis: adis device
  155 + **/
  156 +struct adis16400_state {
  157 + struct adis16400_chip_info *variant;
  158 + int filt_int;
  159 +
  160 + struct adis adis;
  161 +};
  162 +
  163 +/* At the moment triggers are only used for ring buffer
  164 + * filling. This may change!
  165 + */
  166 +
  167 +enum {
  168 + ADIS16400_SCAN_SUPPLY,
  169 + ADIS16400_SCAN_GYRO_X,
  170 + ADIS16400_SCAN_GYRO_Y,
  171 + ADIS16400_SCAN_GYRO_Z,
  172 + ADIS16400_SCAN_ACC_X,
  173 + ADIS16400_SCAN_ACC_Y,
  174 + ADIS16400_SCAN_ACC_Z,
  175 + ADIS16400_SCAN_MAGN_X,
  176 + ADIS16400_SCAN_MAGN_Y,
  177 + ADIS16400_SCAN_MAGN_Z,
  178 + ADIS16350_SCAN_TEMP_X,
  179 + ADIS16350_SCAN_TEMP_Y,
  180 + ADIS16350_SCAN_TEMP_Z,
  181 + ADIS16300_SCAN_INCLI_X,
  182 + ADIS16300_SCAN_INCLI_Y,
  183 + ADIS16400_SCAN_ADC,
  184 +};
  185 +
  186 +#ifdef CONFIG_IIO_BUFFER
  187 +
  188 +ssize_t adis16400_read_data_from_ring(struct device *dev,
  189 + struct device_attribute *attr,
  190 + char *buf);
  191 +
  192 +
  193 +int adis16400_update_scan_mode(struct iio_dev *indio_dev,
  194 + const unsigned long *scan_mask);
  195 +irqreturn_t adis16400_trigger_handler(int irq, void *p);
  196 +
  197 +#else /* CONFIG_IIO_BUFFER */
  198 +
  199 +#define adis16400_update_scan_mode NULL
  200 +#define adis16400_trigger_handler NULL
  201 +
  202 +#endif /* CONFIG_IIO_BUFFER */
  203 +
  204 +#endif /* SPI_ADIS16400_H_ */
drivers/iio/imu/adis16400_buffer.c
  1 +#include <linux/interrupt.h>
  2 +#include <linux/mutex.h>
  3 +#include <linux/kernel.h>
  4 +#include <linux/spi/spi.h>
  5 +#include <linux/slab.h>
  6 +#include <linux/bitops.h>
  7 +#include <linux/export.h>
  8 +
  9 +#include <linux/iio/iio.h>
  10 +#include <linux/iio/buffer.h>
  11 +#include <linux/iio/triggered_buffer.h>
  12 +#include <linux/iio/trigger_consumer.h>
  13 +
  14 +#include "adis16400.h"
  15 +
  16 +int adis16400_update_scan_mode(struct iio_dev *indio_dev,
  17 + const unsigned long *scan_mask)
  18 +{
  19 + struct adis16400_state *st = iio_priv(indio_dev);
  20 + struct adis *adis = &st->adis;
  21 + uint16_t *tx, *rx;
  22 +
  23 + if (st->variant->flags & ADIS16400_NO_BURST)
  24 + return adis_update_scan_mode(indio_dev, scan_mask);
  25 +
  26 + kfree(adis->xfer);
  27 + kfree(adis->buffer);
  28 +
  29 + adis->xfer = kcalloc(2, sizeof(*adis->xfer), GFP_KERNEL);
  30 + if (!adis->xfer)
  31 + return -ENOMEM;
  32 +
  33 + adis->buffer = kzalloc(indio_dev->scan_bytes + sizeof(u16),
  34 + GFP_KERNEL);
  35 + if (!adis->buffer)
  36 + return -ENOMEM;
  37 +
  38 + rx = adis->buffer;
  39 + tx = adis->buffer + indio_dev->scan_bytes;
  40 +
  41 + tx[0] = ADIS_READ_REG(ADIS16400_GLOB_CMD);
  42 + tx[1] = 0;
  43 +
  44 + adis->xfer[0].tx_buf = tx;
  45 + adis->xfer[0].bits_per_word = 8;
  46 + adis->xfer[0].len = 2;
  47 + adis->xfer[1].tx_buf = tx;
  48 + adis->xfer[1].bits_per_word = 8;
  49 + adis->xfer[1].len = indio_dev->scan_bytes;
  50 +
  51 + spi_message_init(&adis->msg);
  52 + spi_message_add_tail(&adis->xfer[0], &adis->msg);
  53 + spi_message_add_tail(&adis->xfer[1], &adis->msg);
  54 +
  55 + return 0;
  56 +}
  57 +
  58 +irqreturn_t adis16400_trigger_handler(int irq, void *p)
  59 +{
  60 + struct iio_poll_func *pf = p;
  61 + struct iio_dev *indio_dev = pf->indio_dev;
  62 + struct adis16400_state *st = iio_priv(indio_dev);
  63 + struct adis *adis = &st->adis;
  64 + u32 old_speed_hz = st->adis.spi->max_speed_hz;
  65 + int ret;
  66 +
  67 + if (!adis->buffer)
  68 + return -ENOMEM;
  69 +
  70 + if (!(st->variant->flags & ADIS16400_NO_BURST) &&
  71 + st->adis.spi->max_speed_hz > ADIS16400_SPI_BURST) {
  72 + st->adis.spi->max_speed_hz = ADIS16400_SPI_BURST;
  73 + spi_setup(st->adis.spi);
  74 + }
  75 +
  76 + ret = spi_sync(adis->spi, &adis->msg);
  77 + if (ret)
  78 + dev_err(&adis->spi->dev, "Failed to read data: %d\n", ret);
  79 +
  80 + if (!(st->variant->flags & ADIS16400_NO_BURST)) {
  81 + st->adis.spi->max_speed_hz = old_speed_hz;
  82 + spi_setup(st->adis.spi);
  83 + }
  84 +
  85 + /* Guaranteed to be aligned with 8 byte boundary */
  86 + if (indio_dev->scan_timestamp) {
  87 + void *b = adis->buffer + indio_dev->scan_bytes - sizeof(s64);
  88 + *(s64 *)b = pf->timestamp;
  89 + }
  90 +
  91 + iio_push_to_buffers(indio_dev, adis->buffer);
  92 +
  93 + iio_trigger_notify_done(indio_dev->trig);
  94 +
  95 + return IRQ_HANDLED;
  96 +}
drivers/iio/imu/adis16400_core.c
  1 +/*
  2 + * adis16400.c support Analog Devices ADIS16400/5
  3 + * 3d 2g Linear Accelerometers,
  4 + * 3d Gyroscopes,
  5 + * 3d Magnetometers via SPI
  6 + *
  7 + * Copyright (c) 2009 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
  8 + * Copyright (c) 2007 Jonathan Cameron <jic23@kernel.org>
  9 + * Copyright (c) 2011 Analog Devices Inc.
  10 + *
  11 + * This program is free software; you can redistribute it and/or modify
  12 + * it under the terms of the GNU General Public License version 2 as
  13 + * published by the Free Software Foundation.
  14 + *
  15 + */
  16 +
  17 +#include <linux/interrupt.h>
  18 +#include <linux/irq.h>
  19 +#include <linux/delay.h>
  20 +#include <linux/mutex.h>
  21 +#include <linux/device.h>
  22 +#include <linux/kernel.h>
  23 +#include <linux/spi/spi.h>
  24 +#include <linux/slab.h>
  25 +#include <linux/sysfs.h>
  26 +#include <linux/list.h>
  27 +#include <linux/module.h>
  28 +
  29 +#include <linux/iio/iio.h>
  30 +#include <linux/iio/sysfs.h>
  31 +#include <linux/iio/buffer.h>
  32 +
  33 +#include "adis16400.h"
  34 +
  35 +enum adis16400_chip_variant {
  36 + ADIS16300,
  37 + ADIS16334,
  38 + ADIS16350,
  39 + ADIS16360,
  40 + ADIS16362,
  41 + ADIS16364,
  42 + ADIS16400,
  43 +};
  44 +
  45 +static int adis16334_get_freq(struct adis16400_state *st)
  46 +{
  47 + int ret;
  48 + uint16_t t;
  49 +
  50 + ret = adis_read_reg_16(&st->adis, ADIS16400_SMPL_PRD, &t);
  51 + if (ret < 0)
  52 + return ret;
  53 +
  54 + t >>= ADIS16334_RATE_DIV_SHIFT;
  55 +
  56 + return (8192 >> t) / 10;
  57 +}
  58 +
  59 +static int adis16334_set_freq(struct adis16400_state *st, unsigned int freq)
  60 +{
  61 + unsigned int t;
  62 +
  63 + freq *= 10;
  64 + if (freq < 8192)
  65 + t = ilog2(8192 / freq);
  66 + else
  67 + t = 0;
  68 +
  69 + if (t > 0x31)
  70 + t = 0x31;
  71 +
  72 + t <<= ADIS16334_RATE_DIV_SHIFT;
  73 + t |= ADIS16334_RATE_INT_CLK;
  74 +
  75 + return adis_write_reg_16(&st->adis, ADIS16400_SMPL_PRD, t);
  76 +}
  77 +
  78 +static int adis16400_get_freq(struct adis16400_state *st)
  79 +{
  80 + int sps, ret;
  81 + uint16_t t;
  82 +
  83 + ret = adis_read_reg_16(&st->adis, ADIS16400_SMPL_PRD, &t);
  84 + if (ret < 0)
  85 + return ret;
  86 +
  87 + sps = (t & ADIS16400_SMPL_PRD_TIME_BASE) ? 53 : 1638;
  88 + sps /= (t & ADIS16400_SMPL_PRD_DIV_MASK) + 1;
  89 +
  90 + return sps;
  91 +}
  92 +
  93 +static int adis16400_set_freq(struct adis16400_state *st, unsigned int freq)
  94 +{
  95 + unsigned int t;
  96 +
  97 + t = 1638 / freq;
  98 + if (t > 0)
  99 + t--;
  100 + t &= ADIS16400_SMPL_PRD_DIV_MASK;
  101 +
  102 + if ((t & ADIS16400_SMPL_PRD_DIV_MASK) >= 0x0A)
  103 + st->adis.spi->max_speed_hz = ADIS16400_SPI_SLOW;
  104 + else
  105 + st->adis.spi->max_speed_hz = ADIS16400_SPI_FAST;
  106 +
  107 + return adis_write_reg_8(&st->adis, ADIS16400_SMPL_PRD, t);
  108 +}
  109 +
  110 +static ssize_t adis16400_read_frequency(struct device *dev,
  111 + struct device_attribute *attr,
  112 + char *buf)
  113 +{
  114 + struct iio_dev *indio_dev = dev_to_iio_dev(dev);
  115 + struct adis16400_state *st = iio_priv(indio_dev);
  116 + int ret;
  117 +
  118 + ret = st->variant->get_freq(st);
  119 + if (ret < 0)
  120 + return ret;
  121 +
  122 + return sprintf(buf, "%d\n", ret);
  123 +}
  124 +
  125 +static const unsigned adis16400_3db_divisors[] = {
  126 + [0] = 2, /* Special case */
  127 + [1] = 6,
  128 + [2] = 12,
  129 + [3] = 25,
  130 + [4] = 50,
  131 + [5] = 100,
  132 + [6] = 200,
  133 + [7] = 200, /* Not a valid setting */
  134 +};
  135 +
  136 +static int adis16400_set_filter(struct iio_dev *indio_dev, int sps, int val)
  137 +{
  138 + struct adis16400_state *st = iio_priv(indio_dev);
  139 + uint16_t val16;
  140 + int i, ret;
  141 +
  142 + for (i = ARRAY_SIZE(adis16400_3db_divisors) - 1; i >= 1; i--) {
  143 + if (sps / adis16400_3db_divisors[i] >= val)
  144 + break;
  145 + }
  146 +
  147 + ret = adis_read_reg_16(&st->adis, ADIS16400_SENS_AVG, &val16);
  148 + if (ret < 0)
  149 + return ret;
  150 +
  151 + ret = adis_write_reg_16(&st->adis, ADIS16400_SENS_AVG,
  152 + (val16 & ~0x07) | i);
  153 + return ret;
  154 +}
  155 +
  156 +static ssize_t adis16400_write_frequency(struct device *dev,
  157 + struct device_attribute *attr, const char *buf, size_t len)
  158 +{
  159 + struct iio_dev *indio_dev = dev_to_iio_dev(dev);
  160 + struct adis16400_state *st = iio_priv(indio_dev);
  161 + long val;
  162 + int ret;
  163 +
  164 + ret = kstrtol(buf, 10, &val);
  165 + if (ret)
  166 + return ret;
  167 +
  168 + if (val == 0)
  169 + return -EINVAL;
  170 +
  171 + mutex_lock(&indio_dev->mlock);
  172 + st->variant->set_freq(st, val);
  173 + mutex_unlock(&indio_dev->mlock);
  174 +
  175 + return ret ? ret : len;
  176 +}
  177 +
  178 +/* Power down the device */
  179 +static int adis16400_stop_device(struct iio_dev *indio_dev)
  180 +{
  181 + struct adis16400_state *st = iio_priv(indio_dev);
  182 + int ret;
  183 +
  184 + ret = adis_write_reg_16(&st->adis, ADIS16400_SLP_CNT,
  185 + ADIS16400_SLP_CNT_POWER_OFF);
  186 + if (ret)
  187 + dev_err(&indio_dev->dev,
  188 + "problem with turning device off: SLP_CNT");
  189 +
  190 + return ret;
  191 +}
  192 +
  193 +static int adis16400_initial_setup(struct iio_dev *indio_dev)
  194 +{
  195 + struct adis16400_state *st = iio_priv(indio_dev);
  196 + uint16_t prod_id, smp_prd;
  197 + unsigned int device_id;
  198 + int ret;
  199 +
  200 + /* use low spi speed for init if the device has a slow mode */
  201 + if (st->variant->flags & ADIS16400_HAS_SLOW_MODE)
  202 + st->adis.spi->max_speed_hz = ADIS16400_SPI_SLOW;
  203 + else
  204 + st->adis.spi->max_speed_hz = ADIS16400_SPI_FAST;
  205 + st->adis.spi->mode = SPI_MODE_3;
  206 + spi_setup(st->adis.spi);
  207 +
  208 + ret = adis_initial_startup(&st->adis);
  209 + if (ret)
  210 + return ret;
  211 +
  212 + if (st->variant->flags & ADIS16400_HAS_PROD_ID) {
  213 + ret = adis_read_reg_16(&st->adis,
  214 + ADIS16400_PRODUCT_ID, &prod_id);
  215 + if (ret)
  216 + goto err_ret;
  217 +
  218 + sscanf(indio_dev->name, "adis%u\n", &device_id);
  219 +
  220 + if (prod_id != device_id)
  221 + dev_warn(&indio_dev->dev, "Device ID(%u) and product ID(%u) do not match.",
  222 + device_id, prod_id);
  223 +
  224 + dev_info(&indio_dev->dev, "%s: prod_id 0x%04x at CS%d (irq %d)\n",
  225 + indio_dev->name, prod_id,
  226 + st->adis.spi->chip_select, st->adis.spi->irq);
  227 + }
  228 + /* use high spi speed if possible */
  229 + if (st->variant->flags & ADIS16400_HAS_SLOW_MODE) {
  230 + ret = adis_read_reg_16(&st->adis, ADIS16400_SMPL_PRD, &smp_prd);
  231 + if (ret)
  232 + goto err_ret;
  233 +
  234 + if ((smp_prd & ADIS16400_SMPL_PRD_DIV_MASK) < 0x0A) {
  235 + st->adis.spi->max_speed_hz = ADIS16400_SPI_FAST;
  236 + spi_setup(st->adis.spi);
  237 + }
  238 + }
  239 +
  240 +err_ret:
  241 + return ret;
  242 +}
  243 +
  244 +static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
  245 + adis16400_read_frequency,
  246 + adis16400_write_frequency);
  247 +
  248 +static const uint8_t adis16400_addresses[] = {
  249 + [ADIS16400_SCAN_GYRO_X] = ADIS16400_XGYRO_OFF,
  250 + [ADIS16400_SCAN_GYRO_Y] = ADIS16400_YGYRO_OFF,
  251 + [ADIS16400_SCAN_GYRO_Z] = ADIS16400_ZGYRO_OFF,
  252 + [ADIS16400_SCAN_ACC_X] = ADIS16400_XACCL_OFF,
  253 + [ADIS16400_SCAN_ACC_Y] = ADIS16400_YACCL_OFF,
  254 + [ADIS16400_SCAN_ACC_Z] = ADIS16400_ZACCL_OFF,
  255 +};
  256 +
  257 +static int adis16400_write_raw(struct iio_dev *indio_dev,
  258 + struct iio_chan_spec const *chan, int val, int val2, long info)
  259 +{
  260 + struct adis16400_state *st = iio_priv(indio_dev);
  261 + int ret, sps;
  262 +
  263 + switch (info) {
  264 + case IIO_CHAN_INFO_CALIBBIAS:
  265 + mutex_lock(&indio_dev->mlock);
  266 + ret = adis_write_reg_16(&st->adis,
  267 + adis16400_addresses[chan->scan_index], val);
  268 + mutex_unlock(&indio_dev->mlock);
  269 + return ret;
  270 + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
  271 + /*
  272 + * Need to cache values so we can update if the frequency
  273 + * changes.
  274 + */
  275 + mutex_lock(&indio_dev->mlock);
  276 + st->filt_int = val;
  277 + /* Work out update to current value */
  278 + sps = st->variant->get_freq(st);
  279 + if (sps < 0) {
  280 + mutex_unlock(&indio_dev->mlock);
  281 + return sps;
  282 + }
  283 +
  284 + ret = adis16400_set_filter(indio_dev, sps, val);
  285 + mutex_unlock(&indio_dev->mlock);
  286 + return ret;
  287 + default:
  288 + return -EINVAL;
  289 + }
  290 +}
  291 +
  292 +static int adis16400_read_raw(struct iio_dev *indio_dev,
  293 + struct iio_chan_spec const *chan, int *val, int *val2, long info)
  294 +{
  295 + struct adis16400_state *st = iio_priv(indio_dev);
  296 + int16_t val16;
  297 + int ret;
  298 +
  299 + switch (info) {
  300 + case IIO_CHAN_INFO_RAW:
  301 + return adis_single_conversion(indio_dev, chan, 0, val);
  302 + case IIO_CHAN_INFO_SCALE:
  303 + switch (chan->type) {
  304 + case IIO_ANGL_VEL:
  305 + *val = 0;
  306 + *val2 = st->variant->gyro_scale_micro;
  307 + return IIO_VAL_INT_PLUS_MICRO;
  308 + case IIO_VOLTAGE:
  309 + *val = 0;
  310 + if (chan->channel == 0) {
  311 + *val = 2;
  312 + *val2 = 418000; /* 2.418 mV */
  313 + } else {
  314 + *val = 0;
  315 + *val2 = 805800; /* 805.8 uV */
  316 + }
  317 + return IIO_VAL_INT_PLUS_MICRO;
  318 + case IIO_ACCEL:
  319 + *val = 0;
  320 + *val2 = st->variant->accel_scale_micro;
  321 + return IIO_VAL_INT_PLUS_MICRO;
  322 + case IIO_MAGN:
  323 + *val = 0;
  324 + *val2 = 500; /* 0.5 mgauss */
  325 + return IIO_VAL_INT_PLUS_MICRO;
  326 + case IIO_TEMP:
  327 + *val = st->variant->temp_scale_nano / 1000000;
  328 + *val2 = (st->variant->temp_scale_nano % 1000000);
  329 + return IIO_VAL_INT_PLUS_MICRO;
  330 + default:
  331 + return -EINVAL;
  332 + }
  333 + case IIO_CHAN_INFO_CALIBBIAS:
  334 + mutex_lock(&indio_dev->mlock);
  335 + ret = adis_read_reg_16(&st->adis,
  336 + adis16400_addresses[chan->scan_index], &val16);
  337 + mutex_unlock(&indio_dev->mlock);
  338 + if (ret)
  339 + return ret;
  340 + val16 = ((val16 & 0xFFF) << 4) >> 4;
  341 + *val = val16;
  342 + return IIO_VAL_INT;
  343 + case IIO_CHAN_INFO_OFFSET:
  344 + /* currently only temperature */
  345 + *val = st->variant->temp_offset;
  346 + return IIO_VAL_INT;
  347 + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
  348 + mutex_lock(&indio_dev->mlock);
  349 + /* Need both the number of taps and the sampling frequency */
  350 + ret = adis_read_reg_16(&st->adis,
  351 + ADIS16400_SENS_AVG,
  352 + &val16);
  353 + if (ret < 0) {
  354 + mutex_unlock(&indio_dev->mlock);
  355 + return ret;
  356 + }
  357 + ret = st->variant->get_freq(st);
  358 + if (ret >= 0)
  359 + *val = ret / adis16400_3db_divisors[val16 & 0x07];
  360 + *val2 = 0;
  361 + mutex_unlock(&indio_dev->mlock);
  362 + if (ret < 0)
  363 + return ret;
  364 + return IIO_VAL_INT_PLUS_MICRO;
  365 + default:
  366 + return -EINVAL;
  367 + }
  368 +}
  369 +
  370 +#define ADIS16400_VOLTAGE_CHAN(addr, bits, name, si) { \
  371 + .type = IIO_VOLTAGE, \
  372 + .indexed = 1, \
  373 + .channel = 0, \
  374 + .extend_name = name, \
  375 + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
  376 + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
  377 + .address = (addr), \
  378 + .scan_index = (si), \
  379 + .scan_type = { \
  380 + .sign = 'u', \
  381 + .realbits = (bits), \
  382 + .storagebits = 16, \
  383 + .shift = 0, \
  384 + .endianness = IIO_BE, \
  385 + }, \
  386 +}
  387 +
  388 +#define ADIS16400_SUPPLY_CHAN(addr, bits) \
  389 + ADIS16400_VOLTAGE_CHAN(addr, bits, "supply", ADIS16400_SCAN_SUPPLY)
  390 +
  391 +#define ADIS16400_AUX_ADC_CHAN(addr, bits) \
  392 + ADIS16400_VOLTAGE_CHAN(addr, bits, NULL, ADIS16400_SCAN_ADC)
  393 +
  394 +#define ADIS16400_GYRO_CHAN(mod, addr, bits) { \
  395 + .type = IIO_ANGL_VEL, \
  396 + .modified = 1, \
  397 + .channel2 = IIO_MOD_ ## mod, \
  398 + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
  399 + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \
  400 + IIO_CHAN_INFO_SCALE_SHARED_BIT | \
  401 + IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, \
  402 + .address = addr, \
  403 + .scan_index = ADIS16400_SCAN_GYRO_ ## mod, \
  404 + .scan_type = { \
  405 + .sign = 's', \
  406 + .realbits = (bits), \
  407 + .storagebits = 16, \
  408 + .shift = 0, \
  409 + .endianness = IIO_BE, \
  410 + }, \
  411 +}
  412 +
  413 +#define ADIS16400_ACCEL_CHAN(mod, addr, bits) { \
  414 + .type = IIO_ACCEL, \
  415 + .modified = 1, \
  416 + .channel2 = IIO_MOD_ ## mod, \
  417 + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
  418 + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \
  419 + IIO_CHAN_INFO_SCALE_SHARED_BIT | \
  420 + IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, \
  421 + .address = (addr), \
  422 + .scan_index = ADIS16400_SCAN_ACC_ ## mod, \
  423 + .scan_type = { \
  424 + .sign = 's', \
  425 + .realbits = (bits), \
  426 + .storagebits = 16, \
  427 + .shift = 0, \
  428 + .endianness = IIO_BE, \
  429 + }, \
  430 +}
  431 +
  432 +#define ADIS16400_MAGN_CHAN(mod, addr, bits) { \
  433 + .type = IIO_MAGN, \
  434 + .modified = 1, \
  435 + .channel2 = IIO_MOD_ ## mod, \
  436 + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
  437 + IIO_CHAN_INFO_SCALE_SHARED_BIT | \
  438 + IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, \
  439 + .address = (addr), \
  440 + .scan_index = ADIS16400_SCAN_MAGN_ ## mod, \
  441 + .scan_type = { \
  442 + .sign = 's', \
  443 + .realbits = (bits), \
  444 + .storagebits = 16, \
  445 + .shift = 0, \
  446 + .endianness = IIO_BE, \
  447 + }, \
  448 +}
  449 +
  450 +#define ADIS16400_MOD_TEMP_NAME_X "x"
  451 +#define ADIS16400_MOD_TEMP_NAME_Y "y"
  452 +#define ADIS16400_MOD_TEMP_NAME_Z "z"
  453 +
  454 +#define ADIS16400_MOD_TEMP_CHAN(mod, addr, bits) { \
  455 + .type = IIO_TEMP, \
  456 + .indexed = 1, \
  457 + .channel = 0, \
  458 + .extend_name = ADIS16400_MOD_TEMP_NAME_ ## mod, \
  459 + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
  460 + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \
  461 + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \
  462 + IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, \
  463 + .address = (addr), \
  464 + .scan_index = ADIS16350_SCAN_TEMP_ ## mod, \
  465 + .scan_type = { \
  466 + .sign = 's', \
  467 + .realbits = (bits), \
  468 + .storagebits = 16, \
  469 + .shift = 0, \
  470 + .endianness = IIO_BE, \
  471 + }, \
  472 +}
  473 +
  474 +#define ADIS16400_TEMP_CHAN(addr, bits) { \
  475 + .type = IIO_TEMP, \
  476 + .indexed = 1, \
  477 + .channel = 0, \
  478 + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
  479 + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \
  480 + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
  481 + .address = (addr), \
  482 + .scan_index = ADIS16350_SCAN_TEMP_X, \
  483 + .scan_type = { \
  484 + .sign = 's', \
  485 + .realbits = (bits), \
  486 + .storagebits = 16, \
  487 + .shift = 0, \
  488 + .endianness = IIO_BE, \
  489 + }, \
  490 +}
  491 +
  492 +#define ADIS16400_INCLI_CHAN(mod, addr, bits) { \
  493 + .type = IIO_INCLI, \
  494 + .modified = 1, \
  495 + .channel2 = IIO_MOD_ ## mod, \
  496 + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
  497 + IIO_CHAN_INFO_SCALE_SHARED_BIT, \
  498 + .address = (addr), \
  499 + .scan_index = ADIS16300_SCAN_INCLI_ ## mod, \
  500 + .scan_type = { \
  501 + .sign = 's', \
  502 + .realbits = (bits), \
  503 + .storagebits = 16, \
  504 + .shift = 0, \
  505 + .endianness = IIO_BE, \
  506 + }, \
  507 +}
  508 +
  509 +static const struct iio_chan_spec adis16400_channels[] = {
  510 + ADIS16400_SUPPLY_CHAN(ADIS16400_SUPPLY_OUT, 14),
  511 + ADIS16400_GYRO_CHAN(X, ADIS16400_XGYRO_OUT, 14),
  512 + ADIS16400_GYRO_CHAN(Y, ADIS16400_YGYRO_OUT, 14),
  513 + ADIS16400_GYRO_CHAN(Z, ADIS16400_ZGYRO_OUT, 14),
  514 + ADIS16400_ACCEL_CHAN(X, ADIS16400_XACCL_OUT, 14),
  515 + ADIS16400_ACCEL_CHAN(Y, ADIS16400_YACCL_OUT, 14),
  516 + ADIS16400_ACCEL_CHAN(Z, ADIS16400_ZACCL_OUT, 14),
  517 + ADIS16400_MAGN_CHAN(X, ADIS16400_XMAGN_OUT, 14),
  518 + ADIS16400_MAGN_CHAN(Y, ADIS16400_YMAGN_OUT, 14),
  519 + ADIS16400_MAGN_CHAN(Z, ADIS16400_ZMAGN_OUT, 14),
  520 + ADIS16400_TEMP_CHAN(ADIS16400_TEMP_OUT, 12),
  521 + ADIS16400_AUX_ADC_CHAN(ADIS16400_AUX_ADC, 12),
  522 + IIO_CHAN_SOFT_TIMESTAMP(12)
  523 +};
  524 +
  525 +static const struct iio_chan_spec adis16350_channels[] = {
  526 + ADIS16400_SUPPLY_CHAN(ADIS16400_SUPPLY_OUT, 12),
  527 + ADIS16400_GYRO_CHAN(X, ADIS16400_XGYRO_OUT, 14),
  528 + ADIS16400_GYRO_CHAN(Y, ADIS16400_YGYRO_OUT, 14),
  529 + ADIS16400_GYRO_CHAN(Z, ADIS16400_ZGYRO_OUT, 14),
  530 + ADIS16400_ACCEL_CHAN(X, ADIS16400_XACCL_OUT, 14),
  531 + ADIS16400_ACCEL_CHAN(Y, ADIS16400_YACCL_OUT, 14),
  532 + ADIS16400_ACCEL_CHAN(Z, ADIS16400_ZACCL_OUT, 14),
  533 + ADIS16400_MAGN_CHAN(X, ADIS16400_XMAGN_OUT, 14),
  534 + ADIS16400_MAGN_CHAN(Y, ADIS16400_YMAGN_OUT, 14),
  535 + ADIS16400_MAGN_CHAN(Z, ADIS16400_ZMAGN_OUT, 14),
  536 + ADIS16400_AUX_ADC_CHAN(ADIS16300_AUX_ADC, 12),
  537 + ADIS16400_MOD_TEMP_CHAN(X, ADIS16350_XTEMP_OUT, 12),
  538 + ADIS16400_MOD_TEMP_CHAN(Y, ADIS16350_YTEMP_OUT, 12),
  539 + ADIS16400_MOD_TEMP_CHAN(Z, ADIS16350_ZTEMP_OUT, 12),
  540 + IIO_CHAN_SOFT_TIMESTAMP(11)
  541 +};
  542 +
  543 +static const struct iio_chan_spec adis16300_channels[] = {
  544 + ADIS16400_SUPPLY_CHAN(ADIS16400_SUPPLY_OUT, 12),
  545 + ADIS16400_GYRO_CHAN(X, ADIS16400_XGYRO_OUT, 14),
  546 + ADIS16400_ACCEL_CHAN(X, ADIS16400_XACCL_OUT, 14),
  547 + ADIS16400_ACCEL_CHAN(Y, ADIS16400_YACCL_OUT, 14),
  548 + ADIS16400_ACCEL_CHAN(Z, ADIS16400_ZACCL_OUT, 14),
  549 + ADIS16400_TEMP_CHAN(ADIS16350_XTEMP_OUT, 12),
  550 + ADIS16400_AUX_ADC_CHAN(ADIS16300_AUX_ADC, 12),
  551 + ADIS16400_INCLI_CHAN(X, ADIS16300_PITCH_OUT, 13),
  552 + ADIS16400_INCLI_CHAN(Y, ADIS16300_ROLL_OUT, 13),
  553 + IIO_CHAN_SOFT_TIMESTAMP(14)
  554 +};
  555 +
  556 +static const struct iio_chan_spec adis16334_channels[] = {
  557 + ADIS16400_GYRO_CHAN(X, ADIS16400_XGYRO_OUT, 14),
  558 + ADIS16400_GYRO_CHAN(Y, ADIS16400_YGYRO_OUT, 14),
  559 + ADIS16400_GYRO_CHAN(Z, ADIS16400_ZGYRO_OUT, 14),
  560 + ADIS16400_ACCEL_CHAN(X, ADIS16400_XACCL_OUT, 14),
  561 + ADIS16400_ACCEL_CHAN(Y, ADIS16400_YACCL_OUT, 14),
  562 + ADIS16400_ACCEL_CHAN(Z, ADIS16400_ZACCL_OUT, 14),
  563 + ADIS16400_TEMP_CHAN(ADIS16350_XTEMP_OUT, 12),
  564 + IIO_CHAN_SOFT_TIMESTAMP(8)
  565 +};
  566 +
  567 +static struct attribute *adis16400_attributes[] = {
  568 + &iio_dev_attr_sampling_frequency.dev_attr.attr,
  569 + NULL
  570 +};
  571 +
  572 +static const struct attribute_group adis16400_attribute_group = {
  573 + .attrs = adis16400_attributes,
  574 +};
  575 +
  576 +static struct adis16400_chip_info adis16400_chips[] = {
  577 + [ADIS16300] = {
  578 + .channels = adis16300_channels,
  579 + .num_channels = ARRAY_SIZE(adis16300_channels),
  580 + .flags = ADIS16400_HAS_SLOW_MODE,
  581 + .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
  582 + .accel_scale_micro = 5884,
  583 + .temp_scale_nano = 140000000, /* 0.14 C */
  584 + .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */
  585 + .set_freq = adis16400_set_freq,
  586 + .get_freq = adis16400_get_freq,
  587 + },
  588 + [ADIS16334] = {
  589 + .channels = adis16334_channels,
  590 + .num_channels = ARRAY_SIZE(adis16334_channels),
  591 + .flags = ADIS16400_HAS_PROD_ID,
  592 + .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
  593 + .accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */
  594 + .temp_scale_nano = 67850000, /* 0.06785 C */
  595 + .temp_offset = 25000000 / 67850, /* 25 C = 0x00 */
  596 + .set_freq = adis16334_set_freq,
  597 + .get_freq = adis16334_get_freq,
  598 + },
  599 + [ADIS16350] = {
  600 + .channels = adis16350_channels,
  601 + .num_channels = ARRAY_SIZE(adis16350_channels),
  602 + .gyro_scale_micro = IIO_DEGREE_TO_RAD(73260), /* 0.07326 deg/s */
  603 + .accel_scale_micro = IIO_G_TO_M_S_2(2522), /* 0.002522 g */
  604 + .temp_scale_nano = 145300000, /* 0.1453 C */
  605 + .temp_offset = 25000000 / 145300, /* 25 C = 0x00 */
  606 + .flags = ADIS16400_NO_BURST | ADIS16400_HAS_SLOW_MODE,
  607 + .set_freq = adis16400_set_freq,
  608 + .get_freq = adis16400_get_freq,
  609 + },
  610 + [ADIS16360] = {
  611 + .channels = adis16350_channels,
  612 + .num_channels = ARRAY_SIZE(adis16350_channels),
  613 + .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE,
  614 + .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
  615 + .accel_scale_micro = IIO_G_TO_M_S_2(3333), /* 3.333 mg */
  616 + .temp_scale_nano = 136000000, /* 0.136 C */
  617 + .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
  618 + .set_freq = adis16400_set_freq,
  619 + .get_freq = adis16400_get_freq,
  620 + },
  621 + [ADIS16362] = {
  622 + .channels = adis16350_channels,
  623 + .num_channels = ARRAY_SIZE(adis16350_channels),
  624 + .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE,
  625 + .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
  626 + .accel_scale_micro = IIO_G_TO_M_S_2(333), /* 0.333 mg */
  627 + .temp_scale_nano = 136000000, /* 0.136 C */
  628 + .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
  629 + .set_freq = adis16400_set_freq,
  630 + .get_freq = adis16400_get_freq,
  631 + },
  632 + [ADIS16364] = {
  633 + .channels = adis16350_channels,
  634 + .num_channels = ARRAY_SIZE(adis16350_channels),
  635 + .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE,
  636 + .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
  637 + .accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */
  638 + .temp_scale_nano = 136000000, /* 0.136 C */
  639 + .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
  640 + .set_freq = adis16400_set_freq,
  641 + .get_freq = adis16400_get_freq,
  642 + },
  643 + [ADIS16400] = {
  644 + .channels = adis16400_channels,
  645 + .num_channels = ARRAY_SIZE(adis16400_channels),
  646 + .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE,
  647 + .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
  648 + .accel_scale_micro = IIO_G_TO_M_S_2(3333), /* 3.333 mg */
  649 + .temp_scale_nano = 140000000, /* 0.14 C */
  650 + .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */
  651 + .set_freq = adis16400_set_freq,
  652 + .get_freq = adis16400_get_freq,
  653 + }
  654 +};
  655 +
  656 +static const struct iio_info adis16400_info = {
  657 + .driver_module = THIS_MODULE,
  658 + .read_raw = &adis16400_read_raw,
  659 + .write_raw = &adis16400_write_raw,
  660 + .attrs = &adis16400_attribute_group,
  661 + .update_scan_mode = adis16400_update_scan_mode,
  662 +};
  663 +
  664 +static const unsigned long adis16400_burst_scan_mask[] = {
  665 + ~0UL,
  666 + 0,
  667 +};
  668 +
  669 +static const char * const adis16400_status_error_msgs[] = {
  670 + [ADIS16400_DIAG_STAT_ZACCL_FAIL] = "Z-axis accelerometer self-test failure",
  671 + [ADIS16400_DIAG_STAT_YACCL_FAIL] = "Y-axis accelerometer self-test failure",
  672 + [ADIS16400_DIAG_STAT_XACCL_FAIL] = "X-axis accelerometer self-test failure",
  673 + [ADIS16400_DIAG_STAT_XGYRO_FAIL] = "X-axis gyroscope self-test failure",
  674 + [ADIS16400_DIAG_STAT_YGYRO_FAIL] = "Y-axis gyroscope self-test failure",
  675 + [ADIS16400_DIAG_STAT_ZGYRO_FAIL] = "Z-axis gyroscope self-test failure",
  676 + [ADIS16400_DIAG_STAT_ALARM2] = "Alarm 2 active",
  677 + [ADIS16400_DIAG_STAT_ALARM1] = "Alarm 1 active",
  678 + [ADIS16400_DIAG_STAT_FLASH_CHK] = "Flash checksum error",
  679 + [ADIS16400_DIAG_STAT_SELF_TEST] = "Self test error",
  680 + [ADIS16400_DIAG_STAT_OVERFLOW] = "Sensor overrange",
  681 + [ADIS16400_DIAG_STAT_SPI_FAIL] = "SPI failure",
  682 + [ADIS16400_DIAG_STAT_FLASH_UPT] = "Flash update failed",
  683 + [ADIS16400_DIAG_STAT_POWER_HIGH] = "Power supply above 5.25V",
  684 + [ADIS16400_DIAG_STAT_POWER_LOW] = "Power supply below 4.75V",
  685 +};
  686 +
  687 +static const struct adis_data adis16400_data = {
  688 + .msc_ctrl_reg = ADIS16400_MSC_CTRL,
  689 + .glob_cmd_reg = ADIS16400_GLOB_CMD,
  690 + .diag_stat_reg = ADIS16400_DIAG_STAT,
  691 +
  692 + .read_delay = 50,
  693 + .write_delay = 50,
  694 +
  695 + .self_test_mask = ADIS16400_MSC_CTRL_MEM_TEST,
  696 + .startup_delay = ADIS16400_STARTUP_DELAY,
  697 +
  698 + .status_error_msgs = adis16400_status_error_msgs,
  699 + .status_error_mask = BIT(ADIS16400_DIAG_STAT_ZACCL_FAIL) |
  700 + BIT(ADIS16400_DIAG_STAT_YACCL_FAIL) |
  701 + BIT(ADIS16400_DIAG_STAT_XACCL_FAIL) |
  702 + BIT(ADIS16400_DIAG_STAT_XGYRO_FAIL) |
  703 + BIT(ADIS16400_DIAG_STAT_YGYRO_FAIL) |
  704 + BIT(ADIS16400_DIAG_STAT_ZGYRO_FAIL) |
  705 + BIT(ADIS16400_DIAG_STAT_ALARM2) |
  706 + BIT(ADIS16400_DIAG_STAT_ALARM1) |
  707 + BIT(ADIS16400_DIAG_STAT_FLASH_CHK) |
  708 + BIT(ADIS16400_DIAG_STAT_SELF_TEST) |
  709 + BIT(ADIS16400_DIAG_STAT_OVERFLOW) |
  710 + BIT(ADIS16400_DIAG_STAT_SPI_FAIL) |
  711 + BIT(ADIS16400_DIAG_STAT_FLASH_UPT) |
  712 + BIT(ADIS16400_DIAG_STAT_POWER_HIGH) |
  713 + BIT(ADIS16400_DIAG_STAT_POWER_LOW),
  714 +};
  715 +
  716 +static int adis16400_probe(struct spi_device *spi)
  717 +{
  718 + struct adis16400_state *st;
  719 + struct iio_dev *indio_dev;
  720 + int ret;
  721 +
  722 + indio_dev = iio_device_alloc(sizeof(*st));
  723 + if (indio_dev == NULL)
  724 + return -ENOMEM;
  725 +
  726 + st = iio_priv(indio_dev);
  727 + /* this is only used for removal purposes */
  728 + spi_set_drvdata(spi, indio_dev);
  729 +
  730 + /* setup the industrialio driver allocated elements */
  731 + st->variant = &adis16400_chips[spi_get_device_id(spi)->driver_data];
  732 + indio_dev->dev.parent = &spi->dev;
  733 + indio_dev->name = spi_get_device_id(spi)->name;
  734 + indio_dev->channels = st->variant->channels;
  735 + indio_dev->num_channels = st->variant->num_channels;
  736 + indio_dev->info = &adis16400_info;
  737 + indio_dev->modes = INDIO_DIRECT_MODE;
  738 +
  739 + if (!(st->variant->flags & ADIS16400_NO_BURST))
  740 + indio_dev->available_scan_masks = adis16400_burst_scan_mask;
  741 +
  742 + ret = adis_init(&st->adis, indio_dev, spi, &adis16400_data);
  743 + if (ret)
  744 + goto error_free_dev;
  745 +
  746 + ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev,
  747 + adis16400_trigger_handler);
  748 + if (ret)
  749 + goto error_free_dev;
  750 +
  751 + /* Get the device into a sane initial state */
  752 + ret = adis16400_initial_setup(indio_dev);
  753 + if (ret)
  754 + goto error_cleanup_buffer;
  755 + ret = iio_device_register(indio_dev);
  756 + if (ret)
  757 + goto error_cleanup_buffer;
  758 +
  759 + return 0;
  760 +
  761 +error_cleanup_buffer:
  762 + adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
  763 +error_free_dev:
  764 + iio_device_free(indio_dev);
  765 + return ret;
  766 +}
  767 +
  768 +static int adis16400_remove(struct spi_device *spi)
  769 +{
  770 + struct iio_dev *indio_dev = spi_get_drvdata(spi);
  771 + struct adis16400_state *st = iio_priv(indio_dev);
  772 +
  773 + iio_device_unregister(indio_dev);
  774 + adis16400_stop_device(indio_dev);
  775 +
  776 + adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
  777 +
  778 + iio_device_free(indio_dev);
  779 +
  780 + return 0;
  781 +}
  782 +
  783 +static const struct spi_device_id adis16400_id[] = {
  784 + {"adis16300", ADIS16300},
  785 + {"adis16334", ADIS16334},
  786 + {"adis16350", ADIS16350},
  787 + {"adis16354", ADIS16350},
  788 + {"adis16355", ADIS16350},
  789 + {"adis16360", ADIS16360},
  790 + {"adis16362", ADIS16362},
  791 + {"adis16364", ADIS16364},
  792 + {"adis16365", ADIS16360},
  793 + {"adis16400", ADIS16400},
  794 + {"adis16405", ADIS16400},
  795 + {}
  796 +};
  797 +MODULE_DEVICE_TABLE(spi, adis16400_id);
  798 +
  799 +static struct spi_driver adis16400_driver = {
  800 + .driver = {
  801 + .name = "adis16400",
  802 + .owner = THIS_MODULE,
  803 + },
  804 + .id_table = adis16400_id,
  805 + .probe = adis16400_probe,
  806 + .remove = adis16400_remove,
  807 +};
  808 +module_spi_driver(adis16400_driver);
  809 +
  810 +MODULE_AUTHOR("Manuel Stahl <manuel.stahl@iis.fraunhofer.de>");
  811 +MODULE_DESCRIPTION("Analog Devices ADIS16400/5 IMU SPI driver");
  812 +MODULE_LICENSE("GPL v2");
drivers/staging/iio/Kconfig
... ... @@ -32,7 +32,6 @@
32 32 source "drivers/staging/iio/frequency/Kconfig"
33 33 source "drivers/staging/iio/gyro/Kconfig"
34 34 source "drivers/staging/iio/impedance-analyzer/Kconfig"
35   -source "drivers/staging/iio/imu/Kconfig"
36 35 source "drivers/staging/iio/light/Kconfig"
37 36 source "drivers/staging/iio/magnetometer/Kconfig"
38 37 source "drivers/staging/iio/meter/Kconfig"
drivers/staging/iio/Makefile
... ... @@ -20,7 +20,6 @@
20 20 obj-y += frequency/
21 21 obj-y += gyro/
22 22 obj-y += impedance-analyzer/
23   -obj-y += imu/
24 23 obj-y += light/
25 24 obj-y += magnetometer/
26 25 obj-y += meter/
drivers/staging/iio/imu/Kconfig
1   -#
2   -# IIO imu drivers configuration
3   -#
4   -menu "Inertial measurement units"
5   -
6   -config ADIS16400
7   - tristate "Analog Devices ADIS16400 and similar IMU SPI driver"
8   - depends on SPI
9   - select IIO_ADIS_LIB
10   - select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
11   - help
12   - Say yes here to build support for Analog Devices adis16300, adis16344,
13   - adis16350, adis16354, adis16355, adis16360, adis16362, adis16364,
14   - adis16365, adis16400 and adis16405 triaxial inertial sensors
15   - (adis16400 series also have magnetometers).
16   -
17   -endmenu
drivers/staging/iio/imu/Makefile
1   -#
2   -# Makefile for Inertial Measurement Units
3   -#
4   -
5   -adis16400-y := adis16400_core.o
6   -adis16400-$(CONFIG_IIO_BUFFER) += adis16400_ring.o
7   -obj-$(CONFIG_ADIS16400) += adis16400.o
drivers/staging/iio/imu/adis16400.h
1   -/*
2   - * adis16400.h support Analog Devices ADIS16400
3   - * 3d 18g accelerometers,
4   - * 3d gyroscopes,
5   - * 3d 2.5gauss magnetometers via SPI
6   - *
7   - * Copyright (c) 2009 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
8   - * Copyright (c) 2007 Jonathan Cameron <jic23@kernel.org>
9   - *
10   - * Loosely based upon lis3l02dq.h
11   - *
12   - * This program is free software; you can redistribute it and/or modify
13   - * it under the terms of the GNU General Public License version 2 as
14   - * published by the Free Software Foundation.
15   - */
16   -
17   -#ifndef SPI_ADIS16400_H_
18   -#define SPI_ADIS16400_H_
19   -
20   -#include <linux/iio/imu/adis.h>
21   -
22   -#define ADIS16400_STARTUP_DELAY 290 /* ms */
23   -#define ADIS16400_MTEST_DELAY 90 /* ms */
24   -
25   -#define ADIS16400_FLASH_CNT 0x00 /* Flash memory write count */
26   -#define ADIS16400_SUPPLY_OUT 0x02 /* Power supply measurement */
27   -#define ADIS16400_XGYRO_OUT 0x04 /* X-axis gyroscope output */
28   -#define ADIS16400_YGYRO_OUT 0x06 /* Y-axis gyroscope output */
29   -#define ADIS16400_ZGYRO_OUT 0x08 /* Z-axis gyroscope output */
30   -#define ADIS16400_XACCL_OUT 0x0A /* X-axis accelerometer output */
31   -#define ADIS16400_YACCL_OUT 0x0C /* Y-axis accelerometer output */
32   -#define ADIS16400_ZACCL_OUT 0x0E /* Z-axis accelerometer output */
33   -#define ADIS16400_XMAGN_OUT 0x10 /* X-axis magnetometer measurement */
34   -#define ADIS16400_YMAGN_OUT 0x12 /* Y-axis magnetometer measurement */
35   -#define ADIS16400_ZMAGN_OUT 0x14 /* Z-axis magnetometer measurement */
36   -#define ADIS16400_TEMP_OUT 0x16 /* Temperature output */
37   -#define ADIS16400_AUX_ADC 0x18 /* Auxiliary ADC measurement */
38   -
39   -#define ADIS16350_XTEMP_OUT 0x10 /* X-axis gyroscope temperature measurement */
40   -#define ADIS16350_YTEMP_OUT 0x12 /* Y-axis gyroscope temperature measurement */
41   -#define ADIS16350_ZTEMP_OUT 0x14 /* Z-axis gyroscope temperature measurement */
42   -
43   -#define ADIS16300_PITCH_OUT 0x12 /* X axis inclinometer output measurement */
44   -#define ADIS16300_ROLL_OUT 0x14 /* Y axis inclinometer output measurement */
45   -#define ADIS16300_AUX_ADC 0x16 /* Auxiliary ADC measurement */
46   -
47   -/* Calibration parameters */
48   -#define ADIS16400_XGYRO_OFF 0x1A /* X-axis gyroscope bias offset factor */
49   -#define ADIS16400_YGYRO_OFF 0x1C /* Y-axis gyroscope bias offset factor */
50   -#define ADIS16400_ZGYRO_OFF 0x1E /* Z-axis gyroscope bias offset factor */
51   -#define ADIS16400_XACCL_OFF 0x20 /* X-axis acceleration bias offset factor */
52   -#define ADIS16400_YACCL_OFF 0x22 /* Y-axis acceleration bias offset factor */
53   -#define ADIS16400_ZACCL_OFF 0x24 /* Z-axis acceleration bias offset factor */
54   -#define ADIS16400_XMAGN_HIF 0x26 /* X-axis magnetometer, hard-iron factor */
55   -#define ADIS16400_YMAGN_HIF 0x28 /* Y-axis magnetometer, hard-iron factor */
56   -#define ADIS16400_ZMAGN_HIF 0x2A /* Z-axis magnetometer, hard-iron factor */
57   -#define ADIS16400_XMAGN_SIF 0x2C /* X-axis magnetometer, soft-iron factor */
58   -#define ADIS16400_YMAGN_SIF 0x2E /* Y-axis magnetometer, soft-iron factor */
59   -#define ADIS16400_ZMAGN_SIF 0x30 /* Z-axis magnetometer, soft-iron factor */
60   -
61   -#define ADIS16400_GPIO_CTRL 0x32 /* Auxiliary digital input/output control */
62   -#define ADIS16400_MSC_CTRL 0x34 /* Miscellaneous control */
63   -#define ADIS16400_SMPL_PRD 0x36 /* Internal sample period (rate) control */
64   -#define ADIS16400_SENS_AVG 0x38 /* Dynamic range and digital filter control */
65   -#define ADIS16400_SLP_CNT 0x3A /* Sleep mode control */
66   -#define ADIS16400_DIAG_STAT 0x3C /* System status */
67   -
68   -/* Alarm functions */
69   -#define ADIS16400_GLOB_CMD 0x3E /* System command */
70   -#define ADIS16400_ALM_MAG1 0x40 /* Alarm 1 amplitude threshold */
71   -#define ADIS16400_ALM_MAG2 0x42 /* Alarm 2 amplitude threshold */
72   -#define ADIS16400_ALM_SMPL1 0x44 /* Alarm 1 sample size */
73   -#define ADIS16400_ALM_SMPL2 0x46 /* Alarm 2 sample size */
74   -#define ADIS16400_ALM_CTRL 0x48 /* Alarm control */
75   -#define ADIS16400_AUX_DAC 0x4A /* Auxiliary DAC data */
76   -
77   -#define ADIS16400_PRODUCT_ID 0x56 /* Product identifier */
78   -
79   -#define ADIS16400_ERROR_ACTIVE (1<<14)
80   -#define ADIS16400_NEW_DATA (1<<14)
81   -
82   -/* MSC_CTRL */
83   -#define ADIS16400_MSC_CTRL_MEM_TEST (1<<11)
84   -#define ADIS16400_MSC_CTRL_INT_SELF_TEST (1<<10)
85   -#define ADIS16400_MSC_CTRL_NEG_SELF_TEST (1<<9)
86   -#define ADIS16400_MSC_CTRL_POS_SELF_TEST (1<<8)
87   -#define ADIS16400_MSC_CTRL_GYRO_BIAS (1<<7)
88   -#define ADIS16400_MSC_CTRL_ACCL_ALIGN (1<<6)
89   -#define ADIS16400_MSC_CTRL_DATA_RDY_EN (1<<2)
90   -#define ADIS16400_MSC_CTRL_DATA_RDY_POL_HIGH (1<<1)
91   -#define ADIS16400_MSC_CTRL_DATA_RDY_DIO2 (1<<0)
92   -
93   -/* SMPL_PRD */
94   -#define ADIS16400_SMPL_PRD_TIME_BASE (1<<7)
95   -#define ADIS16400_SMPL_PRD_DIV_MASK 0x7F
96   -
97   -/* DIAG_STAT */
98   -#define ADIS16400_DIAG_STAT_ZACCL_FAIL 15
99   -#define ADIS16400_DIAG_STAT_YACCL_FAIL 14
100   -#define ADIS16400_DIAG_STAT_XACCL_FAIL 13
101   -#define ADIS16400_DIAG_STAT_XGYRO_FAIL 12
102   -#define ADIS16400_DIAG_STAT_YGYRO_FAIL 11
103   -#define ADIS16400_DIAG_STAT_ZGYRO_FAIL 10
104   -#define ADIS16400_DIAG_STAT_ALARM2 9
105   -#define ADIS16400_DIAG_STAT_ALARM1 8
106   -#define ADIS16400_DIAG_STAT_FLASH_CHK 6
107   -#define ADIS16400_DIAG_STAT_SELF_TEST 5
108   -#define ADIS16400_DIAG_STAT_OVERFLOW 4
109   -#define ADIS16400_DIAG_STAT_SPI_FAIL 3
110   -#define ADIS16400_DIAG_STAT_FLASH_UPT 2
111   -#define ADIS16400_DIAG_STAT_POWER_HIGH 1
112   -#define ADIS16400_DIAG_STAT_POWER_LOW 0
113   -
114   -/* GLOB_CMD */
115   -#define ADIS16400_GLOB_CMD_SW_RESET (1<<7)
116   -#define ADIS16400_GLOB_CMD_P_AUTO_NULL (1<<4)
117   -#define ADIS16400_GLOB_CMD_FLASH_UPD (1<<3)
118   -#define ADIS16400_GLOB_CMD_DAC_LATCH (1<<2)
119   -#define ADIS16400_GLOB_CMD_FAC_CALIB (1<<1)
120   -#define ADIS16400_GLOB_CMD_AUTO_NULL (1<<0)
121   -
122   -/* SLP_CNT */
123   -#define ADIS16400_SLP_CNT_POWER_OFF (1<<8)
124   -
125   -#define ADIS16334_RATE_DIV_SHIFT 8
126   -#define ADIS16334_RATE_INT_CLK BIT(0)
127   -
128   -#define ADIS16400_SPI_SLOW (u32)(300 * 1000)
129   -#define ADIS16400_SPI_BURST (u32)(1000 * 1000)
130   -#define ADIS16400_SPI_FAST (u32)(2000 * 1000)
131   -
132   -#define ADIS16400_HAS_PROD_ID BIT(0)
133   -#define ADIS16400_NO_BURST BIT(1)
134   -#define ADIS16400_HAS_SLOW_MODE BIT(2)
135   -
136   -struct adis16400_state;
137   -
138   -struct adis16400_chip_info {
139   - const struct iio_chan_spec *channels;
140   - const int num_channels;
141   - const long flags;
142   - unsigned int gyro_scale_micro;
143   - unsigned int accel_scale_micro;
144   - int temp_scale_nano;
145   - int temp_offset;
146   - int (*set_freq)(struct adis16400_state *st, unsigned int freq);
147   - int (*get_freq)(struct adis16400_state *st);
148   -};
149   -
150   -/**
151   - * struct adis16400_state - device instance specific data
152   - * @variant: chip variant info
153   - * @filt_int: integer part of requested filter frequency
154   - * @adis: adis device
155   - **/
156   -struct adis16400_state {
157   - struct adis16400_chip_info *variant;
158   - int filt_int;
159   -
160   - struct adis adis;
161   -};
162   -
163   -/* At the moment triggers are only used for ring buffer
164   - * filling. This may change!
165   - */
166   -
167   -enum {
168   - ADIS16400_SCAN_SUPPLY,
169   - ADIS16400_SCAN_GYRO_X,
170   - ADIS16400_SCAN_GYRO_Y,
171   - ADIS16400_SCAN_GYRO_Z,
172   - ADIS16400_SCAN_ACC_X,
173   - ADIS16400_SCAN_ACC_Y,
174   - ADIS16400_SCAN_ACC_Z,
175   - ADIS16400_SCAN_MAGN_X,
176   - ADIS16400_SCAN_MAGN_Y,
177   - ADIS16400_SCAN_MAGN_Z,
178   - ADIS16350_SCAN_TEMP_X,
179   - ADIS16350_SCAN_TEMP_Y,
180   - ADIS16350_SCAN_TEMP_Z,
181   - ADIS16300_SCAN_INCLI_X,
182   - ADIS16300_SCAN_INCLI_Y,
183   - ADIS16400_SCAN_ADC,
184   -};
185   -
186   -#ifdef CONFIG_IIO_BUFFER
187   -
188   -ssize_t adis16400_read_data_from_ring(struct device *dev,
189   - struct device_attribute *attr,
190   - char *buf);
191   -
192   -
193   -int adis16400_update_scan_mode(struct iio_dev *indio_dev,
194   - const unsigned long *scan_mask);
195   -irqreturn_t adis16400_trigger_handler(int irq, void *p);
196   -
197   -#else /* CONFIG_IIO_BUFFER */
198   -
199   -#define adis16400_update_scan_mode NULL
200   -#define adis16400_trigger_handler NULL
201   -
202   -#endif /* CONFIG_IIO_BUFFER */
203   -
204   -#endif /* SPI_ADIS16400_H_ */
drivers/staging/iio/imu/adis16400_core.c
1   -/*
2   - * adis16400.c support Analog Devices ADIS16400/5
3   - * 3d 2g Linear Accelerometers,
4   - * 3d Gyroscopes,
5   - * 3d Magnetometers via SPI
6   - *
7   - * Copyright (c) 2009 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
8   - * Copyright (c) 2007 Jonathan Cameron <jic23@kernel.org>
9   - * Copyright (c) 2011 Analog Devices Inc.
10   - *
11   - * This program is free software; you can redistribute it and/or modify
12   - * it under the terms of the GNU General Public License version 2 as
13   - * published by the Free Software Foundation.
14   - *
15   - */
16   -
17   -#include <linux/interrupt.h>
18   -#include <linux/irq.h>
19   -#include <linux/delay.h>
20   -#include <linux/mutex.h>
21   -#include <linux/device.h>
22   -#include <linux/kernel.h>
23   -#include <linux/spi/spi.h>
24   -#include <linux/slab.h>
25   -#include <linux/sysfs.h>
26   -#include <linux/list.h>
27   -#include <linux/module.h>
28   -
29   -#include <linux/iio/iio.h>
30   -#include <linux/iio/sysfs.h>
31   -#include <linux/iio/buffer.h>
32   -
33   -#include "adis16400.h"
34   -
35   -enum adis16400_chip_variant {
36   - ADIS16300,
37   - ADIS16334,
38   - ADIS16350,
39   - ADIS16360,
40   - ADIS16362,
41   - ADIS16364,
42   - ADIS16400,
43   -};
44   -
45   -static int adis16334_get_freq(struct adis16400_state *st)
46   -{
47   - int ret;
48   - uint16_t t;
49   -
50   - ret = adis_read_reg_16(&st->adis, ADIS16400_SMPL_PRD, &t);
51   - if (ret < 0)
52   - return ret;
53   -
54   - t >>= ADIS16334_RATE_DIV_SHIFT;
55   -
56   - return (8192 >> t) / 10;
57   -}
58   -
59   -static int adis16334_set_freq(struct adis16400_state *st, unsigned int freq)
60   -{
61   - unsigned int t;
62   -
63   - freq *= 10;
64   - if (freq < 8192)
65   - t = ilog2(8192 / freq);
66   - else
67   - t = 0;
68   -
69   - if (t > 0x31)
70   - t = 0x31;
71   -
72   - t <<= ADIS16334_RATE_DIV_SHIFT;
73   - t |= ADIS16334_RATE_INT_CLK;
74   -
75   - return adis_write_reg_16(&st->adis, ADIS16400_SMPL_PRD, t);
76   -}
77   -
78   -static int adis16400_get_freq(struct adis16400_state *st)
79   -{
80   - int sps, ret;
81   - uint16_t t;
82   -
83   - ret = adis_read_reg_16(&st->adis, ADIS16400_SMPL_PRD, &t);
84   - if (ret < 0)
85   - return ret;
86   -
87   - sps = (t & ADIS16400_SMPL_PRD_TIME_BASE) ? 53 : 1638;
88   - sps /= (t & ADIS16400_SMPL_PRD_DIV_MASK) + 1;
89   -
90   - return sps;
91   -}
92   -
93   -static int adis16400_set_freq(struct adis16400_state *st, unsigned int freq)
94   -{
95   - unsigned int t;
96   -
97   - t = 1638 / freq;
98   - if (t > 0)
99   - t--;
100   - t &= ADIS16400_SMPL_PRD_DIV_MASK;
101   -
102   - if ((t & ADIS16400_SMPL_PRD_DIV_MASK) >= 0x0A)
103   - st->adis.spi->max_speed_hz = ADIS16400_SPI_SLOW;
104   - else
105   - st->adis.spi->max_speed_hz = ADIS16400_SPI_FAST;
106   -
107   - return adis_write_reg_8(&st->adis, ADIS16400_SMPL_PRD, t);
108   -}
109   -
110   -static ssize_t adis16400_read_frequency(struct device *dev,
111   - struct device_attribute *attr,
112   - char *buf)
113   -{
114   - struct iio_dev *indio_dev = dev_to_iio_dev(dev);
115   - struct adis16400_state *st = iio_priv(indio_dev);
116   - int ret;
117   -
118   - ret = st->variant->get_freq(st);
119   - if (ret < 0)
120   - return ret;
121   -
122   - return sprintf(buf, "%d\n", ret);
123   -}
124   -
125   -static const unsigned adis16400_3db_divisors[] = {
126   - [0] = 2, /* Special case */
127   - [1] = 6,
128   - [2] = 12,
129   - [3] = 25,
130   - [4] = 50,
131   - [5] = 100,
132   - [6] = 200,
133   - [7] = 200, /* Not a valid setting */
134   -};
135   -
136   -static int adis16400_set_filter(struct iio_dev *indio_dev, int sps, int val)
137   -{
138   - struct adis16400_state *st = iio_priv(indio_dev);
139   - uint16_t val16;
140   - int i, ret;
141   -
142   - for (i = ARRAY_SIZE(adis16400_3db_divisors) - 1; i >= 1; i--) {
143   - if (sps / adis16400_3db_divisors[i] >= val)
144   - break;
145   - }
146   -
147   - ret = adis_read_reg_16(&st->adis, ADIS16400_SENS_AVG, &val16);
148   - if (ret < 0)
149   - return ret;
150   -
151   - ret = adis_write_reg_16(&st->adis, ADIS16400_SENS_AVG,
152   - (val16 & ~0x07) | i);
153   - return ret;
154   -}
155   -
156   -static ssize_t adis16400_write_frequency(struct device *dev,
157   - struct device_attribute *attr, const char *buf, size_t len)
158   -{
159   - struct iio_dev *indio_dev = dev_to_iio_dev(dev);
160   - struct adis16400_state *st = iio_priv(indio_dev);
161   - long val;
162   - int ret;
163   -
164   - ret = kstrtol(buf, 10, &val);
165   - if (ret)
166   - return ret;
167   -
168   - if (val == 0)
169   - return -EINVAL;
170   -
171   - mutex_lock(&indio_dev->mlock);
172   - st->variant->set_freq(st, val);
173   - mutex_unlock(&indio_dev->mlock);
174   -
175   - return ret ? ret : len;
176   -}
177   -
178   -/* Power down the device */
179   -static int adis16400_stop_device(struct iio_dev *indio_dev)
180   -{
181   - struct adis16400_state *st = iio_priv(indio_dev);
182   - int ret;
183   -
184   - ret = adis_write_reg_16(&st->adis, ADIS16400_SLP_CNT,
185   - ADIS16400_SLP_CNT_POWER_OFF);
186   - if (ret)
187   - dev_err(&indio_dev->dev,
188   - "problem with turning device off: SLP_CNT");
189   -
190   - return ret;
191   -}
192   -
193   -static int adis16400_initial_setup(struct iio_dev *indio_dev)
194   -{
195   - struct adis16400_state *st = iio_priv(indio_dev);
196   - uint16_t prod_id, smp_prd;
197   - unsigned int device_id;
198   - int ret;
199   -
200   - /* use low spi speed for init if the device has a slow mode */
201   - if (st->variant->flags & ADIS16400_HAS_SLOW_MODE)
202   - st->adis.spi->max_speed_hz = ADIS16400_SPI_SLOW;
203   - else
204   - st->adis.spi->max_speed_hz = ADIS16400_SPI_FAST;
205   - st->adis.spi->mode = SPI_MODE_3;
206   - spi_setup(st->adis.spi);
207   -
208   - ret = adis_initial_startup(&st->adis);
209   - if (ret)
210   - return ret;
211   -
212   - if (st->variant->flags & ADIS16400_HAS_PROD_ID) {
213   - ret = adis_read_reg_16(&st->adis,
214   - ADIS16400_PRODUCT_ID, &prod_id);
215   - if (ret)
216   - goto err_ret;
217   -
218   - sscanf(indio_dev->name, "adis%u\n", &device_id);
219   -
220   - if (prod_id != device_id)
221   - dev_warn(&indio_dev->dev, "Device ID(%u) and product ID(%u) do not match.",
222   - device_id, prod_id);
223   -
224   - dev_info(&indio_dev->dev, "%s: prod_id 0x%04x at CS%d (irq %d)\n",
225   - indio_dev->name, prod_id,
226   - st->adis.spi->chip_select, st->adis.spi->irq);
227   - }
228   - /* use high spi speed if possible */
229   - if (st->variant->flags & ADIS16400_HAS_SLOW_MODE) {
230   - ret = adis_read_reg_16(&st->adis, ADIS16400_SMPL_PRD, &smp_prd);
231   - if (ret)
232   - goto err_ret;
233   -
234   - if ((smp_prd & ADIS16400_SMPL_PRD_DIV_MASK) < 0x0A) {
235   - st->adis.spi->max_speed_hz = ADIS16400_SPI_FAST;
236   - spi_setup(st->adis.spi);
237   - }
238   - }
239   -
240   -err_ret:
241   - return ret;
242   -}
243   -
244   -static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
245   - adis16400_read_frequency,
246   - adis16400_write_frequency);
247   -
248   -static const uint8_t adis16400_addresses[] = {
249   - [ADIS16400_SCAN_GYRO_X] = ADIS16400_XGYRO_OFF,
250   - [ADIS16400_SCAN_GYRO_Y] = ADIS16400_YGYRO_OFF,
251   - [ADIS16400_SCAN_GYRO_Z] = ADIS16400_ZGYRO_OFF,
252   - [ADIS16400_SCAN_ACC_X] = ADIS16400_XACCL_OFF,
253   - [ADIS16400_SCAN_ACC_Y] = ADIS16400_YACCL_OFF,
254   - [ADIS16400_SCAN_ACC_Z] = ADIS16400_ZACCL_OFF,
255   -};
256   -
257   -static int adis16400_write_raw(struct iio_dev *indio_dev,
258   - struct iio_chan_spec const *chan, int val, int val2, long info)
259   -{
260   - struct adis16400_state *st = iio_priv(indio_dev);
261   - int ret, sps;
262   -
263   - switch (info) {
264   - case IIO_CHAN_INFO_CALIBBIAS:
265   - mutex_lock(&indio_dev->mlock);
266   - ret = adis_write_reg_16(&st->adis,
267   - adis16400_addresses[chan->scan_index], val);
268   - mutex_unlock(&indio_dev->mlock);
269   - return ret;
270   - case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
271   - /*
272   - * Need to cache values so we can update if the frequency
273   - * changes.
274   - */
275   - mutex_lock(&indio_dev->mlock);
276   - st->filt_int = val;
277   - /* Work out update to current value */
278   - sps = st->variant->get_freq(st);
279   - if (sps < 0) {
280   - mutex_unlock(&indio_dev->mlock);
281   - return sps;
282   - }
283   -
284   - ret = adis16400_set_filter(indio_dev, sps, val);
285   - mutex_unlock(&indio_dev->mlock);
286   - return ret;
287   - default:
288   - return -EINVAL;
289   - }
290   -}
291   -
292   -static int adis16400_read_raw(struct iio_dev *indio_dev,
293   - struct iio_chan_spec const *chan, int *val, int *val2, long info)
294   -{
295   - struct adis16400_state *st = iio_priv(indio_dev);
296   - int16_t val16;
297   - int ret;
298   -
299   - switch (info) {
300   - case IIO_CHAN_INFO_RAW:
301   - return adis_single_conversion(indio_dev, chan, 0, val);
302   - case IIO_CHAN_INFO_SCALE:
303   - switch (chan->type) {
304   - case IIO_ANGL_VEL:
305   - *val = 0;
306   - *val2 = st->variant->gyro_scale_micro;
307   - return IIO_VAL_INT_PLUS_MICRO;
308   - case IIO_VOLTAGE:
309   - *val = 0;
310   - if (chan->channel == 0) {
311   - *val = 2;
312   - *val2 = 418000; /* 2.418 mV */
313   - } else {
314   - *val = 0;
315   - *val2 = 805800; /* 805.8 uV */
316   - }
317   - return IIO_VAL_INT_PLUS_MICRO;
318   - case IIO_ACCEL:
319   - *val = 0;
320   - *val2 = st->variant->accel_scale_micro;
321   - return IIO_VAL_INT_PLUS_MICRO;
322   - case IIO_MAGN:
323   - *val = 0;
324   - *val2 = 500; /* 0.5 mgauss */
325   - return IIO_VAL_INT_PLUS_MICRO;
326   - case IIO_TEMP:
327   - *val = st->variant->temp_scale_nano / 1000000;
328   - *val2 = (st->variant->temp_scale_nano % 1000000);
329   - return IIO_VAL_INT_PLUS_MICRO;
330   - default:
331   - return -EINVAL;
332   - }
333   - case IIO_CHAN_INFO_CALIBBIAS:
334   - mutex_lock(&indio_dev->mlock);
335   - ret = adis_read_reg_16(&st->adis,
336   - adis16400_addresses[chan->scan_index], &val16);
337   - mutex_unlock(&indio_dev->mlock);
338   - if (ret)
339   - return ret;
340   - val16 = ((val16 & 0xFFF) << 4) >> 4;
341   - *val = val16;
342   - return IIO_VAL_INT;
343   - case IIO_CHAN_INFO_OFFSET:
344   - /* currently only temperature */
345   - *val = st->variant->temp_offset;
346   - return IIO_VAL_INT;
347   - case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
348   - mutex_lock(&indio_dev->mlock);
349   - /* Need both the number of taps and the sampling frequency */
350   - ret = adis_read_reg_16(&st->adis,
351   - ADIS16400_SENS_AVG,
352   - &val16);
353   - if (ret < 0) {
354   - mutex_unlock(&indio_dev->mlock);
355   - return ret;
356   - }
357   - ret = st->variant->get_freq(st);
358   - if (ret >= 0)
359   - *val = ret / adis16400_3db_divisors[val16 & 0x07];
360   - *val2 = 0;
361   - mutex_unlock(&indio_dev->mlock);
362   - if (ret < 0)
363   - return ret;
364   - return IIO_VAL_INT_PLUS_MICRO;
365   - default:
366   - return -EINVAL;
367   - }
368   -}
369   -
370   -#define ADIS16400_VOLTAGE_CHAN(addr, bits, name, si) { \
371   - .type = IIO_VOLTAGE, \
372   - .indexed = 1, \
373   - .channel = 0, \
374   - .extend_name = name, \
375   - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
376   - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
377   - .address = (addr), \
378   - .scan_index = (si), \
379   - .scan_type = { \
380   - .sign = 'u', \
381   - .realbits = (bits), \
382   - .storagebits = 16, \
383   - .shift = 0, \
384   - .endianness = IIO_BE, \
385   - }, \
386   -}
387   -
388   -#define ADIS16400_SUPPLY_CHAN(addr, bits) \
389   - ADIS16400_VOLTAGE_CHAN(addr, bits, "supply", ADIS16400_SCAN_SUPPLY)
390   -
391   -#define ADIS16400_AUX_ADC_CHAN(addr, bits) \
392   - ADIS16400_VOLTAGE_CHAN(addr, bits, NULL, ADIS16400_SCAN_ADC)
393   -
394   -#define ADIS16400_GYRO_CHAN(mod, addr, bits) { \
395   - .type = IIO_ANGL_VEL, \
396   - .modified = 1, \
397   - .channel2 = IIO_MOD_ ## mod, \
398   - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
399   - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \
400   - IIO_CHAN_INFO_SCALE_SHARED_BIT | \
401   - IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, \
402   - .address = addr, \
403   - .scan_index = ADIS16400_SCAN_GYRO_ ## mod, \
404   - .scan_type = { \
405   - .sign = 's', \
406   - .realbits = (bits), \
407   - .storagebits = 16, \
408   - .shift = 0, \
409   - .endianness = IIO_BE, \
410   - }, \
411   -}
412   -
413   -#define ADIS16400_ACCEL_CHAN(mod, addr, bits) { \
414   - .type = IIO_ACCEL, \
415   - .modified = 1, \
416   - .channel2 = IIO_MOD_ ## mod, \
417   - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
418   - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \
419   - IIO_CHAN_INFO_SCALE_SHARED_BIT | \
420   - IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, \
421   - .address = (addr), \
422   - .scan_index = ADIS16400_SCAN_ACC_ ## mod, \
423   - .scan_type = { \
424   - .sign = 's', \
425   - .realbits = (bits), \
426   - .storagebits = 16, \
427   - .shift = 0, \
428   - .endianness = IIO_BE, \
429   - }, \
430   -}
431   -
432   -#define ADIS16400_MAGN_CHAN(mod, addr, bits) { \
433   - .type = IIO_MAGN, \
434   - .modified = 1, \
435   - .channel2 = IIO_MOD_ ## mod, \
436   - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
437   - IIO_CHAN_INFO_SCALE_SHARED_BIT | \
438   - IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, \
439   - .address = (addr), \
440   - .scan_index = ADIS16400_SCAN_MAGN_ ## mod, \
441   - .scan_type = { \
442   - .sign = 's', \
443   - .realbits = (bits), \
444   - .storagebits = 16, \
445   - .shift = 0, \
446   - .endianness = IIO_BE, \
447   - }, \
448   -}
449   -
450   -#define ADIS16400_MOD_TEMP_NAME_X "x"
451   -#define ADIS16400_MOD_TEMP_NAME_Y "y"
452   -#define ADIS16400_MOD_TEMP_NAME_Z "z"
453   -
454   -#define ADIS16400_MOD_TEMP_CHAN(mod, addr, bits) { \
455   - .type = IIO_TEMP, \
456   - .indexed = 1, \
457   - .channel = 0, \
458   - .extend_name = ADIS16400_MOD_TEMP_NAME_ ## mod, \
459   - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
460   - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \
461   - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \
462   - IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, \
463   - .address = (addr), \
464   - .scan_index = ADIS16350_SCAN_TEMP_ ## mod, \
465   - .scan_type = { \
466   - .sign = 's', \
467   - .realbits = (bits), \
468   - .storagebits = 16, \
469   - .shift = 0, \
470   - .endianness = IIO_BE, \
471   - }, \
472   -}
473   -
474   -#define ADIS16400_TEMP_CHAN(addr, bits) { \
475   - .type = IIO_TEMP, \
476   - .indexed = 1, \
477   - .channel = 0, \
478   - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
479   - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \
480   - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
481   - .address = (addr), \
482   - .scan_index = ADIS16350_SCAN_TEMP_X, \
483   - .scan_type = { \
484   - .sign = 's', \
485   - .realbits = (bits), \
486   - .storagebits = 16, \
487   - .shift = 0, \
488   - .endianness = IIO_BE, \
489   - }, \
490   -}
491   -
492   -#define ADIS16400_INCLI_CHAN(mod, addr, bits) { \
493   - .type = IIO_INCLI, \
494   - .modified = 1, \
495   - .channel2 = IIO_MOD_ ## mod, \
496   - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
497   - IIO_CHAN_INFO_SCALE_SHARED_BIT, \
498   - .address = (addr), \
499   - .scan_index = ADIS16300_SCAN_INCLI_ ## mod, \
500   - .scan_type = { \
501   - .sign = 's', \
502   - .realbits = (bits), \
503   - .storagebits = 16, \
504   - .shift = 0, \
505   - .endianness = IIO_BE, \
506   - }, \
507   -}
508   -
509   -static const struct iio_chan_spec adis16400_channels[] = {
510   - ADIS16400_SUPPLY_CHAN(ADIS16400_SUPPLY_OUT, 14),
511   - ADIS16400_GYRO_CHAN(X, ADIS16400_XGYRO_OUT, 14),
512   - ADIS16400_GYRO_CHAN(Y, ADIS16400_YGYRO_OUT, 14),
513   - ADIS16400_GYRO_CHAN(Z, ADIS16400_ZGYRO_OUT, 14),
514   - ADIS16400_ACCEL_CHAN(X, ADIS16400_XACCL_OUT, 14),
515   - ADIS16400_ACCEL_CHAN(Y, ADIS16400_YACCL_OUT, 14),
516   - ADIS16400_ACCEL_CHAN(Z, ADIS16400_ZACCL_OUT, 14),
517   - ADIS16400_MAGN_CHAN(X, ADIS16400_XMAGN_OUT, 14),
518   - ADIS16400_MAGN_CHAN(Y, ADIS16400_YMAGN_OUT, 14),
519   - ADIS16400_MAGN_CHAN(Z, ADIS16400_ZMAGN_OUT, 14),
520   - ADIS16400_TEMP_CHAN(ADIS16400_TEMP_OUT, 12),
521   - ADIS16400_AUX_ADC_CHAN(ADIS16400_AUX_ADC, 12),
522   - IIO_CHAN_SOFT_TIMESTAMP(12)
523   -};
524   -
525   -static const struct iio_chan_spec adis16350_channels[] = {
526   - ADIS16400_SUPPLY_CHAN(ADIS16400_SUPPLY_OUT, 12),
527   - ADIS16400_GYRO_CHAN(X, ADIS16400_XGYRO_OUT, 14),
528   - ADIS16400_GYRO_CHAN(Y, ADIS16400_YGYRO_OUT, 14),
529   - ADIS16400_GYRO_CHAN(Z, ADIS16400_ZGYRO_OUT, 14),
530   - ADIS16400_ACCEL_CHAN(X, ADIS16400_XACCL_OUT, 14),
531   - ADIS16400_ACCEL_CHAN(Y, ADIS16400_YACCL_OUT, 14),
532   - ADIS16400_ACCEL_CHAN(Z, ADIS16400_ZACCL_OUT, 14),
533   - ADIS16400_MAGN_CHAN(X, ADIS16400_XMAGN_OUT, 14),
534   - ADIS16400_MAGN_CHAN(Y, ADIS16400_YMAGN_OUT, 14),
535   - ADIS16400_MAGN_CHAN(Z, ADIS16400_ZMAGN_OUT, 14),
536   - ADIS16400_AUX_ADC_CHAN(ADIS16300_AUX_ADC, 12),
537   - ADIS16400_MOD_TEMP_CHAN(X, ADIS16350_XTEMP_OUT, 12),
538   - ADIS16400_MOD_TEMP_CHAN(Y, ADIS16350_YTEMP_OUT, 12),
539   - ADIS16400_MOD_TEMP_CHAN(Z, ADIS16350_ZTEMP_OUT, 12),
540   - IIO_CHAN_SOFT_TIMESTAMP(11)
541   -};
542   -
543   -static const struct iio_chan_spec adis16300_channels[] = {
544   - ADIS16400_SUPPLY_CHAN(ADIS16400_SUPPLY_OUT, 12),
545   - ADIS16400_GYRO_CHAN(X, ADIS16400_XGYRO_OUT, 14),
546   - ADIS16400_ACCEL_CHAN(X, ADIS16400_XACCL_OUT, 14),
547   - ADIS16400_ACCEL_CHAN(Y, ADIS16400_YACCL_OUT, 14),
548   - ADIS16400_ACCEL_CHAN(Z, ADIS16400_ZACCL_OUT, 14),
549   - ADIS16400_TEMP_CHAN(ADIS16350_XTEMP_OUT, 12),
550   - ADIS16400_AUX_ADC_CHAN(ADIS16300_AUX_ADC, 12),
551   - ADIS16400_INCLI_CHAN(X, ADIS16300_PITCH_OUT, 13),
552   - ADIS16400_INCLI_CHAN(Y, ADIS16300_ROLL_OUT, 13),
553   - IIO_CHAN_SOFT_TIMESTAMP(14)
554   -};
555   -
556   -static const struct iio_chan_spec adis16334_channels[] = {
557   - ADIS16400_GYRO_CHAN(X, ADIS16400_XGYRO_OUT, 14),
558   - ADIS16400_GYRO_CHAN(Y, ADIS16400_YGYRO_OUT, 14),
559   - ADIS16400_GYRO_CHAN(Z, ADIS16400_ZGYRO_OUT, 14),
560   - ADIS16400_ACCEL_CHAN(X, ADIS16400_XACCL_OUT, 14),
561   - ADIS16400_ACCEL_CHAN(Y, ADIS16400_YACCL_OUT, 14),
562   - ADIS16400_ACCEL_CHAN(Z, ADIS16400_ZACCL_OUT, 14),
563   - ADIS16400_TEMP_CHAN(ADIS16350_XTEMP_OUT, 12),
564   - IIO_CHAN_SOFT_TIMESTAMP(8)
565   -};
566   -
567   -static struct attribute *adis16400_attributes[] = {
568   - &iio_dev_attr_sampling_frequency.dev_attr.attr,
569   - NULL
570   -};
571   -
572   -static const struct attribute_group adis16400_attribute_group = {
573   - .attrs = adis16400_attributes,
574   -};
575   -
576   -static struct adis16400_chip_info adis16400_chips[] = {
577   - [ADIS16300] = {
578   - .channels = adis16300_channels,
579   - .num_channels = ARRAY_SIZE(adis16300_channels),
580   - .flags = ADIS16400_HAS_SLOW_MODE,
581   - .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
582   - .accel_scale_micro = 5884,
583   - .temp_scale_nano = 140000000, /* 0.14 C */
584   - .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */
585   - .set_freq = adis16400_set_freq,
586   - .get_freq = adis16400_get_freq,
587   - },
588   - [ADIS16334] = {
589   - .channels = adis16334_channels,
590   - .num_channels = ARRAY_SIZE(adis16334_channels),
591   - .flags = ADIS16400_HAS_PROD_ID,
592   - .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
593   - .accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */
594   - .temp_scale_nano = 67850000, /* 0.06785 C */
595   - .temp_offset = 25000000 / 67850, /* 25 C = 0x00 */
596   - .set_freq = adis16334_set_freq,
597   - .get_freq = adis16334_get_freq,
598   - },
599   - [ADIS16350] = {
600   - .channels = adis16350_channels,
601   - .num_channels = ARRAY_SIZE(adis16350_channels),
602   - .gyro_scale_micro = IIO_DEGREE_TO_RAD(73260), /* 0.07326 deg/s */
603   - .accel_scale_micro = IIO_G_TO_M_S_2(2522), /* 0.002522 g */
604   - .temp_scale_nano = 145300000, /* 0.1453 C */
605   - .temp_offset = 25000000 / 145300, /* 25 C = 0x00 */
606   - .flags = ADIS16400_NO_BURST | ADIS16400_HAS_SLOW_MODE,
607   - .set_freq = adis16400_set_freq,
608   - .get_freq = adis16400_get_freq,
609   - },
610   - [ADIS16360] = {
611   - .channels = adis16350_channels,
612   - .num_channels = ARRAY_SIZE(adis16350_channels),
613   - .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE,
614   - .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
615   - .accel_scale_micro = IIO_G_TO_M_S_2(3333), /* 3.333 mg */
616   - .temp_scale_nano = 136000000, /* 0.136 C */
617   - .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
618   - .set_freq = adis16400_set_freq,
619   - .get_freq = adis16400_get_freq,
620   - },
621   - [ADIS16362] = {
622   - .channels = adis16350_channels,
623   - .num_channels = ARRAY_SIZE(adis16350_channels),
624   - .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE,
625   - .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
626   - .accel_scale_micro = IIO_G_TO_M_S_2(333), /* 0.333 mg */
627   - .temp_scale_nano = 136000000, /* 0.136 C */
628   - .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
629   - .set_freq = adis16400_set_freq,
630   - .get_freq = adis16400_get_freq,
631   - },
632   - [ADIS16364] = {
633   - .channels = adis16350_channels,
634   - .num_channels = ARRAY_SIZE(adis16350_channels),
635   - .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE,
636   - .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
637   - .accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */
638   - .temp_scale_nano = 136000000, /* 0.136 C */
639   - .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
640   - .set_freq = adis16400_set_freq,
641   - .get_freq = adis16400_get_freq,
642   - },
643   - [ADIS16400] = {
644   - .channels = adis16400_channels,
645   - .num_channels = ARRAY_SIZE(adis16400_channels),
646   - .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE,
647   - .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
648   - .accel_scale_micro = IIO_G_TO_M_S_2(3333), /* 3.333 mg */
649   - .temp_scale_nano = 140000000, /* 0.14 C */
650   - .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */
651   - .set_freq = adis16400_set_freq,
652   - .get_freq = adis16400_get_freq,
653   - }
654   -};
655   -
656   -static const struct iio_info adis16400_info = {
657   - .driver_module = THIS_MODULE,
658   - .read_raw = &adis16400_read_raw,
659   - .write_raw = &adis16400_write_raw,
660   - .attrs = &adis16400_attribute_group,
661   - .update_scan_mode = adis16400_update_scan_mode,
662   -};
663   -
664   -static const unsigned long adis16400_burst_scan_mask[] = {
665   - ~0UL,
666   - 0,
667   -};
668   -
669   -static const char * const adis16400_status_error_msgs[] = {
670   - [ADIS16400_DIAG_STAT_ZACCL_FAIL] = "Z-axis accelerometer self-test failure",
671   - [ADIS16400_DIAG_STAT_YACCL_FAIL] = "Y-axis accelerometer self-test failure",
672   - [ADIS16400_DIAG_STAT_XACCL_FAIL] = "X-axis accelerometer self-test failure",
673   - [ADIS16400_DIAG_STAT_XGYRO_FAIL] = "X-axis gyroscope self-test failure",
674   - [ADIS16400_DIAG_STAT_YGYRO_FAIL] = "Y-axis gyroscope self-test failure",
675   - [ADIS16400_DIAG_STAT_ZGYRO_FAIL] = "Z-axis gyroscope self-test failure",
676   - [ADIS16400_DIAG_STAT_ALARM2] = "Alarm 2 active",
677   - [ADIS16400_DIAG_STAT_ALARM1] = "Alarm 1 active",
678   - [ADIS16400_DIAG_STAT_FLASH_CHK] = "Flash checksum error",
679   - [ADIS16400_DIAG_STAT_SELF_TEST] = "Self test error",
680   - [ADIS16400_DIAG_STAT_OVERFLOW] = "Sensor overrange",
681   - [ADIS16400_DIAG_STAT_SPI_FAIL] = "SPI failure",
682   - [ADIS16400_DIAG_STAT_FLASH_UPT] = "Flash update failed",
683   - [ADIS16400_DIAG_STAT_POWER_HIGH] = "Power supply above 5.25V",
684   - [ADIS16400_DIAG_STAT_POWER_LOW] = "Power supply below 4.75V",
685   -};
686   -
687   -static const struct adis_data adis16400_data = {
688   - .msc_ctrl_reg = ADIS16400_MSC_CTRL,
689   - .glob_cmd_reg = ADIS16400_GLOB_CMD,
690   - .diag_stat_reg = ADIS16400_DIAG_STAT,
691   -
692   - .read_delay = 50,
693   - .write_delay = 50,
694   -
695   - .self_test_mask = ADIS16400_MSC_CTRL_MEM_TEST,
696   - .startup_delay = ADIS16400_STARTUP_DELAY,
697   -
698   - .status_error_msgs = adis16400_status_error_msgs,
699   - .status_error_mask = BIT(ADIS16400_DIAG_STAT_ZACCL_FAIL) |
700   - BIT(ADIS16400_DIAG_STAT_YACCL_FAIL) |
701   - BIT(ADIS16400_DIAG_STAT_XACCL_FAIL) |
702   - BIT(ADIS16400_DIAG_STAT_XGYRO_FAIL) |
703   - BIT(ADIS16400_DIAG_STAT_YGYRO_FAIL) |
704   - BIT(ADIS16400_DIAG_STAT_ZGYRO_FAIL) |
705   - BIT(ADIS16400_DIAG_STAT_ALARM2) |
706   - BIT(ADIS16400_DIAG_STAT_ALARM1) |
707   - BIT(ADIS16400_DIAG_STAT_FLASH_CHK) |
708   - BIT(ADIS16400_DIAG_STAT_SELF_TEST) |
709   - BIT(ADIS16400_DIAG_STAT_OVERFLOW) |
710   - BIT(ADIS16400_DIAG_STAT_SPI_FAIL) |
711   - BIT(ADIS16400_DIAG_STAT_FLASH_UPT) |
712   - BIT(ADIS16400_DIAG_STAT_POWER_HIGH) |
713   - BIT(ADIS16400_DIAG_STAT_POWER_LOW),
714   -};
715   -
716   -static int adis16400_probe(struct spi_device *spi)
717   -{
718   - struct adis16400_state *st;
719   - struct iio_dev *indio_dev;
720   - int ret;
721   -
722   - indio_dev = iio_device_alloc(sizeof(*st));
723   - if (indio_dev == NULL)
724   - return -ENOMEM;
725   -
726   - st = iio_priv(indio_dev);
727   - /* this is only used for removal purposes */
728   - spi_set_drvdata(spi, indio_dev);
729   -
730   - /* setup the industrialio driver allocated elements */
731   - st->variant = &adis16400_chips[spi_get_device_id(spi)->driver_data];
732   - indio_dev->dev.parent = &spi->dev;
733   - indio_dev->name = spi_get_device_id(spi)->name;
734   - indio_dev->channels = st->variant->channels;
735   - indio_dev->num_channels = st->variant->num_channels;
736   - indio_dev->info = &adis16400_info;
737   - indio_dev->modes = INDIO_DIRECT_MODE;
738   -
739   - if (!(st->variant->flags & ADIS16400_NO_BURST))
740   - indio_dev->available_scan_masks = adis16400_burst_scan_mask;
741   -
742   - ret = adis_init(&st->adis, indio_dev, spi, &adis16400_data);
743   - if (ret)
744   - goto error_free_dev;
745   -
746   - ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev,
747   - adis16400_trigger_handler);
748   - if (ret)
749   - goto error_free_dev;
750   -
751   - /* Get the device into a sane initial state */
752   - ret = adis16400_initial_setup(indio_dev);
753   - if (ret)
754   - goto error_cleanup_buffer;
755   - ret = iio_device_register(indio_dev);
756   - if (ret)
757   - goto error_cleanup_buffer;
758   -
759   - return 0;
760   -
761   -error_cleanup_buffer:
762   - adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
763   -error_free_dev:
764   - iio_device_free(indio_dev);
765   - return ret;
766   -}
767   -
768   -static int adis16400_remove(struct spi_device *spi)
769   -{
770   - struct iio_dev *indio_dev = spi_get_drvdata(spi);
771   - struct adis16400_state *st = iio_priv(indio_dev);
772   -
773   - iio_device_unregister(indio_dev);
774   - adis16400_stop_device(indio_dev);
775   -
776   - adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
777   -
778   - iio_device_free(indio_dev);
779   -
780   - return 0;
781   -}
782   -
783   -static const struct spi_device_id adis16400_id[] = {
784   - {"adis16300", ADIS16300},
785   - {"adis16334", ADIS16334},
786   - {"adis16350", ADIS16350},
787   - {"adis16354", ADIS16350},
788   - {"adis16355", ADIS16350},
789   - {"adis16360", ADIS16360},
790   - {"adis16362", ADIS16362},
791   - {"adis16364", ADIS16364},
792   - {"adis16365", ADIS16360},
793   - {"adis16400", ADIS16400},
794   - {"adis16405", ADIS16400},
795   - {}
796   -};
797   -MODULE_DEVICE_TABLE(spi, adis16400_id);
798   -
799   -static struct spi_driver adis16400_driver = {
800   - .driver = {
801   - .name = "adis16400",
802   - .owner = THIS_MODULE,
803   - },
804   - .id_table = adis16400_id,
805   - .probe = adis16400_probe,
806   - .remove = adis16400_remove,
807   -};
808   -module_spi_driver(adis16400_driver);
809   -
810   -MODULE_AUTHOR("Manuel Stahl <manuel.stahl@iis.fraunhofer.de>");
811   -MODULE_DESCRIPTION("Analog Devices ADIS16400/5 IMU SPI driver");
812   -MODULE_LICENSE("GPL v2");
drivers/staging/iio/imu/adis16400_ring.c
1   -#include <linux/interrupt.h>
2   -#include <linux/mutex.h>
3   -#include <linux/kernel.h>
4   -#include <linux/spi/spi.h>
5   -#include <linux/slab.h>
6   -#include <linux/bitops.h>
7   -#include <linux/export.h>
8   -
9   -#include <linux/iio/iio.h>
10   -#include <linux/iio/buffer.h>
11   -#include <linux/iio/triggered_buffer.h>
12   -#include <linux/iio/trigger_consumer.h>
13   -
14   -#include "adis16400.h"
15   -
16   -int adis16400_update_scan_mode(struct iio_dev *indio_dev,
17   - const unsigned long *scan_mask)
18   -{
19   - struct adis16400_state *st = iio_priv(indio_dev);
20   - struct adis *adis = &st->adis;
21   - uint16_t *tx, *rx;
22   -
23   - if (st->variant->flags & ADIS16400_NO_BURST)
24   - return adis_update_scan_mode(indio_dev, scan_mask);
25   -
26   - kfree(adis->xfer);
27   - kfree(adis->buffer);
28   -
29   - adis->xfer = kcalloc(2, sizeof(*adis->xfer), GFP_KERNEL);
30   - if (!adis->xfer)
31   - return -ENOMEM;
32   -
33   - adis->buffer = kzalloc(indio_dev->scan_bytes + sizeof(u16),
34   - GFP_KERNEL);
35   - if (!adis->buffer)
36   - return -ENOMEM;
37   -
38   - rx = adis->buffer;
39   - tx = adis->buffer + indio_dev->scan_bytes;
40   -
41   - tx[0] = ADIS_READ_REG(ADIS16400_GLOB_CMD);
42   - tx[1] = 0;
43   -
44   - adis->xfer[0].tx_buf = tx;
45   - adis->xfer[0].bits_per_word = 8;
46   - adis->xfer[0].len = 2;
47   - adis->xfer[1].tx_buf = tx;
48   - adis->xfer[1].bits_per_word = 8;
49   - adis->xfer[1].len = indio_dev->scan_bytes;
50   -
51   - spi_message_init(&adis->msg);
52   - spi_message_add_tail(&adis->xfer[0], &adis->msg);
53   - spi_message_add_tail(&adis->xfer[1], &adis->msg);
54   -
55   - return 0;
56   -}
57   -
58   -irqreturn_t adis16400_trigger_handler(int irq, void *p)
59   -{
60   - struct iio_poll_func *pf = p;
61   - struct iio_dev *indio_dev = pf->indio_dev;
62   - struct adis16400_state *st = iio_priv(indio_dev);
63   - struct adis *adis = &st->adis;
64   - u32 old_speed_hz = st->adis.spi->max_speed_hz;
65   - int ret;
66   -
67   - if (!adis->buffer)
68   - return -ENOMEM;
69   -
70   - if (!(st->variant->flags & ADIS16400_NO_BURST) &&
71   - st->adis.spi->max_speed_hz > ADIS16400_SPI_BURST) {
72   - st->adis.spi->max_speed_hz = ADIS16400_SPI_BURST;
73   - spi_setup(st->adis.spi);
74   - }
75   -
76   - ret = spi_sync(adis->spi, &adis->msg);
77   - if (ret)
78   - dev_err(&adis->spi->dev, "Failed to read data: %d\n", ret);
79   -
80   - if (!(st->variant->flags & ADIS16400_NO_BURST)) {
81   - st->adis.spi->max_speed_hz = old_speed_hz;
82   - spi_setup(st->adis.spi);
83   - }
84   -
85   - /* Guaranteed to be aligned with 8 byte boundary */
86   - if (indio_dev->scan_timestamp) {
87   - void *b = adis->buffer + indio_dev->scan_bytes - sizeof(s64);
88   - *(s64 *)b = pf->timestamp;
89   - }
90   -
91   - iio_push_to_buffers(indio_dev, adis->buffer);
92   -
93   - iio_trigger_notify_done(indio_dev->trig);
94   -
95   - return IRQ_HANDLED;
96   -}