2019-06-04 10:11:33 +02:00
// SPDX-License-Identifier: GPL-2.0-only
2010-05-04 14:43:15 +01:00
/*
* adis16400 . c support Analog Devices ADIS16400 / 5
* 3 d 2 g Linear Accelerometers ,
* 3 d Gyroscopes ,
* 3 d Magnetometers via SPI
*
* Copyright ( c ) 2009 Manuel Stahl < manuel . stahl @ iis . fraunhofer . de >
2012-09-02 21:34:59 +01:00
* Copyright ( c ) 2007 Jonathan Cameron < jic23 @ kernel . org >
2011-03-21 16:44:40 +01:00
* Copyright ( c ) 2011 Analog Devices Inc .
2010-05-04 14:43:15 +01:00
*/
# include <linux/interrupt.h>
# include <linux/irq.h>
# include <linux/delay.h>
# include <linux/mutex.h>
# include <linux/device.h>
# include <linux/kernel.h>
# include <linux/spi/spi.h>
2010-05-23 03:10:35 -04:00
# include <linux/slab.h>
2010-05-04 14:43:15 +01:00
# include <linux/sysfs.h>
# include <linux/list.h>
2011-07-03 15:49:50 -04:00
# include <linux/module.h>
2013-01-16 12:48:00 +00:00
# include <linux/debugfs.h>
2015-01-23 00:34:02 +01:00
# include <linux/bitops.h>
2010-05-04 14:43:15 +01:00
2012-04-25 15:54:58 +01:00
# include <linux/iio/iio.h>
# include <linux/iio/sysfs.h>
# include <linux/iio/buffer.h>
2019-03-22 22:44:38 +02:00
# include <linux/iio/trigger_consumer.h>
2019-03-22 22:44:42 +02:00
# include <linux/iio/imu/adis.h>
2013-01-16 12:48:00 +00:00
2019-03-22 22:44:42 +02:00
# define ADIS16400_STARTUP_DELAY 290 /* ms */
# define ADIS16400_MTEST_DELAY 90 /* ms */
# define ADIS16400_FLASH_CNT 0x00 /* Flash memory write count */
# define ADIS16400_SUPPLY_OUT 0x02 /* Power supply measurement */
# define ADIS16400_XGYRO_OUT 0x04 /* X-axis gyroscope output */
# define ADIS16400_YGYRO_OUT 0x06 /* Y-axis gyroscope output */
# define ADIS16400_ZGYRO_OUT 0x08 /* Z-axis gyroscope output */
# define ADIS16400_XACCL_OUT 0x0A /* X-axis accelerometer output */
# define ADIS16400_YACCL_OUT 0x0C /* Y-axis accelerometer output */
# define ADIS16400_ZACCL_OUT 0x0E /* Z-axis accelerometer output */
# define ADIS16400_XMAGN_OUT 0x10 /* X-axis magnetometer measurement */
# define ADIS16400_YMAGN_OUT 0x12 /* Y-axis magnetometer measurement */
# define ADIS16400_ZMAGN_OUT 0x14 /* Z-axis magnetometer measurement */
# define ADIS16400_TEMP_OUT 0x16 /* Temperature output */
# define ADIS16400_AUX_ADC 0x18 /* Auxiliary ADC measurement */
# define ADIS16350_XTEMP_OUT 0x10 /* X-axis gyroscope temperature measurement */
# define ADIS16350_YTEMP_OUT 0x12 /* Y-axis gyroscope temperature measurement */
# define ADIS16350_ZTEMP_OUT 0x14 /* Z-axis gyroscope temperature measurement */
# define ADIS16300_PITCH_OUT 0x12 /* X axis inclinometer output measurement */
# define ADIS16300_ROLL_OUT 0x14 /* Y axis inclinometer output measurement */
# define ADIS16300_AUX_ADC 0x16 /* Auxiliary ADC measurement */
# define ADIS16448_BARO_OUT 0x16 /* Barometric pressure output */
# define ADIS16448_TEMP_OUT 0x18 /* Temperature output */
/* Calibration parameters */
# define ADIS16400_XGYRO_OFF 0x1A /* X-axis gyroscope bias offset factor */
# define ADIS16400_YGYRO_OFF 0x1C /* Y-axis gyroscope bias offset factor */
# define ADIS16400_ZGYRO_OFF 0x1E /* Z-axis gyroscope bias offset factor */
# define ADIS16400_XACCL_OFF 0x20 /* X-axis acceleration bias offset factor */
# define ADIS16400_YACCL_OFF 0x22 /* Y-axis acceleration bias offset factor */
# define ADIS16400_ZACCL_OFF 0x24 /* Z-axis acceleration bias offset factor */
# define ADIS16400_XMAGN_HIF 0x26 /* X-axis magnetometer, hard-iron factor */
# define ADIS16400_YMAGN_HIF 0x28 /* Y-axis magnetometer, hard-iron factor */
# define ADIS16400_ZMAGN_HIF 0x2A /* Z-axis magnetometer, hard-iron factor */
# define ADIS16400_XMAGN_SIF 0x2C /* X-axis magnetometer, soft-iron factor */
# define ADIS16400_YMAGN_SIF 0x2E /* Y-axis magnetometer, soft-iron factor */
# define ADIS16400_ZMAGN_SIF 0x30 /* Z-axis magnetometer, soft-iron factor */
# define ADIS16400_GPIO_CTRL 0x32 /* Auxiliary digital input/output control */
# define ADIS16400_MSC_CTRL 0x34 /* Miscellaneous control */
# define ADIS16400_SMPL_PRD 0x36 /* Internal sample period (rate) control */
# define ADIS16400_SENS_AVG 0x38 /* Dynamic range and digital filter control */
# define ADIS16400_SLP_CNT 0x3A /* Sleep mode control */
# define ADIS16400_DIAG_STAT 0x3C /* System status */
/* Alarm functions */
# define ADIS16400_GLOB_CMD 0x3E /* System command */
# define ADIS16400_ALM_MAG1 0x40 /* Alarm 1 amplitude threshold */
# define ADIS16400_ALM_MAG2 0x42 /* Alarm 2 amplitude threshold */
# define ADIS16400_ALM_SMPL1 0x44 /* Alarm 1 sample size */
# define ADIS16400_ALM_SMPL2 0x46 /* Alarm 2 sample size */
# define ADIS16400_ALM_CTRL 0x48 /* Alarm control */
# define ADIS16400_AUX_DAC 0x4A /* Auxiliary DAC data */
# define ADIS16334_LOT_ID1 0x52 /* Lot identification code 1 */
# define ADIS16334_LOT_ID2 0x54 /* Lot identification code 2 */
# define ADIS16400_PRODUCT_ID 0x56 /* Product identifier */
# define ADIS16334_SERIAL_NUMBER 0x58 /* Serial number, lot specific */
# define ADIS16400_ERROR_ACTIVE (1<<14)
# define ADIS16400_NEW_DATA (1<<14)
/* MSC_CTRL */
# define ADIS16400_MSC_CTRL_MEM_TEST (1<<11)
# define ADIS16400_MSC_CTRL_INT_SELF_TEST (1<<10)
# define ADIS16400_MSC_CTRL_NEG_SELF_TEST (1<<9)
# define ADIS16400_MSC_CTRL_POS_SELF_TEST (1<<8)
# define ADIS16400_MSC_CTRL_GYRO_BIAS (1<<7)
# define ADIS16400_MSC_CTRL_ACCL_ALIGN (1<<6)
# define ADIS16400_MSC_CTRL_DATA_RDY_EN (1<<2)
# define ADIS16400_MSC_CTRL_DATA_RDY_POL_HIGH (1<<1)
# define ADIS16400_MSC_CTRL_DATA_RDY_DIO2 (1<<0)
/* SMPL_PRD */
# define ADIS16400_SMPL_PRD_TIME_BASE (1<<7)
# define ADIS16400_SMPL_PRD_DIV_MASK 0x7F
/* DIAG_STAT */
# define ADIS16400_DIAG_STAT_ZACCL_FAIL 15
# define ADIS16400_DIAG_STAT_YACCL_FAIL 14
# define ADIS16400_DIAG_STAT_XACCL_FAIL 13
# define ADIS16400_DIAG_STAT_XGYRO_FAIL 12
# define ADIS16400_DIAG_STAT_YGYRO_FAIL 11
# define ADIS16400_DIAG_STAT_ZGYRO_FAIL 10
# define ADIS16400_DIAG_STAT_ALARM2 9
# define ADIS16400_DIAG_STAT_ALARM1 8
# define ADIS16400_DIAG_STAT_FLASH_CHK 6
# define ADIS16400_DIAG_STAT_SELF_TEST 5
# define ADIS16400_DIAG_STAT_OVERFLOW 4
# define ADIS16400_DIAG_STAT_SPI_FAIL 3
# define ADIS16400_DIAG_STAT_FLASH_UPT 2
# define ADIS16400_DIAG_STAT_POWER_HIGH 1
# define ADIS16400_DIAG_STAT_POWER_LOW 0
/* GLOB_CMD */
# define ADIS16400_GLOB_CMD_SW_RESET (1<<7)
# define ADIS16400_GLOB_CMD_P_AUTO_NULL (1<<4)
# define ADIS16400_GLOB_CMD_FLASH_UPD (1<<3)
# define ADIS16400_GLOB_CMD_DAC_LATCH (1<<2)
# define ADIS16400_GLOB_CMD_FAC_CALIB (1<<1)
# define ADIS16400_GLOB_CMD_AUTO_NULL (1<<0)
/* SLP_CNT */
# define ADIS16400_SLP_CNT_POWER_OFF (1<<8)
# define ADIS16334_RATE_DIV_SHIFT 8
# define ADIS16334_RATE_INT_CLK BIT(0)
# define ADIS16400_SPI_SLOW (u32)(300 * 1000)
# define ADIS16400_SPI_BURST (u32)(1000 * 1000)
# define ADIS16400_SPI_FAST (u32)(2000 * 1000)
# define ADIS16400_HAS_PROD_ID BIT(0)
# define ADIS16400_NO_BURST BIT(1)
# define ADIS16400_HAS_SLOW_MODE BIT(2)
# define ADIS16400_HAS_SERIAL_NUMBER BIT(3)
# define ADIS16400_BURST_DIAG_STAT BIT(4)
struct adis16400_state ;
struct adis16400_chip_info {
const struct iio_chan_spec * channels ;
const int num_channels ;
const long flags ;
unsigned int gyro_scale_micro ;
unsigned int accel_scale_micro ;
int temp_scale_nano ;
int temp_offset ;
2019-11-22 15:24:18 +02:00
/* set_freq() & get_freq() need to avoid using ADIS lib's state lock */
2019-03-22 22:44:42 +02:00
int ( * set_freq ) ( struct adis16400_state * st , unsigned int freq ) ;
int ( * get_freq ) ( struct adis16400_state * st ) ;
} ;
/**
* struct adis16400_state - device instance specific data
* @ variant : chip variant info
* @ filt_int : integer part of requested filter frequency
* @ adis : adis device
* */
struct adis16400_state {
struct adis16400_chip_info * variant ;
int filt_int ;
struct adis adis ;
unsigned long avail_scan_mask [ 2 ] ;
} ;
/* At the moment triggers are only used for ring buffer
* filling . This may change !
*/
enum {
ADIS16400_SCAN_SUPPLY ,
ADIS16400_SCAN_GYRO_X ,
ADIS16400_SCAN_GYRO_Y ,
ADIS16400_SCAN_GYRO_Z ,
ADIS16400_SCAN_ACC_X ,
ADIS16400_SCAN_ACC_Y ,
ADIS16400_SCAN_ACC_Z ,
ADIS16400_SCAN_MAGN_X ,
ADIS16400_SCAN_MAGN_Y ,
ADIS16400_SCAN_MAGN_Z ,
ADIS16400_SCAN_BARO ,
ADIS16350_SCAN_TEMP_X ,
ADIS16350_SCAN_TEMP_Y ,
ADIS16350_SCAN_TEMP_Z ,
ADIS16300_SCAN_INCLI_X ,
ADIS16300_SCAN_INCLI_Y ,
ADIS16400_SCAN_ADC ,
ADIS16400_SCAN_TIMESTAMP ,
} ;
2010-05-04 14:43:15 +01:00
2013-01-16 12:48:00 +00:00
# ifdef CONFIG_DEBUG_FS
static ssize_t adis16400_show_serial_number ( struct file * file ,
char __user * userbuf , size_t count , loff_t * ppos )
{
struct adis16400_state * st = file - > private_data ;
u16 lot1 , lot2 , serial_number ;
char buf [ 16 ] ;
size_t len ;
int ret ;
ret = adis_read_reg_16 ( & st - > adis , ADIS16334_LOT_ID1 , & lot1 ) ;
2019-11-01 11:34:57 +02:00
if ( ret )
2013-01-16 12:48:00 +00:00
return ret ;
ret = adis_read_reg_16 ( & st - > adis , ADIS16334_LOT_ID2 , & lot2 ) ;
2019-11-01 11:34:57 +02:00
if ( ret )
2013-01-16 12:48:00 +00:00
return ret ;
ret = adis_read_reg_16 ( & st - > adis , ADIS16334_SERIAL_NUMBER ,
& serial_number ) ;
2019-11-01 11:34:57 +02:00
if ( ret )
2013-01-16 12:48:00 +00:00
return ret ;
len = snprintf ( buf , sizeof ( buf ) , " %.4x-%.4x-%.4x \n " , lot1 , lot2 ,
serial_number ) ;
return simple_read_from_buffer ( userbuf , count , ppos , buf , len ) ;
}
static const struct file_operations adis16400_serial_number_fops = {
. open = simple_open ,
. read = adis16400_show_serial_number ,
. llseek = default_llseek ,
. owner = THIS_MODULE ,
} ;
static int adis16400_show_product_id ( void * arg , u64 * val )
{
struct adis16400_state * st = arg ;
uint16_t prod_id ;
int ret ;
ret = adis_read_reg_16 ( & st - > adis , ADIS16400_PRODUCT_ID , & prod_id ) ;
2019-11-01 11:34:57 +02:00
if ( ret )
2013-01-16 12:48:00 +00:00
return ret ;
* val = prod_id ;
return 0 ;
}
DEFINE_SIMPLE_ATTRIBUTE ( adis16400_product_id_fops ,
adis16400_show_product_id , NULL , " %lld \n " ) ;
static int adis16400_show_flash_count ( void * arg , u64 * val )
{
struct adis16400_state * st = arg ;
uint16_t flash_count ;
int ret ;
ret = adis_read_reg_16 ( & st - > adis , ADIS16400_FLASH_CNT , & flash_count ) ;
2019-11-01 11:34:57 +02:00
if ( ret )
2013-01-16 12:48:00 +00:00
return ret ;
* val = flash_count ;
return 0 ;
}
DEFINE_SIMPLE_ATTRIBUTE ( adis16400_flash_count_fops ,
adis16400_show_flash_count , NULL , " %lld \n " ) ;
static int adis16400_debugfs_init ( struct iio_dev * indio_dev )
{
struct adis16400_state * st = iio_priv ( indio_dev ) ;
if ( st - > variant - > flags & ADIS16400_HAS_SERIAL_NUMBER )
debugfs_create_file ( " serial_number " , 0400 ,
indio_dev - > debugfs_dentry , st ,
& adis16400_serial_number_fops ) ;
if ( st - > variant - > flags & ADIS16400_HAS_PROD_ID )
debugfs_create_file ( " product_id " , 0400 ,
indio_dev - > debugfs_dentry , st ,
& adis16400_product_id_fops ) ;
debugfs_create_file ( " flash_count " , 0400 , indio_dev - > debugfs_dentry ,
st , & adis16400_flash_count_fops ) ;
return 0 ;
}
# else
static int adis16400_debugfs_init ( struct iio_dev * indio_dev )
{
return 0 ;
}
# endif
2011-05-18 14:41:28 +01:00
enum adis16400_chip_variant {
2011-05-18 14:41:30 +01:00
ADIS16300 ,
2011-09-30 10:05:45 +01:00
ADIS16334 ,
2011-05-18 14:41:28 +01:00
ADIS16350 ,
ADIS16360 ,
ADIS16362 ,
ADIS16364 ,
2015-08-05 15:38:19 +02:00
ADIS16367 ,
2011-05-18 14:41:28 +01:00
ADIS16400 ,
2015-08-05 15:38:20 +02:00
ADIS16445 ,
2013-01-16 12:48:00 +00:00
ADIS16448 ,
2011-05-18 14:41:28 +01:00
} ;
2019-03-22 22:44:39 +02:00
static struct adis_burst adis16400_burst = {
. en = true ,
. reg_cmd = ADIS16400_GLOB_CMD ,
} ;
2013-01-16 12:48:00 +00:00
static int adis16334_get_freq ( struct adis16400_state * st )
2011-11-27 11:39:13 +00:00
{
2012-10-30 10:26:00 +00:00
int ret ;
2013-01-16 12:48:00 +00:00
uint16_t t ;
2012-10-30 10:26:00 +00:00
2019-11-22 15:24:18 +02:00
ret = __adis_read_reg_16 ( & st - > adis , ADIS16400_SMPL_PRD , & t ) ;
2019-11-01 11:34:57 +02:00
if ( ret )
2012-10-30 10:26:00 +00:00
return ret ;
t > > = ADIS16334_RATE_DIV_SHIFT ;
2013-01-16 12:48:00 +00:00
return 819200 > > t ;
2012-10-30 10:26:00 +00:00
}
2013-01-16 12:48:00 +00:00
static int adis16334_set_freq ( struct adis16400_state * st , unsigned int freq )
2012-10-30 10:26:00 +00:00
{
unsigned int t ;
2013-01-16 12:48:00 +00:00
if ( freq < 819200 )
t = ilog2 ( 819200 / freq ) ;
2013-01-16 12:48:00 +00:00
else
t = 0 ;
2012-10-30 10:26:00 +00:00
if ( t > 0x31 )
t = 0x31 ;
t < < = ADIS16334_RATE_DIV_SHIFT ;
t | = ADIS16334_RATE_INT_CLK ;
2019-11-22 15:24:18 +02:00
return __adis_write_reg_16 ( & st - > adis , ADIS16400_SMPL_PRD , t ) ;
2012-10-30 10:26:00 +00:00
}
2013-01-16 12:48:00 +00:00
static int adis16400_get_freq ( struct adis16400_state * st )
2012-10-30 10:26:00 +00:00
{
2011-11-27 11:39:13 +00:00
int sps , ret ;
2013-01-16 12:48:00 +00:00
uint16_t t ;
2011-11-27 11:39:13 +00:00
2019-11-22 15:24:18 +02:00
ret = __adis_read_reg_16 ( & st - > adis , ADIS16400_SMPL_PRD , & t ) ;
2019-11-01 11:34:57 +02:00
if ( ret )
2011-11-27 11:39:13 +00:00
return ret ;
2013-01-16 12:48:00 +00:00
2013-01-16 12:48:00 +00:00
sps = ( t & ADIS16400_SMPL_PRD_TIME_BASE ) ? 52851 : 1638404 ;
2011-11-27 11:39:13 +00:00
sps / = ( t & ADIS16400_SMPL_PRD_DIV_MASK ) + 1 ;
return sps ;
}
2013-01-16 12:48:00 +00:00
static int adis16400_set_freq ( struct adis16400_state * st , unsigned int freq )
2012-10-30 10:26:00 +00:00
{
unsigned int t ;
2013-01-16 12:48:00 +00:00
uint8_t val = 0 ;
2012-10-30 10:26:00 +00:00
2013-01-16 12:48:00 +00:00
t = 1638404 / freq ;
2013-01-16 12:48:00 +00:00
if ( t > = 128 ) {
val | = ADIS16400_SMPL_PRD_TIME_BASE ;
t = 52851 / freq ;
if ( t > = 128 )
t = 127 ;
} else if ( t ! = 0 ) {
2012-10-30 10:26:00 +00:00
t - - ;
2013-01-16 12:48:00 +00:00
}
2013-01-16 12:48:00 +00:00
2013-01-16 12:48:00 +00:00
val | = t ;
if ( t > = 0x0A | | ( val & ADIS16400_SMPL_PRD_TIME_BASE ) )
2013-01-16 12:48:00 +00:00
st - > adis . spi - > max_speed_hz = ADIS16400_SPI_SLOW ;
2012-10-30 10:26:00 +00:00
else
2013-01-16 12:48:00 +00:00
st - > adis . spi - > max_speed_hz = ADIS16400_SPI_FAST ;
2012-10-30 10:26:00 +00:00
2019-11-22 15:24:18 +02:00
return __adis_write_reg_8 ( & st - > adis , ADIS16400_SMPL_PRD , val ) ;
2012-10-30 10:26:00 +00:00
}
2017-07-01 17:54:08 -04:00
static const unsigned int adis16400_3db_divisors [ ] = {
2011-11-27 11:39:13 +00:00
[ 0 ] = 2 , /* Special case */
2013-01-16 12:48:00 +00:00
[ 1 ] = 6 ,
[ 2 ] = 12 ,
[ 3 ] = 25 ,
[ 4 ] = 50 ,
[ 5 ] = 100 ,
[ 6 ] = 200 ,
[ 7 ] = 200 , /* Not a valid setting */
2011-11-27 11:39:13 +00:00
} ;
2019-11-22 15:24:18 +02:00
static int __adis16400_set_filter ( struct iio_dev * indio_dev , int sps , int val )
2011-11-27 11:39:13 +00:00
{
2013-01-16 12:48:00 +00:00
struct adis16400_state * st = iio_priv ( indio_dev ) ;
2013-01-16 12:48:00 +00:00
uint16_t val16 ;
2011-11-27 11:39:13 +00:00
int i , ret ;
2013-01-16 12:48:00 +00:00
for ( i = ARRAY_SIZE ( adis16400_3db_divisors ) - 1 ; i > = 1 ; i - - ) {
if ( sps / adis16400_3db_divisors [ i ] > = val )
2011-11-27 11:39:13 +00:00
break ;
2013-01-16 12:48:00 +00:00
}
2019-11-22 15:24:18 +02:00
ret = __adis_read_reg_16 ( & st - > adis , ADIS16400_SENS_AVG , & val16 ) ;
2019-11-01 11:34:57 +02:00
if ( ret )
2013-01-16 12:48:00 +00:00
return ret ;
2011-11-27 11:39:13 +00:00
2019-11-22 15:24:18 +02:00
ret = __adis_write_reg_16 ( & st - > adis , ADIS16400_SENS_AVG ,
2013-01-16 12:48:00 +00:00
( val16 & ~ 0x07 ) | i ) ;
2011-11-27 11:39:13 +00:00
return ret ;
}
2010-05-04 14:43:15 +01:00
/* Power down the device */
2011-05-18 14:41:27 +01:00
static int adis16400_stop_device ( struct iio_dev * indio_dev )
2010-05-04 14:43:15 +01:00
{
2013-01-16 12:48:00 +00:00
struct adis16400_state * st = iio_priv ( indio_dev ) ;
2010-05-04 14:43:15 +01:00
int ret ;
2013-01-16 12:48:00 +00:00
ret = adis_write_reg_16 ( & st - > adis , ADIS16400_SLP_CNT ,
ADIS16400_SLP_CNT_POWER_OFF ) ;
2010-05-04 14:43:15 +01:00
if ( ret )
2011-05-18 14:41:27 +01:00
dev_err ( & indio_dev - > dev ,
" problem with turning device off: SLP_CNT " ) ;
2010-05-04 14:43:15 +01:00
return ret ;
}
2011-05-18 14:42:23 +01:00
static int adis16400_initial_setup ( struct iio_dev * indio_dev )
2010-05-04 14:43:15 +01:00
{
2011-05-18 14:42:23 +01:00
struct adis16400_state * st = iio_priv ( indio_dev ) ;
2013-01-16 12:48:00 +00:00
uint16_t prod_id , smp_prd ;
unsigned int device_id ;
int ret ;
2010-05-04 14:43:15 +01:00
2012-10-30 10:26:00 +00:00
/* use low spi speed for init if the device has a slow mode */
if ( st - > variant - > flags & ADIS16400_HAS_SLOW_MODE )
2013-01-16 12:48:00 +00:00
st - > adis . spi - > max_speed_hz = ADIS16400_SPI_SLOW ;
2012-10-30 10:26:00 +00:00
else
2013-01-16 12:48:00 +00:00
st - > adis . spi - > max_speed_hz = ADIS16400_SPI_FAST ;
st - > adis . spi - > mode = SPI_MODE_3 ;
spi_setup ( st - > adis . spi ) ;
2010-05-04 14:43:15 +01:00
2013-01-16 12:48:00 +00:00
ret = adis_initial_startup ( & st - > adis ) ;
if ( ret )
return ret ;
2010-05-04 14:43:15 +01:00
2011-05-18 14:41:28 +01:00
if ( st - > variant - > flags & ADIS16400_HAS_PROD_ID ) {
2013-01-16 12:48:00 +00:00
ret = adis_read_reg_16 ( & st - > adis ,
2011-05-18 14:41:28 +01:00
ADIS16400_PRODUCT_ID , & prod_id ) ;
if ( ret )
goto err_ret ;
2010-05-04 14:43:15 +01:00
2015-11-01 14:58:45 +02:00
ret = sscanf ( indio_dev - > name , " adis%u \n " , & device_id ) ;
if ( ret ! = 1 ) {
ret = - EINVAL ;
goto err_ret ;
}
2012-10-30 10:26:00 +00:00
if ( prod_id ! = device_id )
dev_warn ( & indio_dev - > dev , " Device ID(%u) and product ID(%u) do not match. " ,
device_id , prod_id ) ;
2010-05-04 14:43:15 +01:00
2011-09-02 17:25:34 +01:00
dev_info ( & indio_dev - > dev , " %s: prod_id 0x%04x at CS%d (irq %d) \n " ,
2013-01-16 12:48:00 +00:00
indio_dev - > name , prod_id ,
st - > adis . spi - > chip_select , st - > adis . spi - > irq ) ;
2011-05-18 14:41:28 +01:00
}
2010-05-04 14:43:15 +01:00
/* use high spi speed if possible */
2012-10-30 10:26:00 +00:00
if ( st - > variant - > flags & ADIS16400_HAS_SLOW_MODE ) {
2013-01-16 12:48:00 +00:00
ret = adis_read_reg_16 ( & st - > adis , ADIS16400_SMPL_PRD , & smp_prd ) ;
2012-10-30 10:26:00 +00:00
if ( ret )
goto err_ret ;
if ( ( smp_prd & ADIS16400_SMPL_PRD_DIV_MASK ) < 0x0A ) {
2013-01-16 12:48:00 +00:00
st - > adis . spi - > max_speed_hz = ADIS16400_SPI_FAST ;
spi_setup ( st - > adis . spi ) ;
2012-10-30 10:26:00 +00:00
}
2010-05-04 14:43:15 +01:00
}
err_ret :
return ret ;
}
2013-01-16 12:48:00 +00:00
static const uint8_t adis16400_addresses [ ] = {
2013-01-16 12:48:00 +00:00
[ ADIS16400_SCAN_GYRO_X ] = ADIS16400_XGYRO_OFF ,
[ ADIS16400_SCAN_GYRO_Y ] = ADIS16400_YGYRO_OFF ,
[ ADIS16400_SCAN_GYRO_Z ] = ADIS16400_ZGYRO_OFF ,
[ ADIS16400_SCAN_ACC_X ] = ADIS16400_XACCL_OFF ,
[ ADIS16400_SCAN_ACC_Y ] = ADIS16400_YACCL_OFF ,
[ ADIS16400_SCAN_ACC_Z ] = ADIS16400_ZACCL_OFF ,
2011-05-18 14:41:27 +01:00
} ;
static int adis16400_write_raw ( struct iio_dev * indio_dev ,
2013-01-16 12:48:00 +00:00
struct iio_chan_spec const * chan , int val , int val2 , long info )
2011-05-18 14:41:27 +01:00
{
2011-11-27 11:39:13 +00:00
struct adis16400_state * st = iio_priv ( indio_dev ) ;
2019-11-22 15:24:18 +02:00
struct mutex * slock = & st - > adis . state_lock ;
2011-11-27 11:39:13 +00:00
int ret , sps ;
2011-09-02 17:25:33 +01:00
2013-01-16 12:48:00 +00:00
switch ( info ) {
2011-10-26 17:41:36 +01:00
case IIO_CHAN_INFO_CALIBBIAS :
2013-01-16 12:48:00 +00:00
ret = adis_write_reg_16 ( & st - > adis ,
adis16400_addresses [ chan - > scan_index ] , val ) ;
2011-05-18 14:41:27 +01:00
return ret ;
2011-11-27 11:39:13 +00:00
case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY :
2013-01-16 12:48:00 +00:00
/*
* Need to cache values so we can update if the frequency
* changes .
*/
2019-11-22 15:24:18 +02:00
mutex_lock ( slock ) ;
2011-11-27 11:39:13 +00:00
st - > filt_int = val ;
/* Work out update to current value */
2013-01-16 12:48:00 +00:00
sps = st - > variant - > get_freq ( st ) ;
2011-11-27 11:39:13 +00:00
if ( sps < 0 ) {
2019-11-22 15:24:18 +02:00
mutex_unlock ( slock ) ;
2011-11-27 11:39:13 +00:00
return sps ;
}
2019-11-22 15:24:18 +02:00
ret = __adis16400_set_filter ( indio_dev , sps ,
2013-01-16 12:48:00 +00:00
val * 1000 + val2 / 1000 ) ;
2019-11-22 15:24:18 +02:00
mutex_unlock ( slock ) ;
2011-11-27 11:39:13 +00:00
return ret ;
2014-06-22 20:59:00 +01:00
case IIO_CHAN_INFO_SAMP_FREQ :
sps = val * 1000 + val2 / 1000 ;
if ( sps < = 0 )
return - EINVAL ;
2019-11-22 15:24:18 +02:00
mutex_lock ( slock ) ;
2014-06-22 20:59:00 +01:00
ret = st - > variant - > set_freq ( st , sps ) ;
2019-11-22 15:24:18 +02:00
mutex_unlock ( slock ) ;
2014-06-22 20:59:00 +01:00
return ret ;
2011-05-18 14:41:27 +01:00
default :
return - EINVAL ;
}
}
static int adis16400_read_raw ( struct iio_dev * indio_dev ,
2013-01-16 12:48:00 +00:00
struct iio_chan_spec const * chan , int * val , int * val2 , long info )
2011-05-18 14:41:27 +01:00
{
2011-05-18 14:42:23 +01:00
struct adis16400_state * st = iio_priv ( indio_dev ) ;
2019-11-22 15:24:18 +02:00
struct mutex * slock = & st - > adis . state_lock ;
2013-01-16 12:48:00 +00:00
int16_t val16 ;
2013-01-16 12:48:00 +00:00
int ret ;
2011-05-18 14:41:27 +01:00
2013-01-16 12:48:00 +00:00
switch ( info ) {
2012-04-15 17:41:21 +01:00
case IIO_CHAN_INFO_RAW :
2013-01-16 12:48:00 +00:00
return adis_single_conversion ( indio_dev , chan , 0 , val ) ;
2011-10-26 17:41:36 +01:00
case IIO_CHAN_INFO_SCALE :
2011-05-18 14:41:27 +01:00
switch ( chan - > type ) {
2011-10-05 15:27:59 +01:00
case IIO_ANGL_VEL :
2011-05-18 14:41:27 +01:00
* val = 0 ;
2011-05-18 14:41:28 +01:00
* val2 = st - > variant - > gyro_scale_micro ;
2011-05-18 14:41:27 +01:00
return IIO_VAL_INT_PLUS_MICRO ;
2011-09-27 09:56:41 +01:00
case IIO_VOLTAGE :
2011-05-18 14:41:27 +01:00
* val = 0 ;
2012-10-15 10:35:00 +01:00
if ( chan - > channel = = 0 ) {
* val = 2 ;
* val2 = 418000 ; /* 2.418 mV */
} else {
* val = 0 ;
* val2 = 805800 ; /* 805.8 uV */
}
2011-05-18 14:41:27 +01:00
return IIO_VAL_INT_PLUS_MICRO ;
case IIO_ACCEL :
* val = 0 ;
2011-05-18 14:41:28 +01:00
* val2 = st - > variant - > accel_scale_micro ;
2011-05-18 14:41:27 +01:00
return IIO_VAL_INT_PLUS_MICRO ;
case IIO_MAGN :
* val = 0 ;
2012-10-15 10:35:00 +01:00
* val2 = 500 ; /* 0.5 mgauss */
2011-05-18 14:41:27 +01:00
return IIO_VAL_INT_PLUS_MICRO ;
case IIO_TEMP :
2012-10-15 10:35:00 +01:00
* val = st - > variant - > temp_scale_nano / 1000000 ;
* val2 = ( st - > variant - > temp_scale_nano % 1000000 ) ;
2011-05-18 14:41:27 +01:00
return IIO_VAL_INT_PLUS_MICRO ;
2015-05-15 17:18:34 +02:00
case IIO_PRESSURE :
/* 20 uBar = 0.002kPascal */
* val = 0 ;
* val2 = 2000 ;
return IIO_VAL_INT_PLUS_MICRO ;
2011-05-18 14:41:27 +01:00
default :
return - EINVAL ;
}
2011-10-26 17:41:36 +01:00
case IIO_CHAN_INFO_CALIBBIAS :
2013-01-16 12:48:00 +00:00
ret = adis_read_reg_16 ( & st - > adis ,
adis16400_addresses [ chan - > scan_index ] , & val16 ) ;
2011-05-18 14:41:28 +01:00
if ( ret )
2011-05-18 14:41:27 +01:00
return ret ;
2015-01-23 00:34:02 +01:00
val16 = sign_extend32 ( val16 , 11 ) ;
2011-05-18 14:41:27 +01:00
* val = val16 ;
return IIO_VAL_INT ;
2011-10-26 17:41:36 +01:00
case IIO_CHAN_INFO_OFFSET :
2011-05-18 14:41:27 +01:00
/* currently only temperature */
2012-10-15 10:35:00 +01:00
* val = st - > variant - > temp_offset ;
2012-10-15 10:35:00 +01:00
return IIO_VAL_INT ;
2011-11-27 11:39:13 +00:00
case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY :
2019-11-22 15:24:18 +02:00
mutex_lock ( slock ) ;
2011-11-27 11:39:13 +00:00
/* Need both the number of taps and the sampling frequency */
2019-11-22 15:24:18 +02:00
ret = __adis_read_reg_16 ( & st - > adis ,
2011-11-27 11:39:13 +00:00
ADIS16400_SENS_AVG ,
& val16 ) ;
2019-11-01 11:34:57 +02:00
if ( ret ) {
2019-11-22 15:24:18 +02:00
mutex_unlock ( slock ) ;
2011-11-27 11:39:13 +00:00
return ret ;
}
2013-01-16 12:48:00 +00:00
ret = st - > variant - > get_freq ( st ) ;
2019-11-22 15:24:18 +02:00
mutex_unlock ( slock ) ;
2019-11-01 11:34:57 +02:00
if ( ret )
2011-11-27 11:39:13 +00:00
return ret ;
2019-11-22 15:24:18 +02:00
ret / = adis16400_3db_divisors [ val16 & 0x07 ] ;
* val = ret / 1000 ;
* val2 = ( ret % 1000 ) * 1000 ;
2011-11-27 11:39:13 +00:00
return IIO_VAL_INT_PLUS_MICRO ;
2014-06-22 20:59:00 +01:00
case IIO_CHAN_INFO_SAMP_FREQ :
2019-11-22 15:24:18 +02:00
mutex_lock ( slock ) ;
2014-06-22 20:59:00 +01:00
ret = st - > variant - > get_freq ( st ) ;
2019-11-22 15:24:18 +02:00
mutex_unlock ( slock ) ;
2019-11-01 11:34:57 +02:00
if ( ret )
2014-06-22 20:59:00 +01:00
return ret ;
* val = ret / 1000 ;
* val2 = ( ret % 1000 ) * 1000 ;
return IIO_VAL_INT_PLUS_MICRO ;
2011-05-18 14:41:27 +01:00
default :
return - EINVAL ;
}
}
2019-03-22 22:44:38 +02:00
# if IS_ENABLED(CONFIG_IIO_BUFFER)
static irqreturn_t adis16400_trigger_handler ( int irq , void * p )
{
struct iio_poll_func * pf = p ;
struct iio_dev * indio_dev = pf - > indio_dev ;
struct adis16400_state * st = iio_priv ( indio_dev ) ;
struct adis * adis = & st - > adis ;
u32 old_speed_hz = st - > adis . spi - > max_speed_hz ;
void * buffer ;
int ret ;
if ( ! adis - > buffer )
return - ENOMEM ;
if ( ! ( st - > variant - > flags & ADIS16400_NO_BURST ) & &
st - > adis . spi - > max_speed_hz > ADIS16400_SPI_BURST ) {
st - > adis . spi - > max_speed_hz = ADIS16400_SPI_BURST ;
spi_setup ( st - > adis . spi ) ;
}
ret = spi_sync ( adis - > spi , & adis - > msg ) ;
if ( ret )
dev_err ( & adis - > spi - > dev , " Failed to read data: %d \n " , ret ) ;
if ( ! ( st - > variant - > flags & ADIS16400_NO_BURST ) ) {
st - > adis . spi - > max_speed_hz = old_speed_hz ;
spi_setup ( st - > adis . spi ) ;
}
if ( st - > variant - > flags & ADIS16400_BURST_DIAG_STAT )
buffer = adis - > buffer + sizeof ( u16 ) ;
else
buffer = adis - > buffer ;
iio_push_to_buffers_with_timestamp ( indio_dev , buffer ,
pf - > timestamp ) ;
iio_trigger_notify_done ( indio_dev - > trig ) ;
return IRQ_HANDLED ;
}
# else
# define adis16400_trigger_handler NULL
# endif /* IS_ENABLED(CONFIG_IIO_BUFFER) */
2015-05-15 17:18:35 +02:00
# define ADIS16400_VOLTAGE_CHAN(addr, bits, name, si, chn) { \
2013-01-16 12:48:00 +00:00
. type = IIO_VOLTAGE , \
. indexed = 1 , \
2015-05-15 17:18:35 +02:00
. channel = chn , \
2013-01-16 12:48:00 +00:00
. extend_name = name , \
2013-02-27 19:31:17 +00:00
. info_mask_separate = BIT ( IIO_CHAN_INFO_RAW ) | \
BIT ( IIO_CHAN_INFO_SCALE ) , \
2014-06-22 20:59:00 +01:00
. info_mask_shared_by_all = BIT ( IIO_CHAN_INFO_SAMP_FREQ ) , \
2013-01-16 12:48:00 +00:00
. address = ( addr ) , \
. scan_index = ( si ) , \
2013-01-16 12:48:00 +00:00
. scan_type = { \
. sign = ' u ' , \
. realbits = ( bits ) , \
. storagebits = 16 , \
. shift = 0 , \
. endianness = IIO_BE , \
} , \
2013-01-16 12:48:00 +00:00
}
# define ADIS16400_SUPPLY_CHAN(addr, bits) \
2015-05-15 17:18:35 +02:00
ADIS16400_VOLTAGE_CHAN ( addr , bits , " supply " , ADIS16400_SCAN_SUPPLY , 0 )
2013-01-16 12:48:00 +00:00
# define ADIS16400_AUX_ADC_CHAN(addr, bits) \
2015-05-15 17:18:35 +02:00
ADIS16400_VOLTAGE_CHAN ( addr , bits , NULL , ADIS16400_SCAN_ADC , 1 )
2013-01-16 12:48:00 +00:00
# define ADIS16400_GYRO_CHAN(mod, addr, bits) { \
. type = IIO_ANGL_VEL , \
. modified = 1 , \
. channel2 = IIO_MOD_ # # mod , \
2013-02-27 19:31:17 +00:00
. info_mask_separate = BIT ( IIO_CHAN_INFO_RAW ) | \
BIT ( IIO_CHAN_INFO_CALIBBIAS ) , \
. info_mask_shared_by_type = BIT ( IIO_CHAN_INFO_SCALE ) | \
BIT ( IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY ) , \
2014-06-22 20:59:00 +01:00
. info_mask_shared_by_all = BIT ( IIO_CHAN_INFO_SAMP_FREQ ) , \
2013-01-16 12:48:00 +00:00
. address = addr , \
. scan_index = ADIS16400_SCAN_GYRO_ # # mod , \
2013-01-16 12:48:00 +00:00
. scan_type = { \
. sign = ' s ' , \
. realbits = ( bits ) , \
. storagebits = 16 , \
. shift = 0 , \
. endianness = IIO_BE , \
} , \
2013-01-16 12:48:00 +00:00
}
# define ADIS16400_ACCEL_CHAN(mod, addr, bits) { \
. type = IIO_ACCEL , \
. modified = 1 , \
. channel2 = IIO_MOD_ # # mod , \
2013-02-27 19:31:17 +00:00
. info_mask_separate = BIT ( IIO_CHAN_INFO_RAW ) | \
BIT ( IIO_CHAN_INFO_CALIBBIAS ) , \
. info_mask_shared_by_type = BIT ( IIO_CHAN_INFO_SCALE ) | \
BIT ( IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY ) , \
2014-06-22 20:59:00 +01:00
. info_mask_shared_by_all = BIT ( IIO_CHAN_INFO_SAMP_FREQ ) , \
2013-01-16 12:48:00 +00:00
. address = ( addr ) , \
. scan_index = ADIS16400_SCAN_ACC_ # # mod , \
2013-01-16 12:48:00 +00:00
. scan_type = { \
. sign = ' s ' , \
. realbits = ( bits ) , \
. storagebits = 16 , \
. shift = 0 , \
. endianness = IIO_BE , \
} , \
2013-01-16 12:48:00 +00:00
}
# define ADIS16400_MAGN_CHAN(mod, addr, bits) { \
. type = IIO_MAGN , \
. modified = 1 , \
. channel2 = IIO_MOD_ # # mod , \
2013-02-27 19:31:17 +00:00
. info_mask_separate = BIT ( IIO_CHAN_INFO_RAW ) , \
. info_mask_shared_by_type = BIT ( IIO_CHAN_INFO_SCALE ) | \
BIT ( IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY ) , \
2014-06-22 20:59:00 +01:00
. info_mask_shared_by_all = BIT ( IIO_CHAN_INFO_SAMP_FREQ ) , \
2013-01-16 12:48:00 +00:00
. address = ( addr ) , \
. scan_index = ADIS16400_SCAN_MAGN_ # # mod , \
2013-01-16 12:48:00 +00:00
. scan_type = { \
. sign = ' s ' , \
. realbits = ( bits ) , \
. storagebits = 16 , \
. shift = 0 , \
. endianness = IIO_BE , \
} , \
2013-01-16 12:48:00 +00:00
}
# define ADIS16400_MOD_TEMP_NAME_X "x"
# define ADIS16400_MOD_TEMP_NAME_Y "y"
# define ADIS16400_MOD_TEMP_NAME_Z "z"
# define ADIS16400_MOD_TEMP_CHAN(mod, addr, bits) { \
. type = IIO_TEMP , \
. indexed = 1 , \
. channel = 0 , \
. extend_name = ADIS16400_MOD_TEMP_NAME_ # # mod , \
2013-02-27 19:31:17 +00:00
. info_mask_separate = BIT ( IIO_CHAN_INFO_RAW ) | \
BIT ( IIO_CHAN_INFO_OFFSET ) | \
BIT ( IIO_CHAN_INFO_SCALE ) , \
. info_mask_shared_by_type = \
BIT ( IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY ) , \
2014-06-22 20:59:00 +01:00
. info_mask_shared_by_all = BIT ( IIO_CHAN_INFO_SAMP_FREQ ) , \
2013-01-16 12:48:00 +00:00
. address = ( addr ) , \
. scan_index = ADIS16350_SCAN_TEMP_ # # mod , \
2013-01-16 12:48:00 +00:00
. scan_type = { \
. sign = ' s ' , \
. realbits = ( bits ) , \
. storagebits = 16 , \
. shift = 0 , \
. endianness = IIO_BE , \
} , \
2013-01-16 12:48:00 +00:00
}
# define ADIS16400_TEMP_CHAN(addr, bits) { \
. type = IIO_TEMP , \
. indexed = 1 , \
. channel = 0 , \
2013-02-27 19:31:17 +00:00
. info_mask_separate = BIT ( IIO_CHAN_INFO_RAW ) | \
BIT ( IIO_CHAN_INFO_OFFSET ) | \
BIT ( IIO_CHAN_INFO_SCALE ) , \
2014-06-22 20:59:00 +01:00
. info_mask_shared_by_all = BIT ( IIO_CHAN_INFO_SAMP_FREQ ) , \
2013-01-16 12:48:00 +00:00
. address = ( addr ) , \
. scan_index = ADIS16350_SCAN_TEMP_X , \
2013-01-16 12:48:00 +00:00
. scan_type = { \
. sign = ' s ' , \
. realbits = ( bits ) , \
. storagebits = 16 , \
. shift = 0 , \
. endianness = IIO_BE , \
} , \
2013-01-16 12:48:00 +00:00
}
# define ADIS16400_INCLI_CHAN(mod, addr, bits) { \
. type = IIO_INCLI , \
. modified = 1 , \
. channel2 = IIO_MOD_ # # mod , \
2013-02-27 19:31:17 +00:00
. info_mask_separate = BIT ( IIO_CHAN_INFO_RAW ) , \
. info_mask_shared_by_type = BIT ( IIO_CHAN_INFO_SCALE ) , \
2014-06-22 20:59:00 +01:00
. info_mask_shared_by_all = BIT ( IIO_CHAN_INFO_SAMP_FREQ ) , \
2013-01-16 12:48:00 +00:00
. address = ( addr ) , \
. scan_index = ADIS16300_SCAN_INCLI_ # # mod , \
2013-01-16 12:48:00 +00:00
. scan_type = { \
. sign = ' s ' , \
. realbits = ( bits ) , \
. storagebits = 16 , \
. shift = 0 , \
. endianness = IIO_BE , \
} , \
2013-01-16 12:48:00 +00:00
}
2012-08-09 08:51:00 +01:00
static const struct iio_chan_spec adis16400_channels [ ] = {
2013-01-16 12:48:00 +00:00
ADIS16400_SUPPLY_CHAN ( ADIS16400_SUPPLY_OUT , 14 ) ,
ADIS16400_GYRO_CHAN ( X , ADIS16400_XGYRO_OUT , 14 ) ,
ADIS16400_GYRO_CHAN ( Y , ADIS16400_YGYRO_OUT , 14 ) ,
ADIS16400_GYRO_CHAN ( Z , ADIS16400_ZGYRO_OUT , 14 ) ,
ADIS16400_ACCEL_CHAN ( X , ADIS16400_XACCL_OUT , 14 ) ,
ADIS16400_ACCEL_CHAN ( Y , ADIS16400_YACCL_OUT , 14 ) ,
ADIS16400_ACCEL_CHAN ( Z , ADIS16400_ZACCL_OUT , 14 ) ,
ADIS16400_MAGN_CHAN ( X , ADIS16400_XMAGN_OUT , 14 ) ,
ADIS16400_MAGN_CHAN ( Y , ADIS16400_YMAGN_OUT , 14 ) ,
ADIS16400_MAGN_CHAN ( Z , ADIS16400_ZMAGN_OUT , 14 ) ,
ADIS16400_TEMP_CHAN ( ADIS16400_TEMP_OUT , 12 ) ,
ADIS16400_AUX_ADC_CHAN ( ADIS16400_AUX_ADC , 12 ) ,
2014-01-24 11:24:00 +00:00
IIO_CHAN_SOFT_TIMESTAMP ( ADIS16400_SCAN_TIMESTAMP ) ,
2011-05-18 14:41:27 +01:00
} ;
2015-08-05 15:38:20 +02:00
static const struct iio_chan_spec adis16445_channels [ ] = {
ADIS16400_GYRO_CHAN ( X , ADIS16400_XGYRO_OUT , 16 ) ,
ADIS16400_GYRO_CHAN ( Y , ADIS16400_YGYRO_OUT , 16 ) ,
ADIS16400_GYRO_CHAN ( Z , ADIS16400_ZGYRO_OUT , 16 ) ,
ADIS16400_ACCEL_CHAN ( X , ADIS16400_XACCL_OUT , 16 ) ,
ADIS16400_ACCEL_CHAN ( Y , ADIS16400_YACCL_OUT , 16 ) ,
ADIS16400_ACCEL_CHAN ( Z , ADIS16400_ZACCL_OUT , 16 ) ,
ADIS16400_TEMP_CHAN ( ADIS16448_TEMP_OUT , 12 ) ,
IIO_CHAN_SOFT_TIMESTAMP ( ADIS16400_SCAN_TIMESTAMP ) ,
} ;
2013-01-16 12:48:00 +00:00
static const struct iio_chan_spec adis16448_channels [ ] = {
ADIS16400_GYRO_CHAN ( X , ADIS16400_XGYRO_OUT , 16 ) ,
ADIS16400_GYRO_CHAN ( Y , ADIS16400_YGYRO_OUT , 16 ) ,
ADIS16400_GYRO_CHAN ( Z , ADIS16400_ZGYRO_OUT , 16 ) ,
ADIS16400_ACCEL_CHAN ( X , ADIS16400_XACCL_OUT , 16 ) ,
ADIS16400_ACCEL_CHAN ( Y , ADIS16400_YACCL_OUT , 16 ) ,
ADIS16400_ACCEL_CHAN ( Z , ADIS16400_ZACCL_OUT , 16 ) ,
ADIS16400_MAGN_CHAN ( X , ADIS16400_XMAGN_OUT , 16 ) ,
ADIS16400_MAGN_CHAN ( Y , ADIS16400_YMAGN_OUT , 16 ) ,
ADIS16400_MAGN_CHAN ( Z , ADIS16400_ZMAGN_OUT , 16 ) ,
{
. type = IIO_PRESSURE ,
2013-02-27 19:31:17 +00:00
. info_mask_separate = BIT ( IIO_CHAN_INFO_RAW ) ,
. info_mask_shared_by_type = BIT ( IIO_CHAN_INFO_SCALE ) ,
2014-06-22 20:59:00 +01:00
. info_mask_shared_by_all = BIT ( IIO_CHAN_INFO_SAMP_FREQ ) ,
2013-01-16 12:48:00 +00:00
. address = ADIS16448_BARO_OUT ,
. scan_index = ADIS16400_SCAN_BARO ,
2013-12-11 18:45:00 +00:00
. scan_type = {
. sign = ' s ' ,
. realbits = 16 ,
. storagebits = 16 ,
. endianness = IIO_BE ,
} ,
2013-01-16 12:48:00 +00:00
} ,
ADIS16400_TEMP_CHAN ( ADIS16448_TEMP_OUT , 12 ) ,
2014-01-24 11:24:00 +00:00
IIO_CHAN_SOFT_TIMESTAMP ( ADIS16400_SCAN_TIMESTAMP ) ,
2013-01-16 12:48:00 +00:00
} ;
2012-08-09 08:51:00 +01:00
static const struct iio_chan_spec adis16350_channels [ ] = {
2013-01-16 12:48:00 +00:00
ADIS16400_SUPPLY_CHAN ( ADIS16400_SUPPLY_OUT , 12 ) ,
ADIS16400_GYRO_CHAN ( X , ADIS16400_XGYRO_OUT , 14 ) ,
ADIS16400_GYRO_CHAN ( Y , ADIS16400_YGYRO_OUT , 14 ) ,
ADIS16400_GYRO_CHAN ( Z , ADIS16400_ZGYRO_OUT , 14 ) ,
ADIS16400_ACCEL_CHAN ( X , ADIS16400_XACCL_OUT , 14 ) ,
ADIS16400_ACCEL_CHAN ( Y , ADIS16400_YACCL_OUT , 14 ) ,
ADIS16400_ACCEL_CHAN ( Z , ADIS16400_ZACCL_OUT , 14 ) ,
ADIS16400_MAGN_CHAN ( X , ADIS16400_XMAGN_OUT , 14 ) ,
ADIS16400_MAGN_CHAN ( Y , ADIS16400_YMAGN_OUT , 14 ) ,
ADIS16400_MAGN_CHAN ( Z , ADIS16400_ZMAGN_OUT , 14 ) ,
ADIS16400_AUX_ADC_CHAN ( ADIS16300_AUX_ADC , 12 ) ,
ADIS16400_MOD_TEMP_CHAN ( X , ADIS16350_XTEMP_OUT , 12 ) ,
ADIS16400_MOD_TEMP_CHAN ( Y , ADIS16350_YTEMP_OUT , 12 ) ,
ADIS16400_MOD_TEMP_CHAN ( Z , ADIS16350_ZTEMP_OUT , 12 ) ,
2014-01-24 11:24:00 +00:00
IIO_CHAN_SOFT_TIMESTAMP ( ADIS16400_SCAN_TIMESTAMP ) ,
2011-05-18 14:41:28 +01:00
} ;
2012-08-09 08:51:00 +01:00
static const struct iio_chan_spec adis16300_channels [ ] = {
2013-01-16 12:48:00 +00:00
ADIS16400_SUPPLY_CHAN ( ADIS16400_SUPPLY_OUT , 12 ) ,
ADIS16400_GYRO_CHAN ( X , ADIS16400_XGYRO_OUT , 14 ) ,
ADIS16400_ACCEL_CHAN ( X , ADIS16400_XACCL_OUT , 14 ) ,
ADIS16400_ACCEL_CHAN ( Y , ADIS16400_YACCL_OUT , 14 ) ,
ADIS16400_ACCEL_CHAN ( Z , ADIS16400_ZACCL_OUT , 14 ) ,
ADIS16400_TEMP_CHAN ( ADIS16350_XTEMP_OUT , 12 ) ,
ADIS16400_AUX_ADC_CHAN ( ADIS16300_AUX_ADC , 12 ) ,
ADIS16400_INCLI_CHAN ( X , ADIS16300_PITCH_OUT , 13 ) ,
ADIS16400_INCLI_CHAN ( Y , ADIS16300_ROLL_OUT , 13 ) ,
2014-01-24 11:24:00 +00:00
IIO_CHAN_SOFT_TIMESTAMP ( ADIS16400_SCAN_TIMESTAMP ) ,
2011-05-18 14:41:30 +01:00
} ;
2011-09-30 10:05:45 +01:00
static const struct iio_chan_spec adis16334_channels [ ] = {
2013-01-16 12:48:00 +00:00
ADIS16400_GYRO_CHAN ( X , ADIS16400_XGYRO_OUT , 14 ) ,
ADIS16400_GYRO_CHAN ( Y , ADIS16400_YGYRO_OUT , 14 ) ,
ADIS16400_GYRO_CHAN ( Z , ADIS16400_ZGYRO_OUT , 14 ) ,
ADIS16400_ACCEL_CHAN ( X , ADIS16400_XACCL_OUT , 14 ) ,
ADIS16400_ACCEL_CHAN ( Y , ADIS16400_YACCL_OUT , 14 ) ,
ADIS16400_ACCEL_CHAN ( Z , ADIS16400_ZACCL_OUT , 14 ) ,
ADIS16400_TEMP_CHAN ( ADIS16350_XTEMP_OUT , 12 ) ,
2014-01-24 11:24:00 +00:00
IIO_CHAN_SOFT_TIMESTAMP ( ADIS16400_SCAN_TIMESTAMP ) ,
2011-08-12 18:04:37 +01:00
} ;
2011-05-18 14:41:28 +01:00
static struct adis16400_chip_info adis16400_chips [ ] = {
2011-05-18 14:41:30 +01:00
[ ADIS16300 ] = {
. channels = adis16300_channels ,
. num_channels = ARRAY_SIZE ( adis16300_channels ) ,
2015-08-05 15:38:16 +02:00
. flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE |
ADIS16400_HAS_SERIAL_NUMBER ,
2012-10-15 10:35:00 +01:00
. gyro_scale_micro = IIO_DEGREE_TO_RAD ( 50000 ) , /* 0.05 deg/s */
2011-05-18 14:41:30 +01:00
. accel_scale_micro = 5884 ,
2012-10-15 10:35:00 +01:00
. temp_scale_nano = 140000000 , /* 0.14 C */
. temp_offset = 25000000 / 140000 , /* 25 C = 0x00 */
2012-10-30 10:26:00 +00:00
. set_freq = adis16400_set_freq ,
. get_freq = adis16400_get_freq ,
2011-05-18 14:41:30 +01:00
} ,
2011-09-30 10:05:45 +01:00
[ ADIS16334 ] = {
. channels = adis16334_channels ,
. num_channels = ARRAY_SIZE ( adis16334_channels ) ,
2013-01-16 12:48:00 +00:00
. flags = ADIS16400_HAS_PROD_ID | ADIS16400_NO_BURST |
ADIS16400_HAS_SERIAL_NUMBER ,
2012-10-15 10:35:00 +01:00
. gyro_scale_micro = IIO_DEGREE_TO_RAD ( 50000 ) , /* 0.05 deg/s */
. accel_scale_micro = IIO_G_TO_M_S_2 ( 1000 ) , /* 1 mg */
2012-10-15 10:35:00 +01:00
. temp_scale_nano = 67850000 , /* 0.06785 C */
. temp_offset = 25000000 / 67850 , /* 25 C = 0x00 */
2012-10-30 10:26:00 +00:00
. set_freq = adis16334_set_freq ,
. get_freq = adis16334_get_freq ,
2011-08-12 18:04:37 +01:00
} ,
2011-05-18 14:41:28 +01:00
[ ADIS16350 ] = {
. channels = adis16350_channels ,
. num_channels = ARRAY_SIZE ( adis16350_channels ) ,
2012-10-15 10:35:00 +01:00
. gyro_scale_micro = IIO_DEGREE_TO_RAD ( 73260 ) , /* 0.07326 deg/s */
. accel_scale_micro = IIO_G_TO_M_S_2 ( 2522 ) , /* 0.002522 g */
2012-10-15 10:35:00 +01:00
. temp_scale_nano = 145300000 , /* 0.1453 C */
. temp_offset = 25000000 / 145300 , /* 25 C = 0x00 */
2012-10-30 10:26:00 +00:00
. flags = ADIS16400_NO_BURST | ADIS16400_HAS_SLOW_MODE ,
. set_freq = adis16400_set_freq ,
. get_freq = adis16400_get_freq ,
2011-05-18 14:41:28 +01:00
} ,
[ ADIS16360 ] = {
. channels = adis16350_channels ,
. num_channels = ARRAY_SIZE ( adis16350_channels ) ,
2013-01-16 12:48:00 +00:00
. flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE |
ADIS16400_HAS_SERIAL_NUMBER ,
2012-10-15 10:35:00 +01:00
. gyro_scale_micro = IIO_DEGREE_TO_RAD ( 50000 ) , /* 0.05 deg/s */
. accel_scale_micro = IIO_G_TO_M_S_2 ( 3333 ) , /* 3.333 mg */
2012-10-15 10:35:00 +01:00
. temp_scale_nano = 136000000 , /* 0.136 C */
. temp_offset = 25000000 / 136000 , /* 25 C = 0x00 */
2012-10-30 10:26:00 +00:00
. set_freq = adis16400_set_freq ,
. get_freq = adis16400_get_freq ,
2011-05-18 14:41:28 +01:00
} ,
[ ADIS16362 ] = {
. channels = adis16350_channels ,
. num_channels = ARRAY_SIZE ( adis16350_channels ) ,
2013-01-16 12:48:00 +00:00
. flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE |
ADIS16400_HAS_SERIAL_NUMBER ,
2012-10-15 10:35:00 +01:00
. gyro_scale_micro = IIO_DEGREE_TO_RAD ( 50000 ) , /* 0.05 deg/s */
. accel_scale_micro = IIO_G_TO_M_S_2 ( 333 ) , /* 0.333 mg */
2012-10-15 10:35:00 +01:00
. temp_scale_nano = 136000000 , /* 0.136 C */
. temp_offset = 25000000 / 136000 , /* 25 C = 0x00 */
2012-10-30 10:26:00 +00:00
. set_freq = adis16400_set_freq ,
. get_freq = adis16400_get_freq ,
2011-05-18 14:41:28 +01:00
} ,
[ ADIS16364 ] = {
. channels = adis16350_channels ,
. num_channels = ARRAY_SIZE ( adis16350_channels ) ,
2013-01-16 12:48:00 +00:00
. flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE |
ADIS16400_HAS_SERIAL_NUMBER ,
2012-10-15 10:35:00 +01:00
. gyro_scale_micro = IIO_DEGREE_TO_RAD ( 50000 ) , /* 0.05 deg/s */
. accel_scale_micro = IIO_G_TO_M_S_2 ( 1000 ) , /* 1 mg */
2012-10-15 10:35:00 +01:00
. temp_scale_nano = 136000000 , /* 0.136 C */
. temp_offset = 25000000 / 136000 , /* 25 C = 0x00 */
2012-10-30 10:26:00 +00:00
. set_freq = adis16400_set_freq ,
. get_freq = adis16400_get_freq ,
2011-05-18 14:41:28 +01:00
} ,
2015-08-05 15:38:19 +02:00
[ ADIS16367 ] = {
. channels = adis16350_channels ,
. num_channels = ARRAY_SIZE ( adis16350_channels ) ,
. flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE |
ADIS16400_HAS_SERIAL_NUMBER ,
. gyro_scale_micro = IIO_DEGREE_TO_RAD ( 2000 ) , /* 0.2 deg/s */
. accel_scale_micro = IIO_G_TO_M_S_2 ( 3333 ) , /* 3.333 mg */
. temp_scale_nano = 136000000 , /* 0.136 C */
. temp_offset = 25000000 / 136000 , /* 25 C = 0x00 */
. set_freq = adis16400_set_freq ,
. get_freq = adis16400_get_freq ,
} ,
2011-05-18 14:41:28 +01:00
[ ADIS16400 ] = {
. channels = adis16400_channels ,
. num_channels = ARRAY_SIZE ( adis16400_channels ) ,
2012-10-30 10:26:00 +00:00
. flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE ,
2012-10-15 10:35:00 +01:00
. gyro_scale_micro = IIO_DEGREE_TO_RAD ( 50000 ) , /* 0.05 deg/s */
. accel_scale_micro = IIO_G_TO_M_S_2 ( 3333 ) , /* 3.333 mg */
2012-10-15 10:35:00 +01:00
. temp_scale_nano = 140000000 , /* 0.14 C */
. temp_offset = 25000000 / 140000 , /* 25 C = 0x00 */
2012-10-30 10:26:00 +00:00
. set_freq = adis16400_set_freq ,
. get_freq = adis16400_get_freq ,
2013-01-16 12:48:00 +00:00
} ,
2015-08-05 15:38:20 +02:00
[ ADIS16445 ] = {
. channels = adis16445_channels ,
. num_channels = ARRAY_SIZE ( adis16445_channels ) ,
. flags = ADIS16400_HAS_PROD_ID |
ADIS16400_HAS_SERIAL_NUMBER |
ADIS16400_BURST_DIAG_STAT ,
. gyro_scale_micro = IIO_DEGREE_TO_RAD ( 10000 ) , /* 0.01 deg/s */
. accel_scale_micro = IIO_G_TO_M_S_2 ( 250 ) , /* 1/4000 g */
. temp_scale_nano = 73860000 , /* 0.07386 C */
. temp_offset = 31000000 / 73860 , /* 31 C = 0x00 */
. set_freq = adis16334_set_freq ,
. get_freq = adis16334_get_freq ,
} ,
2013-01-16 12:48:00 +00:00
[ ADIS16448 ] = {
. channels = adis16448_channels ,
. num_channels = ARRAY_SIZE ( adis16448_channels ) ,
. flags = ADIS16400_HAS_PROD_ID |
2015-05-15 17:18:38 +02:00
ADIS16400_HAS_SERIAL_NUMBER |
ADIS16400_BURST_DIAG_STAT ,
2015-08-05 15:38:13 +02:00
. gyro_scale_micro = IIO_DEGREE_TO_RAD ( 40000 ) , /* 0.04 deg/s */
2013-01-16 12:48:00 +00:00
. accel_scale_micro = IIO_G_TO_M_S_2 ( 833 ) , /* 1/1200 g */
. temp_scale_nano = 73860000 , /* 0.07386 C */
. temp_offset = 31000000 / 73860 , /* 31 C = 0x00 */
. set_freq = adis16334_set_freq ,
. get_freq = adis16334_get_freq ,
2011-05-18 14:41:28 +01:00
}
} ;
2011-05-18 14:42:37 +01:00
static const struct iio_info adis16400_info = {
. read_raw = & adis16400_read_raw ,
. write_raw = & adis16400_write_raw ,
2019-03-22 22:44:40 +02:00
. update_scan_mode = adis_update_scan_mode ,
2013-01-16 12:48:00 +00:00
. debugfs_reg_access = adis_debugfs_reg_access ,
2013-01-16 12:48:00 +00:00
} ;
2013-01-16 12:48:00 +00:00
static const char * const adis16400_status_error_msgs [ ] = {
[ ADIS16400_DIAG_STAT_ZACCL_FAIL ] = " Z-axis accelerometer self-test failure " ,
[ ADIS16400_DIAG_STAT_YACCL_FAIL ] = " Y-axis accelerometer self-test failure " ,
[ ADIS16400_DIAG_STAT_XACCL_FAIL ] = " X-axis accelerometer self-test failure " ,
[ ADIS16400_DIAG_STAT_XGYRO_FAIL ] = " X-axis gyroscope self-test failure " ,
[ ADIS16400_DIAG_STAT_YGYRO_FAIL ] = " Y-axis gyroscope self-test failure " ,
[ ADIS16400_DIAG_STAT_ZGYRO_FAIL ] = " Z-axis gyroscope self-test failure " ,
[ ADIS16400_DIAG_STAT_ALARM2 ] = " Alarm 2 active " ,
[ ADIS16400_DIAG_STAT_ALARM1 ] = " Alarm 1 active " ,
[ ADIS16400_DIAG_STAT_FLASH_CHK ] = " Flash checksum error " ,
[ ADIS16400_DIAG_STAT_SELF_TEST ] = " Self test error " ,
[ ADIS16400_DIAG_STAT_OVERFLOW ] = " Sensor overrange " ,
[ ADIS16400_DIAG_STAT_SPI_FAIL ] = " SPI failure " ,
[ ADIS16400_DIAG_STAT_FLASH_UPT ] = " Flash update failed " ,
[ ADIS16400_DIAG_STAT_POWER_HIGH ] = " Power supply above 5.25V " ,
[ ADIS16400_DIAG_STAT_POWER_LOW ] = " Power supply below 4.75V " ,
} ;
static const struct adis_data adis16400_data = {
. msc_ctrl_reg = ADIS16400_MSC_CTRL ,
. glob_cmd_reg = ADIS16400_GLOB_CMD ,
. diag_stat_reg = ADIS16400_DIAG_STAT ,
. read_delay = 50 ,
. write_delay = 50 ,
. self_test_mask = ADIS16400_MSC_CTRL_MEM_TEST ,
. startup_delay = ADIS16400_STARTUP_DELAY ,
. status_error_msgs = adis16400_status_error_msgs ,
. status_error_mask = BIT ( ADIS16400_DIAG_STAT_ZACCL_FAIL ) |
BIT ( ADIS16400_DIAG_STAT_YACCL_FAIL ) |
BIT ( ADIS16400_DIAG_STAT_XACCL_FAIL ) |
BIT ( ADIS16400_DIAG_STAT_XGYRO_FAIL ) |
BIT ( ADIS16400_DIAG_STAT_YGYRO_FAIL ) |
BIT ( ADIS16400_DIAG_STAT_ZGYRO_FAIL ) |
BIT ( ADIS16400_DIAG_STAT_ALARM2 ) |
BIT ( ADIS16400_DIAG_STAT_ALARM1 ) |
BIT ( ADIS16400_DIAG_STAT_FLASH_CHK ) |
BIT ( ADIS16400_DIAG_STAT_SELF_TEST ) |
BIT ( ADIS16400_DIAG_STAT_OVERFLOW ) |
BIT ( ADIS16400_DIAG_STAT_SPI_FAIL ) |
BIT ( ADIS16400_DIAG_STAT_FLASH_UPT ) |
BIT ( ADIS16400_DIAG_STAT_POWER_HIGH ) |
BIT ( ADIS16400_DIAG_STAT_POWER_LOW ) ,
} ;
2015-05-15 17:18:36 +02:00
static void adis16400_setup_chan_mask ( struct adis16400_state * st )
{
const struct adis16400_chip_info * chip_info = st - > variant ;
2017-07-01 17:54:08 -04:00
unsigned int i ;
2015-05-15 17:18:36 +02:00
for ( i = 0 ; i < chip_info - > num_channels ; i + + ) {
const struct iio_chan_spec * ch = & chip_info - > channels [ i ] ;
if ( ch - > scan_index > = 0 & &
ch - > scan_index ! = ADIS16400_SCAN_TIMESTAMP )
st - > avail_scan_mask [ 0 ] | = BIT ( ch - > scan_index ) ;
}
}
2012-11-19 13:21:57 -05:00
static int adis16400_probe ( struct spi_device * spi )
2010-05-04 14:43:15 +01:00
{
2011-05-18 14:42:23 +01:00
struct adis16400_state * st ;
2013-01-16 12:48:00 +00:00
struct iio_dev * indio_dev ;
int ret ;
2013-07-30 09:44:00 +01:00
indio_dev = devm_iio_device_alloc ( & spi - > dev , sizeof ( * st ) ) ;
2013-01-16 12:48:00 +00:00
if ( indio_dev = = NULL )
return - ENOMEM ;
2011-05-18 14:42:23 +01:00
st = iio_priv ( indio_dev ) ;
2010-05-04 14:43:15 +01:00
/* this is only used for removal purposes */
2011-05-18 14:42:23 +01:00
spi_set_drvdata ( spi , indio_dev ) ;
2010-05-04 14:43:15 +01:00
/* setup the industrialio driver allocated elements */
2011-05-18 14:41:28 +01:00
st - > variant = & adis16400_chips [ spi_get_device_id ( spi ) - > driver_data ] ;
2011-05-18 14:42:23 +01:00
indio_dev - > dev . parent = & spi - > dev ;
indio_dev - > name = spi_get_device_id ( spi ) - > name ;
indio_dev - > channels = st - > variant - > channels ;
indio_dev - > num_channels = st - > variant - > num_channels ;
2011-05-18 14:42:37 +01:00
indio_dev - > info = & adis16400_info ;
2011-05-18 14:42:23 +01:00
indio_dev - > modes = INDIO_DIRECT_MODE ;
2015-05-15 17:18:36 +02:00
if ( ! ( st - > variant - > flags & ADIS16400_NO_BURST ) ) {
adis16400_setup_chan_mask ( st ) ;
indio_dev - > available_scan_masks = st - > avail_scan_mask ;
2019-03-22 22:44:39 +02:00
st - > adis . burst = & adis16400_burst ;
if ( st - > variant - > flags & ADIS16400_BURST_DIAG_STAT )
st - > adis . burst - > extra_len = sizeof ( u16 ) ;
2015-05-15 17:18:36 +02:00
}
2013-01-16 12:48:00 +00:00
2013-01-16 12:48:00 +00:00
ret = adis_init ( & st - > adis , indio_dev , spi , & adis16400_data ) ;
if ( ret )
2013-07-30 09:44:00 +01:00
return ret ;
2013-01-16 12:48:00 +00:00
2013-01-16 12:48:00 +00:00
ret = adis_setup_buffer_and_trigger ( & st - > adis , indio_dev ,
adis16400_trigger_handler ) ;
2010-05-04 14:43:15 +01:00
if ( ret )
2013-07-30 09:44:00 +01:00
return ret ;
2010-05-04 14:43:15 +01:00
/* Get the device into a sane initial state */
2011-05-18 14:42:23 +01:00
ret = adis16400_initial_setup ( indio_dev ) ;
2010-05-04 14:43:15 +01:00
if ( ret )
2013-01-16 12:48:00 +00:00
goto error_cleanup_buffer ;
2011-09-02 17:14:40 +01:00
ret = iio_device_register ( indio_dev ) ;
if ( ret )
2013-01-16 12:48:00 +00:00
goto error_cleanup_buffer ;
2011-09-02 17:14:40 +01:00
2013-01-16 12:48:00 +00:00
adis16400_debugfs_init ( indio_dev ) ;
2010-05-04 14:43:15 +01:00
return 0 ;
2013-01-16 12:48:00 +00:00
error_cleanup_buffer :
adis_cleanup_buffer_and_trigger ( & st - > adis , indio_dev ) ;
2010-05-04 14:43:15 +01:00
return ret ;
}
2012-11-19 13:26:37 -05:00
static int adis16400_remove ( struct spi_device * spi )
2010-05-04 14:43:15 +01:00
{
2013-01-16 12:48:00 +00:00
struct iio_dev * indio_dev = spi_get_drvdata ( spi ) ;
2013-01-16 12:48:00 +00:00
struct adis16400_state * st = iio_priv ( indio_dev ) ;
2010-05-04 14:43:15 +01:00
2011-10-14 14:46:58 +01:00
iio_device_unregister ( indio_dev ) ;
2012-09-22 09:56:00 +01:00
adis16400_stop_device ( indio_dev ) ;
2010-05-04 14:43:15 +01:00
2013-01-16 12:48:00 +00:00
adis_cleanup_buffer_and_trigger ( & st - > adis , indio_dev ) ;
2013-01-16 12:48:00 +00:00
2010-05-04 14:43:15 +01:00
return 0 ;
}
2011-05-18 14:41:28 +01:00
static const struct spi_device_id adis16400_id [ ] = {
2011-05-18 14:41:30 +01:00
{ " adis16300 " , ADIS16300 } ,
2015-08-05 15:38:17 +02:00
{ " adis16305 " , ADIS16300 } ,
2011-09-30 10:05:45 +01:00
{ " adis16334 " , ADIS16334 } ,
2011-05-18 14:41:28 +01:00
{ " adis16350 " , ADIS16350 } ,
{ " adis16354 " , ADIS16350 } ,
{ " adis16355 " , ADIS16350 } ,
{ " adis16360 " , ADIS16360 } ,
{ " adis16362 " , ADIS16362 } ,
{ " adis16364 " , ADIS16364 } ,
2012-10-30 10:26:00 +00:00
{ " adis16365 " , ADIS16360 } ,
2015-08-05 15:38:19 +02:00
{ " adis16367 " , ADIS16367 } ,
2011-05-18 14:41:28 +01:00
{ " adis16400 " , ADIS16400 } ,
{ " adis16405 " , ADIS16400 } ,
2015-08-05 15:38:20 +02:00
{ " adis16445 " , ADIS16445 } ,
2013-01-16 12:48:00 +00:00
{ " adis16448 " , ADIS16448 } ,
2011-05-18 14:41:28 +01:00
{ }
} ;
2011-11-16 08:53:31 +01:00
MODULE_DEVICE_TABLE ( spi , adis16400_id ) ;
2011-05-18 14:41:28 +01:00
2010-05-04 14:43:15 +01:00
static struct spi_driver adis16400_driver = {
. driver = {
. name = " adis16400 " ,
} ,
2011-05-18 14:41:28 +01:00
. id_table = adis16400_id ,
2010-05-04 14:43:15 +01:00
. probe = adis16400_probe ,
2012-11-19 13:21:38 -05:00
. remove = adis16400_remove ,
2010-05-04 14:43:15 +01:00
} ;
2011-11-16 10:13:39 +01:00
module_spi_driver ( adis16400_driver ) ;
2010-05-04 14:43:15 +01:00
MODULE_AUTHOR ( " Manuel Stahl <manuel.stahl@iis.fraunhofer.de> " ) ;
MODULE_DESCRIPTION ( " Analog Devices ADIS16400/5 IMU SPI driver " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;