2019-05-28 19:57:06 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2011-04-06 13:42:49 +04:00
/*
2011-12-14 23:25:13 +04:00
* ADXRS450 / ADXRS453 Digital Output Gyroscope Driver
2011-04-06 13:42:49 +04:00
*
* Copyright 2011 Analog Devices Inc .
*/
# 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>
# include <linux/slab.h>
# include <linux/sysfs.h>
# include <linux/list.h>
2011-07-03 23:49:50 +04:00
# include <linux/module.h>
2011-04-06 13:42:49 +04:00
2012-04-25 18:54:58 +04:00
# include <linux/iio/iio.h>
# include <linux/iio/sysfs.h>
2011-04-06 13:42:49 +04:00
2013-01-31 18:27:00 +04:00
# define ADXRS450_STARTUP_DELAY 50 /* ms */
/* The MSB for the spi commands */
# define ADXRS450_SENSOR_DATA (0x20 << 24)
# define ADXRS450_WRITE_DATA (0x40 << 24)
# define ADXRS450_READ_DATA (0x80 << 24)
# define ADXRS450_RATE1 0x00 /* Rate Registers */
# define ADXRS450_TEMP1 0x02 /* Temperature Registers */
# define ADXRS450_LOCST1 0x04 /* Low CST Memory Registers */
# define ADXRS450_HICST1 0x06 /* High CST Memory Registers */
# define ADXRS450_QUAD1 0x08 /* Quad Memory Registers */
# define ADXRS450_FAULT1 0x0A /* Fault Registers */
# define ADXRS450_PID1 0x0C /* Part ID Register 1 */
# define ADXRS450_SNH 0x0E /* Serial Number Registers, 4 bytes */
# define ADXRS450_SNL 0x10
# define ADXRS450_DNC1 0x12 /* Dynamic Null Correction Registers */
/* Check bits */
# define ADXRS450_P 0x01
# define ADXRS450_CHK 0x02
# define ADXRS450_CST 0x04
# define ADXRS450_PWR 0x08
# define ADXRS450_POR 0x10
# define ADXRS450_NVM 0x20
# define ADXRS450_Q 0x40
# define ADXRS450_PLL 0x80
# define ADXRS450_UV 0x100
# define ADXRS450_OV 0x200
# define ADXRS450_AMP 0x400
# define ADXRS450_FAIL 0x800
# define ADXRS450_WRERR_MASK (0x7 << 29)
# define ADXRS450_MAX_RX 4
# define ADXRS450_MAX_TX 4
# define ADXRS450_GET_ST(a) ((a >> 26) & 0x3)
enum {
ID_ADXRS450 ,
ID_ADXRS453 ,
} ;
/**
* struct adxrs450_state - device instance specific data
* @ us : actual spi_device
* @ buf_lock : mutex to protect tx and rx
* @ tx : transmit buffer
* @ rx : receive buffer
* */
struct adxrs450_state {
struct spi_device * us ;
struct mutex buf_lock ;
2022-05-08 20:56:54 +03:00
__be32 tx __aligned ( IIO_DMA_MINALIGN ) ;
2013-01-31 18:27:00 +04:00
__be32 rx ;
} ;
2011-04-06 13:42:49 +04:00
/**
* adxrs450_spi_read_reg_16 ( ) - read 2 bytes from a register pair
2013-01-31 18:27:00 +04:00
* @ indio_dev : device associated with child of actual iio_dev
2013-01-31 18:27:00 +04:00
* @ reg_address : the address of the lower of the two registers , which should be
* an even address , the second register ' s address is reg_address + 1.
2011-04-06 13:42:49 +04:00
* @ val : somewhere to pass back the value read
* */
2011-08-12 20:47:54 +04:00
static int adxrs450_spi_read_reg_16 ( struct iio_dev * indio_dev ,
u8 reg_address ,
u16 * val )
2011-04-06 13:42:49 +04:00
{
2011-06-27 16:07:47 +04:00
struct adxrs450_state * st = iio_priv ( indio_dev ) ;
2013-01-31 18:27:00 +04:00
u32 tx ;
2011-04-06 13:42:49 +04:00
int ret ;
2013-01-31 18:27:00 +04:00
struct spi_transfer xfers [ ] = {
{
2013-01-31 18:27:00 +04:00
. tx_buf = & st - > tx ,
2013-01-31 18:27:00 +04:00
. bits_per_word = 8 ,
2013-01-31 18:27:00 +04:00
. len = sizeof ( st - > tx ) ,
2013-01-31 18:27:00 +04:00
. cs_change = 1 ,
} , {
2013-01-31 18:27:00 +04:00
. rx_buf = & st - > rx ,
2013-01-31 18:27:00 +04:00
. bits_per_word = 8 ,
2013-01-31 18:27:00 +04:00
. len = sizeof ( st - > rx ) ,
2013-01-31 18:27:00 +04:00
} ,
} ;
2011-04-29 16:16:59 +04:00
2011-04-06 13:42:49 +04:00
mutex_lock ( & st - > buf_lock ) ;
2013-01-31 18:27:00 +04:00
tx = ADXRS450_READ_DATA | ( reg_address < < 17 ) ;
2011-04-06 13:42:49 +04:00
2013-01-31 18:27:00 +04:00
if ( ! ( hweight32 ( tx ) & 1 ) )
tx | = ADXRS450_P ;
2011-04-29 16:17:01 +04:00
2013-01-31 18:27:00 +04:00
st - > tx = cpu_to_be32 ( tx ) ;
2013-10-05 11:45:00 +04:00
ret = spi_sync_transfer ( st - > us , xfers , ARRAY_SIZE ( xfers ) ) ;
2011-04-06 13:42:49 +04:00
if ( ret ) {
dev_err ( & st - > us - > dev , " problem while reading 16 bit register 0x%02x \n " ,
reg_address ) ;
goto error_ret ;
}
2013-01-31 18:27:00 +04:00
* val = ( be32_to_cpu ( st - > rx ) > > 5 ) & 0xFFFF ;
2011-04-06 13:42:49 +04:00
error_ret :
mutex_unlock ( & st - > buf_lock ) ;
return ret ;
}
/**
* adxrs450_spi_write_reg_16 ( ) - write 2 bytes data to a register pair
2013-01-31 18:27:00 +04:00
* @ indio_dev : device associated with child of actual actual iio_dev
2013-01-31 18:27:00 +04:00
* @ reg_address : the address of the lower of the two registers , which should be
* an even address , the second register ' s address is reg_address + 1.
2011-04-06 13:42:49 +04:00
* @ val : value to be written .
* */
2011-08-12 20:47:54 +04:00
static int adxrs450_spi_write_reg_16 ( struct iio_dev * indio_dev ,
u8 reg_address ,
u16 val )
2011-04-06 13:42:49 +04:00
{
2011-06-27 16:07:47 +04:00
struct adxrs450_state * st = iio_priv ( indio_dev ) ;
2013-01-31 18:27:00 +04:00
u32 tx ;
2011-04-06 13:42:49 +04:00
int ret ;
mutex_lock ( & st - > buf_lock ) ;
2013-01-31 18:27:00 +04:00
tx = ADXRS450_WRITE_DATA | ( reg_address < < 17 ) | ( val < < 1 ) ;
2011-04-29 16:17:01 +04:00
2013-01-31 18:27:00 +04:00
if ( ! ( hweight32 ( tx ) & 1 ) )
tx | = ADXRS450_P ;
2011-04-29 16:17:01 +04:00
2013-01-31 18:27:00 +04:00
st - > tx = cpu_to_be32 ( tx ) ;
ret = spi_write ( st - > us , & st - > tx , sizeof ( st - > tx ) ) ;
2011-04-06 13:42:49 +04:00
if ( ret )
dev_err ( & st - > us - > dev , " problem while writing 16 bit register 0x%02x \n " ,
2011-08-12 20:47:55 +04:00
reg_address ) ;
2013-01-31 18:27:00 +04:00
usleep_range ( 100 , 1000 ) ; /* enforce sequential transfer delay 0.1ms */
2011-04-06 13:42:49 +04:00
mutex_unlock ( & st - > buf_lock ) ;
return ret ;
}
/**
* adxrs450_spi_sensor_data ( ) - read 2 bytes sensor data
2013-01-31 18:27:00 +04:00
* @ indio_dev : device associated with child of actual iio_dev
2011-04-06 13:42:49 +04:00
* @ val : somewhere to pass back the value read
* */
2011-08-12 20:47:54 +04:00
static int adxrs450_spi_sensor_data ( struct iio_dev * indio_dev , s16 * val )
2011-04-06 13:42:49 +04:00
{
2011-06-27 16:07:47 +04:00
struct adxrs450_state * st = iio_priv ( indio_dev ) ;
2011-04-06 13:42:49 +04:00
int ret ;
2013-01-31 18:27:00 +04:00
struct spi_transfer xfers [ ] = {
{
2013-01-31 18:27:00 +04:00
. tx_buf = & st - > tx ,
2013-01-31 18:27:00 +04:00
. bits_per_word = 8 ,
2013-01-31 18:27:00 +04:00
. len = sizeof ( st - > tx ) ,
2013-01-31 18:27:00 +04:00
. cs_change = 1 ,
} , {
2013-01-31 18:27:00 +04:00
. rx_buf = & st - > rx ,
2013-01-31 18:27:00 +04:00
. bits_per_word = 8 ,
2013-01-31 18:27:00 +04:00
. len = sizeof ( st - > rx ) ,
2013-01-31 18:27:00 +04:00
} ,
} ;
2011-04-06 13:42:49 +04:00
mutex_lock ( & st - > buf_lock ) ;
2013-01-31 18:27:00 +04:00
st - > tx = cpu_to_be32 ( ADXRS450_SENSOR_DATA ) ;
2011-04-06 13:42:49 +04:00
2013-10-05 11:45:00 +04:00
ret = spi_sync_transfer ( st - > us , xfers , ARRAY_SIZE ( xfers ) ) ;
2011-04-06 13:42:49 +04:00
if ( ret ) {
dev_err ( & st - > us - > dev , " Problem while reading sensor data \n " ) ;
goto error_ret ;
}
2013-01-31 18:27:00 +04:00
* val = ( be32_to_cpu ( st - > rx ) > > 10 ) & 0xFFFF ;
2011-04-29 16:17:00 +04:00
2011-04-06 13:42:49 +04:00
error_ret :
mutex_unlock ( & st - > buf_lock ) ;
return ret ;
}
/**
* adxrs450_spi_initial ( ) - use for initializing procedure .
* @ st : device instance specific data
* @ val : somewhere to pass back the value read
2013-01-31 18:27:00 +04:00
* @ chk : Whether to perform fault check
2011-04-06 13:42:49 +04:00
* */
static int adxrs450_spi_initial ( struct adxrs450_state * st ,
u32 * val , char chk )
{
int ret ;
2013-01-31 18:27:00 +04:00
u32 tx ;
2011-04-06 13:42:49 +04:00
struct spi_transfer xfers = {
2013-01-31 18:27:00 +04:00
. tx_buf = & st - > tx ,
. rx_buf = & st - > rx ,
2011-04-06 13:42:49 +04:00
. bits_per_word = 8 ,
2013-01-31 18:27:00 +04:00
. len = sizeof ( st - > tx ) ,
2011-04-06 13:42:49 +04:00
} ;
mutex_lock ( & st - > buf_lock ) ;
2013-01-31 18:27:00 +04:00
tx = ADXRS450_SENSOR_DATA ;
2011-04-06 13:42:49 +04:00
if ( chk )
2013-01-31 18:27:00 +04:00
tx | = ( ADXRS450_CHK | ADXRS450_P ) ;
st - > tx = cpu_to_be32 ( tx ) ;
2013-01-09 21:31:00 +04:00
ret = spi_sync_transfer ( st - > us , & xfers , 1 ) ;
2011-04-06 13:42:49 +04:00
if ( ret ) {
dev_err ( & st - > us - > dev , " Problem while reading initializing data \n " ) ;
goto error_ret ;
}
2013-01-31 18:27:00 +04:00
* val = be32_to_cpu ( st - > rx ) ;
2011-04-06 13:42:49 +04:00
error_ret :
mutex_unlock ( & st - > buf_lock ) ;
return ret ;
}
/* Recommended Startup Sequence by spec */
2011-06-27 16:07:47 +04:00
static int adxrs450_initial_setup ( struct iio_dev * indio_dev )
2011-04-06 13:42:49 +04:00
{
u32 t ;
u16 data ;
int ret ;
2011-06-27 16:07:47 +04:00
struct adxrs450_state * st = iio_priv ( indio_dev ) ;
2011-04-06 13:42:49 +04:00
msleep ( ADXRS450_STARTUP_DELAY * 2 ) ;
ret = adxrs450_spi_initial ( st , & t , 1 ) ;
if ( ret )
return ret ;
2011-04-29 16:17:04 +04:00
if ( t ! = 0x01 )
2013-01-31 18:27:00 +04:00
dev_warn ( & st - > us - > dev , " The initial power on response is not correct! Restart without reset? \n " ) ;
2011-04-06 13:42:49 +04:00
msleep ( ADXRS450_STARTUP_DELAY ) ;
ret = adxrs450_spi_initial ( st , & t , 0 ) ;
if ( ret )
return ret ;
msleep ( ADXRS450_STARTUP_DELAY ) ;
ret = adxrs450_spi_initial ( st , & t , 0 ) ;
if ( ret )
return ret ;
if ( ( ( t & 0xff ) | 0x01 ) ! = 0xff | | ADXRS450_GET_ST ( t ) ! = 2 ) {
dev_err ( & st - > us - > dev , " The second response is not correct! \n " ) ;
return - EIO ;
}
ret = adxrs450_spi_initial ( st , & t , 0 ) ;
if ( ret )
return ret ;
if ( ( ( t & 0xff ) | 0x01 ) ! = 0xff | | ADXRS450_GET_ST ( t ) ! = 2 ) {
dev_err ( & st - > us - > dev , " The third response is not correct! \n " ) ;
return - EIO ;
}
2011-08-12 20:47:54 +04:00
ret = adxrs450_spi_read_reg_16 ( indio_dev , ADXRS450_FAULT1 , & data ) ;
2011-04-06 13:42:49 +04:00
if ( ret )
return ret ;
if ( data & 0x0fff ) {
dev_err ( & st - > us - > dev , " The device is not in normal status! \n " ) ;
return - EINVAL ;
}
return 0 ;
}
2011-08-12 20:47:54 +04:00
static int adxrs450_write_raw ( struct iio_dev * indio_dev ,
struct iio_chan_spec const * chan ,
int val ,
int val2 ,
long mask )
{
int ret ;
switch ( mask ) {
2011-10-26 20:41:36 +04:00
case IIO_CHAN_INFO_CALIBBIAS :
2013-01-31 18:27:00 +04:00
if ( val < - 0x400 | | val > = 0x400 )
return - EINVAL ;
2011-08-12 20:47:54 +04:00
ret = adxrs450_spi_write_reg_16 ( indio_dev ,
2013-01-31 18:27:00 +04:00
ADXRS450_DNC1 , val ) ;
2011-08-12 20:47:54 +04:00
break ;
default :
ret = - EINVAL ;
break ;
}
return ret ;
}
static int adxrs450_read_raw ( struct iio_dev * indio_dev ,
struct iio_chan_spec const * chan ,
int * val ,
int * val2 ,
long mask )
{
int ret ;
2011-08-12 20:47:56 +04:00
s16 t ;
2011-12-14 23:25:11 +04:00
2011-08-12 20:47:54 +04:00
switch ( mask ) {
2012-04-15 20:41:20 +04:00
case IIO_CHAN_INFO_RAW :
2011-08-12 20:47:54 +04:00
switch ( chan - > type ) {
2011-10-05 18:27:59 +04:00
case IIO_ANGL_VEL :
2011-08-12 20:47:56 +04:00
ret = adxrs450_spi_sensor_data ( indio_dev , & t ) ;
if ( ret )
2011-08-12 20:47:54 +04:00
break ;
2011-08-12 20:47:56 +04:00
* val = t ;
2011-08-12 20:47:54 +04:00
ret = IIO_VAL_INT ;
break ;
case IIO_TEMP :
2011-08-12 20:47:56 +04:00
ret = adxrs450_spi_read_reg_16 ( indio_dev ,
2011-12-14 23:25:11 +04:00
ADXRS450_TEMP1 , & t ) ;
2011-08-12 20:47:56 +04:00
if ( ret )
2011-08-12 20:47:54 +04:00
break ;
2011-12-14 23:25:11 +04:00
* val = ( t > > 6 ) + 225 ;
2011-08-12 20:47:54 +04:00
ret = IIO_VAL_INT ;
break ;
default :
ret = - EINVAL ;
break ;
}
break ;
2011-12-14 23:25:11 +04:00
case IIO_CHAN_INFO_SCALE :
switch ( chan - > type ) {
case IIO_ANGL_VEL :
* val = 0 ;
* val2 = 218166 ;
return IIO_VAL_INT_PLUS_NANO ;
case IIO_TEMP :
* val = 200 ;
* val2 = 0 ;
return IIO_VAL_INT ;
default :
return - EINVAL ;
}
2011-10-26 20:41:36 +04:00
case IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW :
2011-08-12 20:47:56 +04:00
ret = adxrs450_spi_read_reg_16 ( indio_dev , ADXRS450_QUAD1 , & t ) ;
if ( ret )
2011-08-12 20:47:54 +04:00
break ;
2011-08-12 20:47:56 +04:00
* val = t ;
2011-08-12 20:47:54 +04:00
ret = IIO_VAL_INT ;
break ;
2011-12-14 23:25:12 +04:00
case IIO_CHAN_INFO_CALIBBIAS :
ret = adxrs450_spi_read_reg_16 ( indio_dev , ADXRS450_DNC1 , & t ) ;
if ( ret )
break ;
2013-01-31 18:27:00 +04:00
* val = sign_extend32 ( t , 9 ) ;
2011-12-14 23:25:12 +04:00
ret = IIO_VAL_INT ;
break ;
2011-08-12 20:47:54 +04:00
default :
ret = - EINVAL ;
break ;
}
return ret ;
}
2011-04-06 13:42:49 +04:00
2011-12-14 23:25:13 +04:00
static const struct iio_chan_spec adxrs450_channels [ 2 ] [ 2 ] = {
[ ID_ADXRS450 ] = {
{
. type = IIO_ANGL_VEL ,
. modified = 1 ,
. channel2 = IIO_MOD_Z ,
2013-02-27 23:30:18 +04:00
. info_mask_separate = BIT ( IIO_CHAN_INFO_RAW ) |
BIT ( IIO_CHAN_INFO_CALIBBIAS ) |
BIT ( IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW ) |
BIT ( IIO_CHAN_INFO_SCALE ) ,
2011-12-14 23:25:13 +04:00
} , {
. type = IIO_TEMP ,
. indexed = 1 ,
. channel = 0 ,
2013-02-27 23:30:18 +04:00
. info_mask_separate = BIT ( IIO_CHAN_INFO_RAW ) |
BIT ( IIO_CHAN_INFO_SCALE ) ,
2011-12-14 23:25:13 +04:00
}
} ,
[ ID_ADXRS453 ] = {
{
. type = IIO_ANGL_VEL ,
. modified = 1 ,
. channel2 = IIO_MOD_Z ,
2013-02-27 23:30:18 +04:00
. info_mask_separate = BIT ( IIO_CHAN_INFO_RAW ) |
BIT ( IIO_CHAN_INFO_SCALE ) |
BIT ( IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW ) ,
2011-12-14 23:25:13 +04:00
} , {
. type = IIO_TEMP ,
. indexed = 1 ,
. channel = 0 ,
2013-02-27 23:30:18 +04:00
. info_mask_separate = BIT ( IIO_CHAN_INFO_RAW ) |
BIT ( IIO_CHAN_INFO_SCALE ) ,
2011-12-14 23:25:13 +04:00
}
} ,
2011-04-06 13:42:49 +04:00
} ;
2011-05-18 17:42:37 +04:00
static const struct iio_info adxrs450_info = {
2011-08-12 20:47:54 +04:00
. read_raw = & adxrs450_read_raw ,
. write_raw = & adxrs450_write_raw ,
2011-05-18 17:42:37 +04:00
} ;
2012-11-19 22:21:57 +04:00
static int adxrs450_probe ( struct spi_device * spi )
2011-04-06 13:42:49 +04:00
{
2011-10-14 17:46:58 +04:00
int ret ;
2011-06-27 16:07:47 +04:00
struct adxrs450_state * st ;
struct iio_dev * indio_dev ;
2011-04-06 13:42:49 +04:00
2011-06-27 16:07:47 +04:00
/* setup the industrialio driver allocated elements */
2013-08-13 10:34:00 +04:00
indio_dev = devm_iio_device_alloc ( & spi - > dev , sizeof ( * st ) ) ;
if ( ! indio_dev )
return - ENOMEM ;
2011-06-27 16:07:47 +04:00
st = iio_priv ( indio_dev ) ;
2011-04-06 13:42:49 +04:00
st - > us = spi ;
mutex_init ( & st - > buf_lock ) ;
2011-06-27 16:07:47 +04:00
/* This is only used for removal purposes */
spi_set_drvdata ( spi , indio_dev ) ;
2011-04-06 13:42:49 +04:00
2011-06-27 16:07:47 +04:00
indio_dev - > info = & adxrs450_info ;
indio_dev - > modes = INDIO_DIRECT_MODE ;
2011-12-14 23:25:13 +04:00
indio_dev - > channels =
adxrs450_channels [ spi_get_device_id ( spi ) - > driver_data ] ;
2011-08-12 20:47:54 +04:00
indio_dev - > num_channels = ARRAY_SIZE ( adxrs450_channels ) ;
indio_dev - > name = spi - > dev . driver - > name ;
2011-04-06 13:42:49 +04:00
2013-10-29 15:39:00 +04:00
ret = devm_iio_device_register ( & spi - > dev , indio_dev ) ;
2011-04-06 13:42:49 +04:00
if ( ret )
2013-08-13 10:34:00 +04:00
return ret ;
2011-04-06 13:42:49 +04:00
/* Get the device into a sane initial state */
2011-06-27 16:07:47 +04:00
ret = adxrs450_initial_setup ( indio_dev ) ;
2011-04-06 13:42:49 +04:00
if ( ret )
2013-10-29 15:39:00 +04:00
return ret ;
2011-04-06 13:42:49 +04:00
return 0 ;
}
2011-12-14 23:25:13 +04:00
static const struct spi_device_id adxrs450_id [ ] = {
{ " adxrs450 " , ID_ADXRS450 } ,
{ " adxrs453 " , ID_ADXRS453 } ,
{ }
} ;
MODULE_DEVICE_TABLE ( spi , adxrs450_id ) ;
2011-04-06 13:42:49 +04:00
static struct spi_driver adxrs450_driver = {
. driver = {
. name = " adxrs450 " ,
} ,
. probe = adxrs450_probe ,
2011-12-14 23:25:13 +04:00
. id_table = adxrs450_id ,
2011-04-06 13:42:49 +04:00
} ;
2011-11-16 13:13:39 +04:00
module_spi_driver ( adxrs450_driver ) ;
2011-04-06 13:42:49 +04:00
MODULE_AUTHOR ( " Cliff Cai <cliff.cai@xxxxxxxxxx> " ) ;
2011-12-14 23:25:13 +04:00
MODULE_DESCRIPTION ( " Analog Devices ADXRS450/ADXRS453 Gyroscope SPI driver " ) ;
2011-04-06 13:42:49 +04:00
MODULE_LICENSE ( " GPL v2 " ) ;