2010-10-01 18:41:51 +04:00
/*
* iio / adc / ad799x . c
2014-02-16 15:57:00 +04:00
* Copyright ( C ) 2010 - 2011 Michael Hennerich , Analog Devices Inc .
2010-10-01 18:41:51 +04:00
*
* based on iio / adc / max1363
* Copyright ( C ) 2008 - 2010 Jonathan Cameron
*
* based on linux / drivers / i2c / chips / max123x
* Copyright ( C ) 2002 - 2004 Stefan Eletzhofer
*
* based on linux / drivers / acron / char / pcf8583 . c
* Copyright ( C ) 2000 Russell King
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
* ad799x . c
*
* Support for ad7991 , ad7995 , ad7999 , ad7992 , ad7993 , ad7994 , ad7997 ,
* ad7998 and similar chips .
*
*/
# include <linux/interrupt.h>
# include <linux/device.h>
# include <linux/kernel.h>
# include <linux/sysfs.h>
# include <linux/i2c.h>
# include <linux/regulator/consumer.h>
# include <linux/slab.h>
# include <linux/types.h>
# include <linux/err.h>
2011-07-03 23:49:50 +04:00
# include <linux/module.h>
2014-12-06 08:54:00 +03:00
# include <linux/bitops.h>
2010-10-01 18:41:51 +04:00
2012-04-25 18:54:58 +04:00
# include <linux/iio/iio.h>
# include <linux/iio/sysfs.h>
# include <linux/iio/events.h>
# include <linux/iio/buffer.h>
2014-10-03 13:31:00 +04:00
# include <linux/iio/trigger_consumer.h>
# include <linux/iio/triggered_buffer.h>
2011-08-12 20:08:43 +04:00
2014-10-03 13:31:00 +04:00
# define AD799X_CHANNEL_SHIFT 4
2014-12-06 08:54:00 +03:00
2014-10-03 13:31:00 +04:00
/*
* AD7991 , AD7995 and AD7999 defines
*/
# define AD7991_REF_SEL 0x08
# define AD7991_FLTR 0x04
# define AD7991_BIT_TRIAL_DELAY 0x02
# define AD7991_SAMPLE_DELAY 0x01
/*
* AD7992 , AD7993 , AD7994 , AD7997 and AD7998 defines
*/
2014-12-06 08:54:00 +03:00
# define AD7998_FLTR BIT(3)
# define AD7998_ALERT_EN BIT(2)
# define AD7998_BUSY_ALERT BIT(1)
# define AD7998_BUSY_ALERT_POL BIT(0)
2014-10-03 13:31:00 +04:00
# define AD7998_CONV_RES_REG 0x0
# define AD7998_ALERT_STAT_REG 0x1
# define AD7998_CONF_REG 0x2
# define AD7998_CYCLE_TMR_REG 0x3
# define AD7998_DATALOW_REG(x) ((x) * 3 + 0x4)
# define AD7998_DATAHIGH_REG(x) ((x) * 3 + 0x5)
# define AD7998_HYST_REG(x) ((x) * 3 + 0x6)
2014-12-06 08:54:00 +03:00
# define AD7998_CYC_MASK GENMASK(2, 0)
2014-10-03 13:31:00 +04:00
# define AD7998_CYC_DIS 0x0
# define AD7998_CYC_TCONF_32 0x1
# define AD7998_CYC_TCONF_64 0x2
# define AD7998_CYC_TCONF_128 0x3
# define AD7998_CYC_TCONF_256 0x4
# define AD7998_CYC_TCONF_512 0x5
# define AD7998_CYC_TCONF_1024 0x6
# define AD7998_CYC_TCONF_2048 0x7
# define AD7998_ALERT_STAT_CLEAR 0xFF
/*
* AD7997 and AD7997 defines
*/
2014-12-06 08:54:00 +03:00
# define AD7997_8_READ_SINGLE BIT(7)
# define AD7997_8_READ_SEQUENCE (BIT(6) | BIT(5) | BIT(4))
2014-10-03 13:31:00 +04:00
enum {
ad7991 ,
ad7995 ,
ad7999 ,
ad7992 ,
ad7993 ,
ad7994 ,
ad7997 ,
ad7998
} ;
/**
2014-12-06 08:54:00 +03:00
* struct ad799x_chip_config - chip specific information
2014-10-03 13:31:00 +04:00
* @ channel : channel specification
* @ default_config : device default configuration
2014-12-06 08:54:00 +03:00
* @ info : pointer to iio_info struct
2014-10-03 13:31:00 +04:00
*/
2014-12-06 08:54:00 +03:00
struct ad799x_chip_config {
2014-12-06 08:54:00 +03:00
const struct iio_chan_spec channel [ 9 ] ;
2014-10-03 13:31:00 +04:00
u16 default_config ;
const struct iio_info * info ;
} ;
2014-12-06 08:54:00 +03:00
/**
* struct ad799x_chip_info - chip specific information
* @ num_channels : number of channels
* @ noirq_config : device configuration w / o IRQ
* @ irq_config : device configuration w / IRQ
*/
struct ad799x_chip_info {
int num_channels ;
const struct ad799x_chip_config noirq_config ;
const struct ad799x_chip_config irq_config ;
} ;
2014-10-03 13:31:00 +04:00
struct ad799x_state {
struct i2c_client * client ;
2014-12-06 08:54:00 +03:00
const struct ad799x_chip_config * chip_config ;
2014-10-03 13:31:00 +04:00
struct regulator * reg ;
struct regulator * vref ;
unsigned id ;
u16 config ;
u8 * rx_buf ;
unsigned int transfer_size ;
} ;
2014-12-06 08:54:00 +03:00
static int ad799x_write_config ( struct ad799x_state * st , u16 val )
{
switch ( st - > id ) {
case ad7997 :
case ad7998 :
return i2c_smbus_write_word_swapped ( st - > client , AD7998_CONF_REG ,
val ) ;
2014-11-26 13:35:35 +03:00
case ad7992 :
case ad7993 :
case ad7994 :
2014-12-06 08:54:00 +03:00
return i2c_smbus_write_byte_data ( st - > client , AD7998_CONF_REG ,
val ) ;
2014-11-26 13:35:35 +03:00
default :
/* Will be written when doing a conversion */
st - > config = val ;
return 0 ;
2014-12-06 08:54:00 +03:00
}
}
static int ad799x_read_config ( struct ad799x_state * st )
{
switch ( st - > id ) {
case ad7997 :
case ad7998 :
return i2c_smbus_read_word_swapped ( st - > client , AD7998_CONF_REG ) ;
2014-11-26 13:35:35 +03:00
case ad7992 :
case ad7993 :
case ad7994 :
2014-12-06 08:54:00 +03:00
return i2c_smbus_read_byte_data ( st - > client , AD7998_CONF_REG ) ;
2014-11-26 13:35:35 +03:00
default :
/* No readback support */
return st - > config ;
2014-12-06 08:54:00 +03:00
}
}
2014-10-03 13:31:00 +04:00
/**
* ad799x_trigger_handler ( ) bh of trigger launched polling to ring buffer
*
* Currently there is no option in this driver to disable the saving of
* timestamps within the ring .
* */
static irqreturn_t ad799x_trigger_handler ( int irq , void * p )
{
struct iio_poll_func * pf = p ;
struct iio_dev * indio_dev = pf - > indio_dev ;
struct ad799x_state * st = iio_priv ( indio_dev ) ;
int b_sent ;
u8 cmd ;
switch ( st - > id ) {
case ad7991 :
case ad7995 :
case ad7999 :
cmd = st - > config |
( * indio_dev - > active_scan_mask < < AD799X_CHANNEL_SHIFT ) ;
break ;
case ad7992 :
case ad7993 :
case ad7994 :
cmd = ( * indio_dev - > active_scan_mask < < AD799X_CHANNEL_SHIFT ) |
AD7998_CONV_RES_REG ;
break ;
case ad7997 :
case ad7998 :
cmd = AD7997_8_READ_SEQUENCE | AD7998_CONV_RES_REG ;
break ;
default :
cmd = 0 ;
}
b_sent = i2c_smbus_read_i2c_block_data ( st - > client ,
cmd , st - > transfer_size , st - > rx_buf ) ;
if ( b_sent < 0 )
goto out ;
iio_push_to_buffers_with_timestamp ( indio_dev , st - > rx_buf ,
2016-03-09 21:05:49 +03:00
iio_get_time_ns ( indio_dev ) ) ;
2014-10-03 13:31:00 +04:00
out :
iio_trigger_notify_done ( indio_dev - > trig ) ;
return IRQ_HANDLED ;
}
2010-10-01 18:41:51 +04:00
2014-12-06 08:54:00 +03:00
static int ad799x_update_scan_mode ( struct iio_dev * indio_dev ,
2012-06-18 20:33:56 +04:00
const unsigned long * scan_mask )
2010-10-01 18:41:51 +04:00
{
2012-06-18 20:33:56 +04:00
struct ad799x_state * st = iio_priv ( indio_dev ) ;
2013-03-26 22:43:00 +04:00
kfree ( st - > rx_buf ) ;
st - > rx_buf = kmalloc ( indio_dev - > scan_bytes , GFP_KERNEL ) ;
if ( ! st - > rx_buf )
return - ENOMEM ;
st - > transfer_size = bitmap_weight ( scan_mask , indio_dev - > masklength ) * 2 ;
2012-06-18 20:33:56 +04:00
switch ( st - > id ) {
2014-12-06 08:54:00 +03:00
case ad7992 :
case ad7993 :
case ad7994 :
2012-06-18 20:33:56 +04:00
case ad7997 :
case ad7998 :
2014-12-06 08:54:00 +03:00
st - > config & = ~ ( GENMASK ( 7 , 0 ) < < AD799X_CHANNEL_SHIFT ) ;
st - > config | = ( * scan_mask < < AD799X_CHANNEL_SHIFT ) ;
return ad799x_write_config ( st , st - > config ) ;
2012-06-18 20:33:56 +04:00
default :
2014-12-06 08:54:00 +03:00
return 0 ;
2012-06-18 20:33:56 +04:00
}
2010-10-01 18:41:51 +04:00
}
2011-05-18 17:41:52 +04:00
static int ad799x_scan_direct ( struct ad799x_state * st , unsigned ch )
2010-10-01 18:41:51 +04:00
{
2011-05-18 17:41:52 +04:00
u8 cmd ;
2010-10-01 18:41:51 +04:00
2011-05-18 17:41:52 +04:00
switch ( st - > id ) {
case ad7991 :
case ad7995 :
case ad7999 :
2014-12-06 08:54:00 +03:00
cmd = st - > config | ( BIT ( ch ) < < AD799X_CHANNEL_SHIFT ) ;
2011-05-18 17:41:52 +04:00
break ;
case ad7992 :
case ad7993 :
case ad7994 :
2014-12-06 08:54:00 +03:00
cmd = BIT ( ch ) < < AD799X_CHANNEL_SHIFT ;
2011-05-18 17:41:52 +04:00
break ;
case ad7997 :
case ad7998 :
cmd = ( ch < < AD799X_CHANNEL_SHIFT ) | AD7997_8_READ_SINGLE ;
break ;
default :
return - EINVAL ;
2010-10-01 18:41:51 +04:00
}
2014-12-06 08:54:00 +03:00
return i2c_smbus_read_word_swapped ( st - > client , cmd ) ;
2010-10-01 18:41:51 +04:00
}
2011-10-06 20:14:37 +04:00
static int ad799x_read_raw ( struct iio_dev * indio_dev ,
2011-05-18 17:41:52 +04:00
struct iio_chan_spec const * chan ,
int * val ,
int * val2 ,
long m )
2010-10-01 18:41:51 +04:00
{
2011-05-18 17:41:52 +04:00
int ret ;
2011-10-06 20:14:37 +04:00
struct ad799x_state * st = iio_priv ( indio_dev ) ;
2011-05-18 17:41:52 +04:00
switch ( m ) {
2012-04-15 20:41:18 +04:00
case IIO_CHAN_INFO_RAW :
2016-05-24 22:20:24 +03:00
ret = iio_device_claim_direct_mode ( indio_dev ) ;
if ( ret )
return ret ;
ret = ad799x_scan_direct ( st , chan - > scan_index ) ;
iio_device_release_direct_mode ( indio_dev ) ;
2010-10-01 18:41:51 +04:00
if ( ret < 0 )
2011-05-18 17:41:52 +04:00
return ret ;
2011-09-30 13:05:32 +04:00
* val = ( ret > > chan - > scan_type . shift ) &
2014-12-06 08:54:00 +03:00
GENMASK ( chan - > scan_type . realbits - 1 , 0 ) ;
2011-05-18 17:41:52 +04:00
return IIO_VAL_INT ;
2011-10-26 20:41:36 +04:00
case IIO_CHAN_INFO_SCALE :
2014-02-16 16:02:00 +04:00
ret = regulator_get_voltage ( st - > vref ) ;
if ( ret < 0 )
return ret ;
* val = ret / 1000 ;
2013-09-28 13:31:00 +04:00
* val2 = chan - > scan_type . realbits ;
return IIO_VAL_FRACTIONAL_LOG2 ;
2010-10-01 18:41:51 +04:00
}
2011-05-18 17:41:52 +04:00
return - EINVAL ;
2010-10-01 18:41:51 +04:00
}
2011-09-30 13:05:33 +04:00
static const unsigned int ad7998_frequencies [ ] = {
[ AD7998_CYC_DIS ] = 0 ,
[ AD7998_CYC_TCONF_32 ] = 15625 ,
[ AD7998_CYC_TCONF_64 ] = 7812 ,
[ AD7998_CYC_TCONF_128 ] = 3906 ,
[ AD7998_CYC_TCONF_512 ] = 976 ,
[ AD7998_CYC_TCONF_1024 ] = 488 ,
[ AD7998_CYC_TCONF_2048 ] = 244 ,
} ;
2014-12-06 08:54:00 +03:00
2010-10-01 18:41:51 +04:00
static ssize_t ad799x_read_frequency ( struct device * dev ,
struct device_attribute * attr ,
char * buf )
{
2012-05-12 17:39:42 +04:00
struct iio_dev * indio_dev = dev_to_iio_dev ( dev ) ;
2011-10-06 20:14:37 +04:00
struct ad799x_state * st = iio_priv ( indio_dev ) ;
2010-10-01 18:41:51 +04:00
2014-12-06 08:54:00 +03:00
int ret = i2c_smbus_read_byte_data ( st - > client , AD7998_CYCLE_TMR_REG ) ;
if ( ret < 0 )
2010-10-01 18:41:51 +04:00
return ret ;
2014-12-06 08:54:00 +03:00
return sprintf ( buf , " %u \n " , ad7998_frequencies [ ret & AD7998_CYC_MASK ] ) ;
2010-10-01 18:41:51 +04:00
}
static ssize_t ad799x_write_frequency ( struct device * dev ,
struct device_attribute * attr ,
const char * buf ,
size_t len )
{
2012-05-12 17:39:42 +04:00
struct iio_dev * indio_dev = dev_to_iio_dev ( dev ) ;
2011-10-06 20:14:37 +04:00
struct ad799x_state * st = iio_priv ( indio_dev ) ;
2010-10-01 18:41:51 +04:00
long val ;
2011-09-30 13:05:33 +04:00
int ret , i ;
2010-10-01 18:41:51 +04:00
2013-05-07 00:04:41 +04:00
ret = kstrtol ( buf , 10 , & val ) ;
2010-10-01 18:41:51 +04:00
if ( ret )
return ret ;
2011-10-06 20:14:37 +04:00
mutex_lock ( & indio_dev - > mlock ) ;
2014-12-06 08:54:00 +03:00
ret = i2c_smbus_read_byte_data ( st - > client , AD7998_CYCLE_TMR_REG ) ;
if ( ret < 0 )
2010-10-01 18:41:51 +04:00
goto error_ret_mutex ;
/* Wipe the bits clean */
2014-12-06 08:54:00 +03:00
ret & = ~ AD7998_CYC_MASK ;
2010-10-01 18:41:51 +04:00
2011-09-30 13:05:33 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( ad7998_frequencies ) ; i + + )
if ( val = = ad7998_frequencies [ i ] )
break ;
if ( i = = ARRAY_SIZE ( ad7998_frequencies ) ) {
2010-10-01 18:41:51 +04:00
ret = - EINVAL ;
goto error_ret_mutex ;
}
2014-12-06 08:54:00 +03:00
ret = i2c_smbus_write_byte_data ( st - > client , AD7998_CYCLE_TMR_REG ,
ret | i ) ;
if ( ret < 0 )
goto error_ret_mutex ;
ret = len ;
2010-10-01 18:41:51 +04:00
error_ret_mutex :
2011-10-06 20:14:37 +04:00
mutex_unlock ( & indio_dev - > mlock ) ;
2010-10-01 18:41:51 +04:00
2014-12-06 08:54:00 +03:00
return ret ;
2010-10-01 18:41:51 +04:00
}
2011-10-06 20:14:37 +04:00
static int ad799x_read_event_config ( struct iio_dev * indio_dev ,
2013-10-07 18:11:00 +04:00
const struct iio_chan_spec * chan ,
enum iio_event_type type ,
enum iio_event_direction dir )
2011-09-30 13:05:35 +04:00
{
2014-12-06 08:54:00 +03:00
struct ad799x_state * st = iio_priv ( indio_dev ) ;
if ( ! ( st - > config & AD7998_ALERT_EN ) )
return 0 ;
if ( ( st - > config > > AD799X_CHANNEL_SHIFT ) & BIT ( chan - > scan_index ) )
return 1 ;
return 0 ;
2011-09-30 13:05:35 +04:00
}
2014-12-06 08:54:00 +03:00
static int ad799x_write_event_config ( struct iio_dev * indio_dev ,
const struct iio_chan_spec * chan ,
enum iio_event_type type ,
enum iio_event_direction dir ,
int state )
{
struct ad799x_state * st = iio_priv ( indio_dev ) ;
int ret ;
2016-05-24 22:20:24 +03:00
ret = iio_device_claim_direct_mode ( indio_dev ) ;
if ( ret )
return ret ;
2014-12-06 08:54:00 +03:00
if ( state )
st - > config | = BIT ( chan - > scan_index ) < < AD799X_CHANNEL_SHIFT ;
else
st - > config & = ~ ( BIT ( chan - > scan_index ) < < AD799X_CHANNEL_SHIFT ) ;
if ( st - > config > > AD799X_CHANNEL_SHIFT )
st - > config | = AD7998_ALERT_EN ;
else
st - > config & = ~ AD7998_ALERT_EN ;
ret = ad799x_write_config ( st , st - > config ) ;
2016-05-24 22:20:24 +03:00
iio_device_release_direct_mode ( indio_dev ) ;
2014-12-06 08:54:00 +03:00
return ret ;
}
2013-10-07 18:11:00 +04:00
static unsigned int ad799x_threshold_reg ( const struct iio_chan_spec * chan ,
enum iio_event_direction dir ,
enum iio_event_info info )
2013-10-07 18:11:00 +04:00
{
2013-10-07 18:11:00 +04:00
switch ( info ) {
case IIO_EV_INFO_VALUE :
if ( dir = = IIO_EV_DIR_FALLING )
return AD7998_DATALOW_REG ( chan - > channel ) ;
else
return AD7998_DATAHIGH_REG ( chan - > channel ) ;
case IIO_EV_INFO_HYSTERESIS :
return AD7998_HYST_REG ( chan - > channel ) ;
default :
return - EINVAL ;
}
return 0 ;
2013-10-07 18:11:00 +04:00
}
2011-09-30 13:05:35 +04:00
static int ad799x_write_event_value ( struct iio_dev * indio_dev ,
2013-10-07 18:11:00 +04:00
const struct iio_chan_spec * chan ,
enum iio_event_type type ,
enum iio_event_direction dir ,
enum iio_event_info info ,
int val , int val2 )
2011-09-30 13:05:35 +04:00
{
int ret ;
struct ad799x_state * st = iio_priv ( indio_dev ) ;
2014-12-06 08:54:00 +03:00
if ( val < 0 | | val > GENMASK ( chan - > scan_type . realbits - 1 , 0 ) )
2014-12-06 08:54:00 +03:00
return - EINVAL ;
2011-09-30 13:05:35 +04:00
mutex_lock ( & indio_dev - > mlock ) ;
2014-12-06 08:54:00 +03:00
ret = i2c_smbus_write_word_swapped ( st - > client ,
ad799x_threshold_reg ( chan , dir , info ) ,
2014-12-06 08:54:00 +03:00
val < < chan - > scan_type . shift ) ;
2011-09-30 13:05:35 +04:00
mutex_unlock ( & indio_dev - > mlock ) ;
return ret ;
}
static int ad799x_read_event_value ( struct iio_dev * indio_dev ,
2013-10-07 18:11:00 +04:00
const struct iio_chan_spec * chan ,
enum iio_event_type type ,
enum iio_event_direction dir ,
enum iio_event_info info ,
int * val , int * val2 )
2011-09-30 13:05:35 +04:00
{
int ret ;
struct ad799x_state * st = iio_priv ( indio_dev ) ;
mutex_lock ( & indio_dev - > mlock ) ;
2014-12-06 08:54:00 +03:00
ret = i2c_smbus_read_word_swapped ( st - > client ,
ad799x_threshold_reg ( chan , dir , info ) ) ;
2011-09-30 13:05:35 +04:00
mutex_unlock ( & indio_dev - > mlock ) ;
if ( ret < 0 )
return ret ;
2014-12-06 08:54:00 +03:00
* val = ( ret > > chan - > scan_type . shift ) &
2016-04-14 22:36:38 +03:00
GENMASK ( chan - > scan_type . realbits - 1 , 0 ) ;
2011-09-30 13:05:35 +04:00
2013-10-07 18:11:00 +04:00
return IIO_VAL_INT ;
2011-09-30 13:05:35 +04:00
}
2011-05-18 17:41:15 +04:00
static irqreturn_t ad799x_event_handler ( int irq , void * private )
2010-10-01 18:41:51 +04:00
{
2011-05-18 17:41:15 +04:00
struct iio_dev * indio_dev = private ;
2011-06-27 16:07:20 +04:00
struct ad799x_state * st = iio_priv ( private ) ;
2011-05-18 17:41:15 +04:00
int i , ret ;
2010-10-01 18:41:51 +04:00
2014-12-06 08:54:00 +03:00
ret = i2c_smbus_read_byte_data ( st - > client , AD7998_ALERT_STAT_REG ) ;
if ( ret < = 0 )
2012-07-04 20:09:00 +04:00
goto done ;
2010-10-01 18:41:51 +04:00
2014-12-06 08:54:00 +03:00
if ( i2c_smbus_write_byte_data ( st - > client , AD7998_ALERT_STAT_REG ,
AD7998_ALERT_STAT_CLEAR ) < 0 )
2012-07-04 20:09:00 +04:00
goto done ;
2010-10-01 18:41:51 +04:00
for ( i = 0 ; i < 8 ; i + + ) {
2014-12-06 08:54:00 +03:00
if ( ret & BIT ( i ) )
2011-08-30 15:41:06 +04:00
iio_push_event ( indio_dev ,
2011-05-18 17:41:15 +04:00
i & 0x1 ?
2011-09-27 12:56:41 +04:00
IIO_UNMOD_EVENT_CODE ( IIO_VOLTAGE ,
2011-08-12 20:08:43 +04:00
( i > > 1 ) ,
IIO_EV_TYPE_THRESH ,
IIO_EV_DIR_RISING ) :
2011-09-27 12:56:41 +04:00
IIO_UNMOD_EVENT_CODE ( IIO_VOLTAGE ,
2011-08-12 20:08:43 +04:00
( i > > 1 ) ,
IIO_EV_TYPE_THRESH ,
IIO_EV_DIR_FALLING ) ,
2016-03-09 21:05:49 +03:00
iio_get_time_ns ( indio_dev ) ) ;
2010-10-01 18:41:51 +04:00
}
2012-07-04 20:09:00 +04:00
done :
2011-05-18 17:41:15 +04:00
return IRQ_HANDLED ;
2010-10-01 18:41:51 +04:00
}
static IIO_DEV_ATTR_SAMP_FREQ ( S_IWUSR | S_IRUGO ,
ad799x_read_frequency ,
ad799x_write_frequency ) ;
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL ( " 15625 7812 3906 1953 976 488 244 0 " ) ;
2013-10-07 18:11:00 +04:00
static struct attribute * ad799x_event_attributes [ ] = {
2010-10-01 18:41:51 +04:00
& iio_dev_attr_sampling_frequency . dev_attr . attr ,
& iio_const_attr_sampling_frequency_available . dev_attr . attr ,
NULL ,
} ;
2017-03-28 23:07:45 +03:00
static const struct attribute_group ad799x_event_attrs_group = {
2013-10-07 18:11:00 +04:00
. attrs = ad799x_event_attributes ,
2010-10-01 18:41:51 +04:00
} ;
2011-05-18 17:42:37 +04:00
static const struct iio_info ad7991_info = {
. read_raw = & ad799x_read_raw ,
. driver_module = THIS_MODULE ,
2016-07-11 14:54:17 +03:00
. update_scan_mode = ad799x_update_scan_mode ,
2011-05-18 17:42:37 +04:00
} ;
2014-12-06 08:54:00 +03:00
static const struct iio_info ad7993_4_7_8_noirq_info = {
. read_raw = & ad799x_read_raw ,
. driver_module = THIS_MODULE ,
2014-12-06 08:54:00 +03:00
. update_scan_mode = ad799x_update_scan_mode ,
2014-12-06 08:54:00 +03:00
} ;
static const struct iio_info ad7993_4_7_8_irq_info = {
2011-05-18 17:42:37 +04:00
. read_raw = & ad799x_read_raw ,
2013-10-07 18:11:00 +04:00
. event_attrs = & ad799x_event_attrs_group ,
2013-12-07 14:45:00 +04:00
. read_event_config = & ad799x_read_event_config ,
2014-12-06 08:54:00 +03:00
. write_event_config = & ad799x_write_event_config ,
2013-12-07 14:45:00 +04:00
. read_event_value = & ad799x_read_event_value ,
. write_event_value = & ad799x_write_event_value ,
2011-05-18 17:42:37 +04:00
. driver_module = THIS_MODULE ,
2014-12-06 08:54:00 +03:00
. update_scan_mode = ad799x_update_scan_mode ,
2011-05-18 17:42:37 +04:00
} ;
2013-10-07 18:11:00 +04:00
static const struct iio_event_spec ad799x_events [ ] = {
{
. type = IIO_EV_TYPE_THRESH ,
. dir = IIO_EV_DIR_RISING ,
. mask_separate = BIT ( IIO_EV_INFO_VALUE ) |
BIT ( IIO_EV_INFO_ENABLE ) ,
} , {
. type = IIO_EV_TYPE_THRESH ,
. dir = IIO_EV_DIR_FALLING ,
2014-08-02 03:07:00 +04:00
. mask_separate = BIT ( IIO_EV_INFO_VALUE ) |
2013-10-07 18:11:00 +04:00
BIT ( IIO_EV_INFO_ENABLE ) ,
2013-10-07 18:11:00 +04:00
} , {
. type = IIO_EV_TYPE_THRESH ,
. dir = IIO_EV_DIR_EITHER ,
. mask_separate = BIT ( IIO_EV_INFO_HYSTERESIS ) ,
2013-10-07 18:11:00 +04:00
} ,
} ;
2011-09-30 13:05:35 +04:00
2013-10-07 18:11:00 +04:00
# define _AD799X_CHANNEL(_index, _realbits, _ev_spec, _num_ev_spec) { \
2013-03-26 22:43:00 +04:00
. type = IIO_VOLTAGE , \
. indexed = 1 , \
. channel = ( _index ) , \
. info_mask_separate = BIT ( IIO_CHAN_INFO_RAW ) , \
2013-03-26 22:43:00 +04:00
. info_mask_shared_by_type = BIT ( IIO_CHAN_INFO_SCALE ) , \
2013-03-26 22:43:00 +04:00
. scan_index = ( _index ) , \
2013-12-11 22:45:00 +04:00
. scan_type = { \
. sign = ' u ' , \
. realbits = ( _realbits ) , \
. storagebits = 16 , \
. shift = 12 - ( _realbits ) , \
. endianness = IIO_BE , \
} , \
2013-10-07 18:11:00 +04:00
. event_spec = _ev_spec , \
. num_event_specs = _num_ev_spec , \
2013-03-26 22:43:00 +04:00
}
2013-10-07 18:11:00 +04:00
# define AD799X_CHANNEL(_index, _realbits) \
_AD799X_CHANNEL ( _index , _realbits , NULL , 0 )
# define AD799X_CHANNEL_WITH_EVENTS(_index, _realbits) \
_AD799X_CHANNEL ( _index , _realbits , ad799x_events , \
ARRAY_SIZE ( ad799x_events ) )
2010-10-01 18:41:51 +04:00
static const struct ad799x_chip_info ad799x_chip_info_tbl [ ] = {
[ ad7991 ] = {
2011-05-18 17:41:52 +04:00
. num_channels = 5 ,
2014-12-06 08:54:00 +03:00
. noirq_config = {
. channel = {
AD799X_CHANNEL ( 0 , 12 ) ,
AD799X_CHANNEL ( 1 , 12 ) ,
AD799X_CHANNEL ( 2 , 12 ) ,
AD799X_CHANNEL ( 3 , 12 ) ,
IIO_CHAN_SOFT_TIMESTAMP ( 4 ) ,
} ,
. info = & ad7991_info ,
} ,
2010-10-01 18:41:51 +04:00
} ,
[ ad7995 ] = {
2011-05-18 17:41:52 +04:00
. num_channels = 5 ,
2014-12-06 08:54:00 +03:00
. noirq_config = {
. channel = {
AD799X_CHANNEL ( 0 , 10 ) ,
AD799X_CHANNEL ( 1 , 10 ) ,
AD799X_CHANNEL ( 2 , 10 ) ,
AD799X_CHANNEL ( 3 , 10 ) ,
IIO_CHAN_SOFT_TIMESTAMP ( 4 ) ,
} ,
. info = & ad7991_info ,
} ,
2010-10-01 18:41:51 +04:00
} ,
[ ad7999 ] = {
2011-05-18 17:41:52 +04:00
. num_channels = 5 ,
2014-12-06 08:54:00 +03:00
. noirq_config = {
. channel = {
AD799X_CHANNEL ( 0 , 8 ) ,
AD799X_CHANNEL ( 1 , 8 ) ,
AD799X_CHANNEL ( 2 , 8 ) ,
AD799X_CHANNEL ( 3 , 8 ) ,
IIO_CHAN_SOFT_TIMESTAMP ( 4 ) ,
} ,
. info = & ad7991_info ,
} ,
2010-10-01 18:41:51 +04:00
} ,
[ ad7992 ] = {
2011-05-18 17:41:52 +04:00
. num_channels = 3 ,
2014-12-06 08:54:00 +03:00
. noirq_config = {
. channel = {
AD799X_CHANNEL ( 0 , 12 ) ,
AD799X_CHANNEL ( 1 , 12 ) ,
IIO_CHAN_SOFT_TIMESTAMP ( 3 ) ,
} ,
. info = & ad7993_4_7_8_noirq_info ,
} ,
. irq_config = {
. channel = {
AD799X_CHANNEL_WITH_EVENTS ( 0 , 12 ) ,
AD799X_CHANNEL_WITH_EVENTS ( 1 , 12 ) ,
IIO_CHAN_SOFT_TIMESTAMP ( 3 ) ,
} ,
2014-12-06 08:54:00 +03:00
. default_config = AD7998_ALERT_EN | AD7998_BUSY_ALERT ,
2014-12-06 08:54:00 +03:00
. info = & ad7993_4_7_8_irq_info ,
} ,
2010-10-01 18:41:51 +04:00
} ,
[ ad7993 ] = {
2011-05-18 17:41:52 +04:00
. num_channels = 5 ,
2014-12-06 08:54:00 +03:00
. noirq_config = {
. channel = {
AD799X_CHANNEL ( 0 , 10 ) ,
AD799X_CHANNEL ( 1 , 10 ) ,
AD799X_CHANNEL ( 2 , 10 ) ,
AD799X_CHANNEL ( 3 , 10 ) ,
IIO_CHAN_SOFT_TIMESTAMP ( 4 ) ,
} ,
. info = & ad7993_4_7_8_noirq_info ,
} ,
. irq_config = {
. channel = {
AD799X_CHANNEL_WITH_EVENTS ( 0 , 10 ) ,
AD799X_CHANNEL_WITH_EVENTS ( 1 , 10 ) ,
AD799X_CHANNEL_WITH_EVENTS ( 2 , 10 ) ,
AD799X_CHANNEL_WITH_EVENTS ( 3 , 10 ) ,
IIO_CHAN_SOFT_TIMESTAMP ( 4 ) ,
} ,
2014-12-06 08:54:00 +03:00
. default_config = AD7998_ALERT_EN | AD7998_BUSY_ALERT ,
2014-12-06 08:54:00 +03:00
. info = & ad7993_4_7_8_irq_info ,
} ,
2010-10-01 18:41:51 +04:00
} ,
[ ad7994 ] = {
2011-05-18 17:41:52 +04:00
. num_channels = 5 ,
2014-12-06 08:54:00 +03:00
. noirq_config = {
. channel = {
AD799X_CHANNEL ( 0 , 12 ) ,
AD799X_CHANNEL ( 1 , 12 ) ,
AD799X_CHANNEL ( 2 , 12 ) ,
AD799X_CHANNEL ( 3 , 12 ) ,
IIO_CHAN_SOFT_TIMESTAMP ( 4 ) ,
} ,
. info = & ad7993_4_7_8_noirq_info ,
} ,
. irq_config = {
. channel = {
AD799X_CHANNEL_WITH_EVENTS ( 0 , 12 ) ,
AD799X_CHANNEL_WITH_EVENTS ( 1 , 12 ) ,
AD799X_CHANNEL_WITH_EVENTS ( 2 , 12 ) ,
AD799X_CHANNEL_WITH_EVENTS ( 3 , 12 ) ,
IIO_CHAN_SOFT_TIMESTAMP ( 4 ) ,
} ,
2014-12-06 08:54:00 +03:00
. default_config = AD7998_ALERT_EN | AD7998_BUSY_ALERT ,
2014-12-06 08:54:00 +03:00
. info = & ad7993_4_7_8_irq_info ,
} ,
2010-10-01 18:41:51 +04:00
} ,
[ ad7997 ] = {
2011-05-18 17:41:52 +04:00
. num_channels = 9 ,
2014-12-06 08:54:00 +03:00
. noirq_config = {
. channel = {
AD799X_CHANNEL ( 0 , 10 ) ,
AD799X_CHANNEL ( 1 , 10 ) ,
AD799X_CHANNEL ( 2 , 10 ) ,
AD799X_CHANNEL ( 3 , 10 ) ,
AD799X_CHANNEL ( 4 , 10 ) ,
AD799X_CHANNEL ( 5 , 10 ) ,
AD799X_CHANNEL ( 6 , 10 ) ,
AD799X_CHANNEL ( 7 , 10 ) ,
IIO_CHAN_SOFT_TIMESTAMP ( 8 ) ,
} ,
. info = & ad7993_4_7_8_noirq_info ,
} ,
. irq_config = {
. channel = {
AD799X_CHANNEL_WITH_EVENTS ( 0 , 10 ) ,
AD799X_CHANNEL_WITH_EVENTS ( 1 , 10 ) ,
AD799X_CHANNEL_WITH_EVENTS ( 2 , 10 ) ,
AD799X_CHANNEL_WITH_EVENTS ( 3 , 10 ) ,
AD799X_CHANNEL ( 4 , 10 ) ,
AD799X_CHANNEL ( 5 , 10 ) ,
AD799X_CHANNEL ( 6 , 10 ) ,
AD799X_CHANNEL ( 7 , 10 ) ,
IIO_CHAN_SOFT_TIMESTAMP ( 8 ) ,
} ,
2014-12-06 08:54:00 +03:00
. default_config = AD7998_ALERT_EN | AD7998_BUSY_ALERT ,
2014-12-06 08:54:00 +03:00
. info = & ad7993_4_7_8_irq_info ,
} ,
2010-10-01 18:41:51 +04:00
} ,
[ ad7998 ] = {
2011-05-18 17:41:52 +04:00
. num_channels = 9 ,
2014-12-06 08:54:00 +03:00
. noirq_config = {
. channel = {
AD799X_CHANNEL ( 0 , 12 ) ,
AD799X_CHANNEL ( 1 , 12 ) ,
AD799X_CHANNEL ( 2 , 12 ) ,
AD799X_CHANNEL ( 3 , 12 ) ,
AD799X_CHANNEL ( 4 , 12 ) ,
AD799X_CHANNEL ( 5 , 12 ) ,
AD799X_CHANNEL ( 6 , 12 ) ,
AD799X_CHANNEL ( 7 , 12 ) ,
IIO_CHAN_SOFT_TIMESTAMP ( 8 ) ,
} ,
. info = & ad7993_4_7_8_noirq_info ,
} ,
. irq_config = {
. channel = {
AD799X_CHANNEL_WITH_EVENTS ( 0 , 12 ) ,
AD799X_CHANNEL_WITH_EVENTS ( 1 , 12 ) ,
AD799X_CHANNEL_WITH_EVENTS ( 2 , 12 ) ,
AD799X_CHANNEL_WITH_EVENTS ( 3 , 12 ) ,
AD799X_CHANNEL ( 4 , 12 ) ,
AD799X_CHANNEL ( 5 , 12 ) ,
AD799X_CHANNEL ( 6 , 12 ) ,
AD799X_CHANNEL ( 7 , 12 ) ,
IIO_CHAN_SOFT_TIMESTAMP ( 8 ) ,
} ,
2014-12-06 08:54:00 +03:00
. default_config = AD7998_ALERT_EN | AD7998_BUSY_ALERT ,
2014-12-06 08:54:00 +03:00
. info = & ad7993_4_7_8_irq_info ,
} ,
2010-10-01 18:41:51 +04:00
} ,
} ;
2012-11-19 22:21:57 +04:00
static int ad799x_probe ( struct i2c_client * client ,
2010-10-01 18:41:51 +04:00
const struct i2c_device_id * id )
{
2011-09-02 20:14:40 +04:00
int ret ;
2011-05-18 17:41:53 +04:00
struct ad799x_state * st ;
2013-08-31 21:12:00 +04:00
struct iio_dev * indio_dev ;
2014-12-06 08:54:00 +03:00
const struct ad799x_chip_info * chip_info =
& ad799x_chip_info_tbl [ id - > driver_data ] ;
2011-05-18 17:41:53 +04:00
2013-08-31 21:12:00 +04:00
indio_dev = devm_iio_device_alloc ( & client - > dev , sizeof ( * st ) ) ;
2011-05-18 17:41:53 +04:00
if ( indio_dev = = NULL )
return - ENOMEM ;
2010-10-01 18:41:51 +04:00
2011-05-18 17:41:53 +04:00
st = iio_priv ( indio_dev ) ;
2010-10-01 18:41:51 +04:00
/* this is only used for device removal purposes */
2011-05-18 17:41:53 +04:00
i2c_set_clientdata ( client , indio_dev ) ;
2010-10-01 18:41:51 +04:00
st - > id = id - > driver_data ;
2014-12-06 08:54:00 +03:00
if ( client - > irq > 0 & & chip_info - > irq_config . info )
st - > chip_config = & chip_info - > irq_config ;
else
st - > chip_config = & chip_info - > noirq_config ;
2010-10-01 18:41:51 +04:00
/* TODO: Add pdata options for filtering and bit delay */
2013-08-31 21:12:00 +04:00
st - > reg = devm_regulator_get ( & client - > dev , " vcc " ) ;
2014-02-16 16:02:00 +04:00
if ( IS_ERR ( st - > reg ) )
return PTR_ERR ( st - > reg ) ;
ret = regulator_enable ( st - > reg ) ;
if ( ret )
return ret ;
st - > vref = devm_regulator_get ( & client - > dev , " vref " ) ;
if ( IS_ERR ( st - > vref ) ) {
ret = PTR_ERR ( st - > vref ) ;
goto error_disable_reg ;
2010-10-01 18:41:51 +04:00
}
2014-02-16 16:02:00 +04:00
ret = regulator_enable ( st - > vref ) ;
if ( ret )
goto error_disable_reg ;
2010-10-01 18:41:51 +04:00
st - > client = client ;
2011-05-18 17:41:53 +04:00
indio_dev - > dev . parent = & client - > dev ;
2016-07-03 03:26:33 +03:00
indio_dev - > dev . of_node = client - > dev . of_node ;
2011-05-18 17:41:53 +04:00
indio_dev - > name = id - > name ;
2014-12-06 08:54:00 +03:00
indio_dev - > info = st - > chip_config - > info ;
2011-05-18 17:42:37 +04:00
2011-05-18 17:41:53 +04:00
indio_dev - > modes = INDIO_DIRECT_MODE ;
2014-12-06 08:54:00 +03:00
indio_dev - > channels = st - > chip_config - > channel ;
indio_dev - > num_channels = chip_info - > num_channels ;
2011-05-18 17:41:53 +04:00
2014-12-06 08:54:00 +03:00
ret = ad799x_write_config ( st , st - > chip_config - > default_config ) ;
if ( ret < 0 )
goto error_disable_reg ;
ret = ad799x_read_config ( st ) ;
if ( ret < 0 )
goto error_disable_reg ;
st - > config = ret ;
2014-10-03 13:31:00 +04:00
ret = iio_triggered_buffer_setup ( indio_dev , NULL ,
& ad799x_trigger_handler , NULL ) ;
2010-10-01 18:41:51 +04:00
if ( ret )
2014-05-01 01:05:00 +04:00
goto error_disable_vref ;
2010-10-01 18:41:51 +04:00
2011-05-18 17:42:37 +04:00
if ( client - > irq > 0 ) {
2014-01-02 03:04:00 +04:00
ret = devm_request_threaded_irq ( & client - > dev ,
client - > irq ,
NULL ,
ad799x_event_handler ,
IRQF_TRIGGER_FALLING |
IRQF_ONESHOT ,
client - > name ,
indio_dev ) ;
2010-10-01 18:41:51 +04:00
if ( ret )
goto error_cleanup_ring ;
}
2011-09-02 20:14:40 +04:00
ret = iio_device_register ( indio_dev ) ;
if ( ret )
2014-01-02 03:04:00 +04:00
goto error_cleanup_ring ;
2010-10-01 18:41:51 +04:00
return 0 ;
2011-05-18 17:41:53 +04:00
2010-10-01 18:41:51 +04:00
error_cleanup_ring :
2014-10-03 13:31:00 +04:00
iio_triggered_buffer_cleanup ( indio_dev ) ;
2014-05-01 01:05:00 +04:00
error_disable_vref :
regulator_disable ( st - > vref ) ;
2010-10-01 18:41:51 +04:00
error_disable_reg :
2014-05-01 01:05:00 +04:00
regulator_disable ( st - > reg ) ;
2011-05-18 17:41:53 +04:00
2010-10-01 18:41:51 +04:00
return ret ;
}
2012-11-19 22:26:37 +04:00
static int ad799x_remove ( struct i2c_client * client )
2010-10-01 18:41:51 +04:00
{
2011-05-18 17:41:53 +04:00
struct iio_dev * indio_dev = i2c_get_clientdata ( client ) ;
struct ad799x_state * st = iio_priv ( indio_dev ) ;
2010-10-01 18:41:51 +04:00
2011-10-14 17:46:58 +04:00
iio_device_unregister ( indio_dev ) ;
2010-10-01 18:41:51 +04:00
2014-10-03 13:31:00 +04:00
iio_triggered_buffer_cleanup ( indio_dev ) ;
2014-05-01 01:05:00 +04:00
regulator_disable ( st - > vref ) ;
regulator_disable ( st - > reg ) ;
2013-03-26 22:43:00 +04:00
kfree ( st - > rx_buf ) ;
2010-10-01 18:41:51 +04:00
return 0 ;
}
static const struct i2c_device_id ad799x_id [ ] = {
{ " ad7991 " , ad7991 } ,
{ " ad7995 " , ad7995 } ,
{ " ad7999 " , ad7999 } ,
{ " ad7992 " , ad7992 } ,
{ " ad7993 " , ad7993 } ,
{ " ad7994 " , ad7994 } ,
{ " ad7997 " , ad7997 } ,
{ " ad7998 " , ad7998 } ,
{ }
} ;
MODULE_DEVICE_TABLE ( i2c , ad799x_id ) ;
static struct i2c_driver ad799x_driver = {
. driver = {
. name = " ad799x " ,
} ,
. probe = ad799x_probe ,
2012-11-19 22:21:38 +04:00
. remove = ad799x_remove ,
2010-10-01 18:41:51 +04:00
. id_table = ad799x_id ,
} ;
2011-11-16 13:13:38 +04:00
module_i2c_driver ( ad799x_driver ) ;
2010-10-01 18:41:51 +04:00
MODULE_AUTHOR ( " Michael Hennerich <hennerich@blackfin.uclinux.org> " ) ;
MODULE_DESCRIPTION ( " Analog Devices AD799x ADC " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;