2010-05-04 14:43:15 +01:00
# include <linux/interrupt.h>
# include <linux/mutex.h>
# include <linux/kernel.h>
# include <linux/spi/spi.h>
2010-05-23 03:10:35 -04:00
# include <linux/slab.h>
2011-05-18 14:41:28 +01:00
# include <linux/bitops.h>
2011-07-10 13:09:12 -04:00
# include <linux/export.h>
2010-05-04 14:43:15 +01:00
2012-04-25 15:54:58 +01:00
# include <linux/iio/iio.h>
2013-01-16 12:48:00 +00:00
# include <linux/iio/buffer.h>
# include <linux/iio/triggered_buffer.h>
2012-04-25 15:54:58 +01:00
# include <linux/iio/trigger_consumer.h>
2013-01-16 12:48:00 +00:00
2010-05-04 14:43:15 +01:00
# include "adis16400.h"
2013-01-16 12:48:00 +00:00
int adis16400_update_scan_mode ( struct iio_dev * indio_dev ,
const unsigned long * scan_mask )
2010-06-04 17:19:53 +08: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
struct adis * adis = & st - > adis ;
uint16_t * tx , * rx ;
2010-06-04 17:19:53 +08:00
2013-01-16 12:48:00 +00:00
if ( st - > variant - > flags & ADIS16400_NO_BURST )
return adis_update_scan_mode ( indio_dev , scan_mask ) ;
2010-06-04 17:19:53 +08:00
2013-01-16 12:48:00 +00:00
kfree ( adis - > xfer ) ;
kfree ( adis - > buffer ) ;
2011-05-18 14:41:28 +01:00
2013-01-16 12:48:00 +00:00
adis - > xfer = kcalloc ( 2 , sizeof ( * adis - > xfer ) , GFP_KERNEL ) ;
if ( ! adis - > xfer )
return - ENOMEM ;
2011-05-18 14:41:28 +01:00
2013-01-16 12:48:00 +00:00
adis - > buffer = kzalloc ( indio_dev - > scan_bytes + sizeof ( u16 ) ,
GFP_KERNEL ) ;
if ( ! adis - > buffer )
2011-05-18 14:41:28 +01:00
return - ENOMEM ;
2013-01-16 12:48:00 +00:00
rx = adis - > buffer ;
tx = adis - > buffer + indio_dev - > scan_bytes ;
tx [ 0 ] = ADIS_READ_REG ( ADIS16400_GLOB_CMD ) ;
tx [ 1 ] = 0 ;
adis - > xfer [ 0 ] . tx_buf = tx ;
adis - > xfer [ 0 ] . bits_per_word = 8 ;
adis - > xfer [ 0 ] . len = 2 ;
adis - > xfer [ 1 ] . tx_buf = tx ;
adis - > xfer [ 1 ] . bits_per_word = 8 ;
adis - > xfer [ 1 ] . len = indio_dev - > scan_bytes ;
spi_message_init ( & adis - > msg ) ;
spi_message_add_tail ( & adis - > xfer [ 0 ] , & adis - > msg ) ;
spi_message_add_tail ( & adis - > xfer [ 1 ] , & adis - > msg ) ;
return 0 ;
2011-05-18 14:41:28 +01:00
}
2013-01-16 12:48:00 +00:00
irqreturn_t adis16400_trigger_handler ( int irq , void * p )
2010-05-04 14:43:15 +01:00
{
2011-05-18 14:41:27 +01:00
struct iio_poll_func * pf = p ;
2011-08-24 17:28:36 +01:00
struct iio_dev * indio_dev = pf - > indio_dev ;
2011-05-18 14:42:23 +01:00
struct adis16400_state * st = iio_priv ( indio_dev ) ;
2013-01-16 12:48:00 +00:00
struct adis * adis = & st - > adis ;
u32 old_speed_hz = st - > adis . spi - > max_speed_hz ;
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 ) ;
2010-05-04 14:43:15 +01:00
}
2013-01-16 12:48:00 +00:00
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 ) ;
2011-05-18 14:41:28 +01:00
}
2013-01-16 12:48:00 +00:00
2010-05-04 14:43:15 +01:00
/* Guaranteed to be aligned with 8 byte boundary */
2013-01-16 12:48:00 +00:00
if ( indio_dev - > scan_timestamp ) {
void * b = adis - > buffer + indio_dev - > scan_bytes - sizeof ( s64 ) ;
* ( s64 * ) b = pf - > timestamp ;
}
iio_push_to_buffers ( indio_dev , adis - > buffer ) ;
2010-05-04 14:43:15 +01:00
2011-05-18 14:41:27 +01:00
iio_trigger_notify_done ( indio_dev - > trig ) ;
2010-05-04 14:43:15 +01:00
2011-05-18 14:41:27 +01:00
return IRQ_HANDLED ;
2010-05-04 14:43:15 +01:00
}