2018-01-14 23:32:40 +03:00
// SPDX-License-Identifier: GPL-2.0
2010-10-11 20:05:37 +04:00
/*
2018-01-14 23:32:39 +03:00
* Analog Devices AD7466 / 7 / 8 AD7476 / 5 / 7 / 8 ( A ) SPI ADC driver
* TI ADC081S / ADC101S / ADC121S 8 / 10 / 12 - bit SPI ADC driver
2010-10-11 20:05:37 +04:00
*
* Copyright 2010 Analog Devices Inc .
*/
# include <linux/device.h>
# include <linux/kernel.h>
# include <linux/slab.h>
# include <linux/sysfs.h>
# include <linux/spi/spi.h>
# include <linux/regulator/consumer.h>
2020-03-11 11:43:25 +03:00
# include <linux/gpio/consumer.h>
2010-10-11 20:05:37 +04:00
# include <linux/err.h>
2011-07-03 23:49:50 +04:00
# include <linux/module.h>
2014-12-06 09:00:00 +03:00
# include <linux/bitops.h>
2020-03-11 11:43:25 +03:00
# include <linux/delay.h>
2010-10-11 20:05:37 +04:00
2012-04-25 18:54:58 +04:00
# include <linux/iio/iio.h>
# include <linux/iio/sysfs.h>
# include <linux/iio/buffer.h>
2012-09-10 12:34:00 +04:00
# include <linux/iio/trigger_consumer.h>
# include <linux/iio/triggered_buffer.h>
2010-10-11 20:05:37 +04:00
2012-09-17 16:26:00 +04:00
struct ad7476_state ;
2012-09-10 12:34:00 +04:00
struct ad7476_chip_info {
unsigned int int_vref_uv ;
struct iio_chan_spec channel [ 2 ] ;
2020-03-11 11:43:26 +03:00
/* channels used when convst gpio is defined */
struct iio_chan_spec convst_channel [ 2 ] ;
2012-09-17 16:26:00 +04:00
void ( * reset ) ( struct ad7476_state * ) ;
2021-04-25 19:31:53 +03:00
bool has_vref ;
bool has_vdrive ;
2012-09-10 12:34:00 +04:00
} ;
struct ad7476_state {
struct spi_device * spi ;
const struct ad7476_chip_info * chip_info ;
2021-04-25 19:31:53 +03:00
struct regulator * ref_reg ;
2020-03-11 11:43:25 +03:00
struct gpio_desc * convst_gpio ;
2012-09-10 12:34:00 +04:00
struct spi_transfer xfer ;
struct spi_message msg ;
/*
2022-05-08 20:55:53 +03:00
* DMA ( thus cache coherency maintenance ) may require the
2012-09-10 12:34:00 +04:00
* transfer buffers to live in their own cache lines .
* Make the buffer large enough for one 16 bit sample and one 64 bit
* aligned 64 bit timestamp .
*/
2022-05-08 20:55:53 +03:00
unsigned char data [ ALIGN ( 2 , sizeof ( s64 ) ) + sizeof ( s64 ) ] __aligned ( IIO_DMA_MINALIGN ) ;
2012-09-10 12:34:00 +04:00
} ;
enum ad7476_supported_device_ids {
2021-04-25 19:31:53 +03:00
ID_AD7091 ,
2012-09-17 16:26:00 +04:00
ID_AD7091R ,
2021-04-25 19:31:53 +03:00
ID_AD7273 ,
ID_AD7274 ,
2012-09-10 13:33:00 +04:00
ID_AD7276 ,
ID_AD7277 ,
ID_AD7278 ,
2012-09-10 12:34:00 +04:00
ID_AD7466 ,
ID_AD7467 ,
ID_AD7468 ,
2021-04-25 19:31:53 +03:00
ID_AD7475 ,
2012-09-10 12:34:00 +04:00
ID_AD7495 ,
ID_AD7940 ,
2018-01-14 23:32:39 +03:00
ID_ADC081S ,
ID_ADC101S ,
ID_ADC121S ,
2019-02-04 15:44:41 +03:00
ID_ADS7866 ,
ID_ADS7867 ,
ID_ADS7868 ,
2020-12-16 11:36:39 +03:00
ID_LTC2314_14 ,
2012-09-10 12:34:00 +04:00
} ;
2020-03-11 11:43:25 +03:00
static void ad7091_convst ( struct ad7476_state * st )
{
if ( ! st - > convst_gpio )
return ;
gpiod_set_value ( st - > convst_gpio , 0 ) ;
udelay ( 1 ) ; /* CONVST pulse width: 10 ns min */
gpiod_set_value ( st - > convst_gpio , 1 ) ;
udelay ( 1 ) ; /* Conversion time: 650 ns max */
}
2012-09-10 12:34:00 +04:00
static irqreturn_t ad7476_trigger_handler ( int irq , void * p )
{
struct iio_poll_func * pf = p ;
struct iio_dev * indio_dev = pf - > indio_dev ;
struct ad7476_state * st = iio_priv ( indio_dev ) ;
int b_sent ;
2020-03-11 11:43:25 +03:00
ad7091_convst ( st ) ;
2012-09-10 12:34:00 +04:00
b_sent = spi_sync ( st - > spi , & st - > msg ) ;
if ( b_sent < 0 )
goto done ;
2013-09-19 16:59:00 +04:00
iio_push_to_buffers_with_timestamp ( indio_dev , st - > data ,
2016-03-09 21:05:49 +03:00
iio_get_time_ns ( indio_dev ) ) ;
2012-09-10 12:34:00 +04:00
done :
iio_trigger_notify_done ( indio_dev - > trig ) ;
return IRQ_HANDLED ;
}
2010-10-11 20:05:37 +04:00
2012-09-17 16:26:00 +04:00
static void ad7091_reset ( struct ad7476_state * st )
{
/* Any transfers with 8 scl cycles will reset the device */
spi_read ( st - > spi , st - > data , 1 ) ;
}
2010-10-11 20:05:37 +04:00
static int ad7476_scan_direct ( struct ad7476_state * st )
{
int ret ;
2020-03-11 11:43:26 +03:00
ad7091_convst ( st ) ;
2010-10-11 20:05:56 +04:00
ret = spi_sync ( st - > spi , & st - > msg ) ;
2010-10-11 20:05:37 +04:00
if ( ret )
return ret ;
2012-09-10 12:34:00 +04:00
return be16_to_cpup ( ( __be16 * ) st - > data ) ;
2010-10-11 20:05:37 +04:00
}
2011-10-06 20:14:37 +04:00
static int ad7476_read_raw ( struct iio_dev * indio_dev ,
2011-05-18 17:41:24 +04:00
struct iio_chan_spec const * chan ,
int * val ,
int * val2 ,
long m )
2010-10-11 20:05:37 +04:00
{
int ret ;
2011-10-06 20:14:37 +04:00
struct ad7476_state * st = iio_priv ( indio_dev ) ;
2012-09-10 12:34:00 +04:00
int scale_uv ;
2011-05-18 17:41:24 +04:00
switch ( m ) {
2012-04-15 20:41:18 +04:00
case IIO_CHAN_INFO_RAW :
2016-05-24 22:18:06 +03:00
ret = iio_device_claim_direct_mode ( indio_dev ) ;
if ( ret )
return ret ;
ret = ad7476_scan_direct ( st ) ;
iio_device_release_direct_mode ( indio_dev ) ;
2011-05-18 17:41:24 +04:00
if ( ret < 0 )
return ret ;
* val = ( ret > > st - > chip_info - > channel [ 0 ] . scan_type . shift ) &
2014-12-06 09:00:00 +03:00
GENMASK ( st - > chip_info - > channel [ 0 ] . scan_type . realbits - 1 , 0 ) ;
2011-05-18 17:41:24 +04:00
return IIO_VAL_INT ;
2011-10-26 20:41:36 +04:00
case IIO_CHAN_INFO_SCALE :
2021-04-25 19:31:53 +03:00
if ( st - > ref_reg ) {
scale_uv = regulator_get_voltage ( st - > ref_reg ) ;
2012-09-10 12:34:00 +04:00
if ( scale_uv < 0 )
return scale_uv ;
} else {
scale_uv = st - > chip_info - > int_vref_uv ;
}
2013-09-28 13:31:00 +04:00
* val = scale_uv / 1000 ;
* val2 = chan - > scan_type . realbits ;
return IIO_VAL_FRACTIONAL_LOG2 ;
2011-05-18 17:41:24 +04:00
}
return - EINVAL ;
2010-10-11 20:05:37 +04:00
}
2013-02-27 23:05:34 +04:00
# define _AD7476_CHAN(bits, _shift, _info_mask_sep) \
2012-04-13 13:42:55 +04:00
{ \
. type = IIO_VOLTAGE , \
. indexed = 1 , \
2013-02-27 23:05:34 +04:00
. info_mask_separate = _info_mask_sep , \
. info_mask_shared_by_type = BIT ( IIO_CHAN_INFO_SCALE ) , \
2012-04-13 13:42:55 +04:00
. scan_type = { \
. sign = ' u ' , \
2012-09-10 12:34:00 +04:00
. realbits = ( bits ) , \
2012-04-13 13:42:55 +04:00
. storagebits = 16 , \
2012-09-10 12:34:00 +04:00
. shift = ( _shift ) , \
. endianness = IIO_BE , \
2012-04-13 13:42:55 +04:00
} , \
}
2018-01-14 23:32:39 +03:00
# define ADC081S_CHAN(bits) _AD7476_CHAN((bits), 12 - (bits), \
BIT ( IIO_CHAN_INFO_RAW ) )
2012-09-17 16:26:00 +04:00
# define AD7476_CHAN(bits) _AD7476_CHAN((bits), 13 - (bits), \
2013-02-27 23:05:34 +04:00
BIT ( IIO_CHAN_INFO_RAW ) )
2012-09-17 16:26:00 +04:00
# define AD7940_CHAN(bits) _AD7476_CHAN((bits), 15 - (bits), \
2013-02-27 23:05:34 +04:00
BIT ( IIO_CHAN_INFO_RAW ) )
2012-09-17 16:26:00 +04:00
# define AD7091R_CHAN(bits) _AD7476_CHAN((bits), 16 - (bits), 0)
2020-03-11 11:43:26 +03:00
# define AD7091R_CONVST_CHAN(bits) _AD7476_CHAN((bits), 16 - (bits), \
BIT ( IIO_CHAN_INFO_RAW ) )
2019-02-04 15:44:41 +03:00
# define ADS786X_CHAN(bits) _AD7476_CHAN((bits), 12 - (bits), \
BIT ( IIO_CHAN_INFO_RAW ) )
2012-09-10 12:34:00 +04:00
2010-10-11 20:05:37 +04:00
static const struct ad7476_chip_info ad7476_chip_info_tbl [ ] = {
2021-04-25 19:31:53 +03:00
[ ID_AD7091 ] = {
. channel [ 0 ] = AD7091R_CHAN ( 12 ) ,
. channel [ 1 ] = IIO_CHAN_SOFT_TIMESTAMP ( 1 ) ,
. convst_channel [ 0 ] = AD7091R_CONVST_CHAN ( 12 ) ,
. convst_channel [ 1 ] = IIO_CHAN_SOFT_TIMESTAMP ( 1 ) ,
. reset = ad7091_reset ,
} ,
2012-09-17 16:26:00 +04:00
[ ID_AD7091R ] = {
. channel [ 0 ] = AD7091R_CHAN ( 12 ) ,
. channel [ 1 ] = IIO_CHAN_SOFT_TIMESTAMP ( 1 ) ,
2020-03-11 11:43:26 +03:00
. convst_channel [ 0 ] = AD7091R_CONVST_CHAN ( 12 ) ,
. convst_channel [ 1 ] = IIO_CHAN_SOFT_TIMESTAMP ( 1 ) ,
2021-04-25 19:31:53 +03:00
. int_vref_uv = 2500000 ,
. has_vref = true ,
2012-09-17 16:26:00 +04:00
. reset = ad7091_reset ,
} ,
2021-04-25 19:31:53 +03:00
[ ID_AD7273 ] = {
. channel [ 0 ] = AD7940_CHAN ( 10 ) ,
. channel [ 1 ] = IIO_CHAN_SOFT_TIMESTAMP ( 1 ) ,
. has_vref = true ,
} ,
[ ID_AD7274 ] = {
. channel [ 0 ] = AD7940_CHAN ( 12 ) ,
. channel [ 1 ] = IIO_CHAN_SOFT_TIMESTAMP ( 1 ) ,
. has_vref = true ,
} ,
2012-09-10 13:33:00 +04:00
[ ID_AD7276 ] = {
. channel [ 0 ] = AD7940_CHAN ( 12 ) ,
. channel [ 1 ] = IIO_CHAN_SOFT_TIMESTAMP ( 1 ) ,
} ,
[ ID_AD7277 ] = {
. channel [ 0 ] = AD7940_CHAN ( 10 ) ,
. channel [ 1 ] = IIO_CHAN_SOFT_TIMESTAMP ( 1 ) ,
} ,
[ ID_AD7278 ] = {
. channel [ 0 ] = AD7940_CHAN ( 8 ) ,
. channel [ 1 ] = IIO_CHAN_SOFT_TIMESTAMP ( 1 ) ,
} ,
2010-10-11 20:05:37 +04:00
[ ID_AD7466 ] = {
2012-04-13 13:42:55 +04:00
. channel [ 0 ] = AD7476_CHAN ( 12 ) ,
2011-05-18 17:41:24 +04:00
. channel [ 1 ] = IIO_CHAN_SOFT_TIMESTAMP ( 1 ) ,
2010-10-11 20:05:37 +04:00
} ,
[ ID_AD7467 ] = {
2012-04-13 13:42:55 +04:00
. channel [ 0 ] = AD7476_CHAN ( 10 ) ,
2011-05-18 17:41:24 +04:00
. channel [ 1 ] = IIO_CHAN_SOFT_TIMESTAMP ( 1 ) ,
2010-10-11 20:05:37 +04:00
} ,
[ ID_AD7468 ] = {
2012-04-13 13:42:55 +04:00
. channel [ 0 ] = AD7476_CHAN ( 8 ) ,
2011-05-18 17:41:24 +04:00
. channel [ 1 ] = IIO_CHAN_SOFT_TIMESTAMP ( 1 ) ,
2010-10-11 20:05:37 +04:00
} ,
2021-04-25 19:31:53 +03:00
[ ID_AD7475 ] = {
. channel [ 0 ] = AD7476_CHAN ( 12 ) ,
. channel [ 1 ] = IIO_CHAN_SOFT_TIMESTAMP ( 1 ) ,
. has_vref = true ,
. has_vdrive = true ,
} ,
2010-10-11 20:05:37 +04:00
[ ID_AD7495 ] = {
2012-04-13 13:42:55 +04:00
. channel [ 0 ] = AD7476_CHAN ( 12 ) ,
2011-05-18 17:41:24 +04:00
. channel [ 1 ] = IIO_CHAN_SOFT_TIMESTAMP ( 1 ) ,
2012-09-10 12:34:00 +04:00
. int_vref_uv = 2500000 ,
2021-04-25 19:31:53 +03:00
. has_vdrive = true ,
2010-10-11 20:05:37 +04:00
} ,
2012-09-10 12:34:00 +04:00
[ ID_AD7940 ] = {
. channel [ 0 ] = AD7940_CHAN ( 14 ) ,
. channel [ 1 ] = IIO_CHAN_SOFT_TIMESTAMP ( 1 ) ,
} ,
2018-01-14 23:32:39 +03:00
[ ID_ADC081S ] = {
. channel [ 0 ] = ADC081S_CHAN ( 8 ) ,
. channel [ 1 ] = IIO_CHAN_SOFT_TIMESTAMP ( 1 ) ,
} ,
[ ID_ADC101S ] = {
. channel [ 0 ] = ADC081S_CHAN ( 10 ) ,
. channel [ 1 ] = IIO_CHAN_SOFT_TIMESTAMP ( 1 ) ,
} ,
[ ID_ADC121S ] = {
. channel [ 0 ] = ADC081S_CHAN ( 12 ) ,
. channel [ 1 ] = IIO_CHAN_SOFT_TIMESTAMP ( 1 ) ,
} ,
2019-02-04 15:44:41 +03:00
[ ID_ADS7866 ] = {
. channel [ 0 ] = ADS786X_CHAN ( 12 ) ,
. channel [ 1 ] = IIO_CHAN_SOFT_TIMESTAMP ( 1 ) ,
} ,
[ ID_ADS7867 ] = {
. channel [ 0 ] = ADS786X_CHAN ( 10 ) ,
. channel [ 1 ] = IIO_CHAN_SOFT_TIMESTAMP ( 1 ) ,
} ,
[ ID_ADS7868 ] = {
. channel [ 0 ] = ADS786X_CHAN ( 8 ) ,
. channel [ 1 ] = IIO_CHAN_SOFT_TIMESTAMP ( 1 ) ,
} ,
2020-12-16 11:36:39 +03:00
[ ID_LTC2314_14 ] = {
. channel [ 0 ] = AD7940_CHAN ( 14 ) ,
. channel [ 1 ] = IIO_CHAN_SOFT_TIMESTAMP ( 1 ) ,
2021-04-25 19:31:53 +03:00
. has_vref = true ,
2020-12-16 11:36:39 +03:00
} ,
2010-10-11 20:05:37 +04:00
} ;
2011-05-18 17:42:37 +04:00
static const struct iio_info ad7476_info = {
. read_raw = & ad7476_read_raw ,
} ;
2020-03-11 11:43:28 +03:00
static void ad7476_reg_disable ( void * data )
{
2021-04-25 19:31:53 +03:00
struct regulator * reg = data ;
2020-03-11 11:43:28 +03:00
2021-04-25 19:31:53 +03:00
regulator_disable ( reg ) ;
2020-03-11 11:43:28 +03:00
}
2012-12-22 01:21:43 +04:00
static int ad7476_probe ( struct spi_device * spi )
2010-10-11 20:05:37 +04:00
{
struct ad7476_state * st ;
2011-06-27 16:07:18 +04:00
struct iio_dev * indio_dev ;
2021-04-25 19:31:53 +03:00
struct regulator * reg ;
2012-09-10 12:34:00 +04:00
int ret ;
2010-10-11 20:05:37 +04:00
2013-07-23 12:58:00 +04:00
indio_dev = devm_iio_device_alloc ( & spi - > dev , sizeof ( * st ) ) ;
if ( ! indio_dev )
return - ENOMEM ;
2011-06-27 16:07:18 +04:00
st = iio_priv ( indio_dev ) ;
2010-10-11 20:05:37 +04:00
st - > chip_info =
& ad7476_chip_info_tbl [ spi_get_device_id ( spi ) - > driver_data ] ;
2021-04-25 19:31:53 +03:00
reg = devm_regulator_get ( & spi - > dev , " vcc " ) ;
if ( IS_ERR ( reg ) )
return PTR_ERR ( reg ) ;
2012-09-10 12:34:00 +04:00
2021-04-25 19:31:53 +03:00
ret = regulator_enable ( reg ) ;
2012-09-10 12:34:00 +04:00
if ( ret )
2013-07-23 12:58:00 +04:00
return ret ;
2010-10-11 20:05:37 +04:00
2021-04-25 19:31:53 +03:00
ret = devm_add_action_or_reset ( & spi - > dev , ad7476_reg_disable , reg ) ;
2020-03-11 11:43:28 +03:00
if ( ret )
return ret ;
2021-04-25 19:31:53 +03:00
/* Either vcc or vref (below) as appropriate */
if ( ! st - > chip_info - > int_vref_uv )
st - > ref_reg = reg ;
if ( st - > chip_info - > has_vref ) {
/* If a device has an internal reference vref is optional */
if ( st - > chip_info - > int_vref_uv ) {
reg = devm_regulator_get_optional ( & spi - > dev , " vref " ) ;
if ( IS_ERR ( reg ) & & ( PTR_ERR ( reg ) ! = - ENODEV ) )
return PTR_ERR ( reg ) ;
} else {
reg = devm_regulator_get ( & spi - > dev , " vref " ) ;
if ( IS_ERR ( reg ) )
return PTR_ERR ( reg ) ;
}
if ( ! IS_ERR ( reg ) ) {
ret = regulator_enable ( reg ) ;
if ( ret )
return ret ;
ret = devm_add_action_or_reset ( & spi - > dev ,
ad7476_reg_disable ,
reg ) ;
if ( ret )
return ret ;
st - > ref_reg = reg ;
} else {
/*
* Can only get here if device supports both internal
* and external reference , but the regulator connected
* to the external reference is not connected .
* Set the reference regulator pointer to NULL to
* indicate this .
*/
st - > ref_reg = NULL ;
}
}
if ( st - > chip_info - > has_vdrive ) {
2022-08-19 22:20:03 +03:00
ret = devm_regulator_get_enable ( & spi - > dev , " vdrive " ) ;
2021-04-25 19:31:53 +03:00
if ( ret )
return ret ;
}
2020-03-11 11:43:25 +03:00
st - > convst_gpio = devm_gpiod_get_optional ( & spi - > dev ,
" adi,conversion-start " ,
GPIOD_OUT_LOW ) ;
if ( IS_ERR ( st - > convst_gpio ) )
return PTR_ERR ( st - > convst_gpio ) ;
2010-10-11 20:05:37 +04:00
st - > spi = spi ;
2011-06-27 16:07:18 +04:00
indio_dev - > name = spi_get_device_id ( spi ) - > name ;
indio_dev - > modes = INDIO_DIRECT_MODE ;
indio_dev - > channels = st - > chip_info - > channel ;
indio_dev - > num_channels = 2 ;
indio_dev - > info = & ad7476_info ;
2020-03-11 11:43:26 +03:00
2020-04-24 16:04:19 +03:00
if ( st - > convst_gpio )
2020-03-11 11:43:26 +03:00
indio_dev - > channels = st - > chip_info - > convst_channel ;
2010-10-11 20:05:37 +04:00
/* Setup default message */
st - > xfer . rx_buf = & st - > data ;
2011-05-18 17:41:24 +04:00
st - > xfer . len = st - > chip_info - > channel [ 0 ] . scan_type . storagebits / 8 ;
2010-10-11 20:05:37 +04:00
spi_message_init ( & st - > msg ) ;
spi_message_add_tail ( & st - > xfer , & st - > msg ) ;
2021-04-01 20:17:57 +03:00
ret = devm_iio_triggered_buffer_setup ( & spi - > dev , indio_dev , NULL ,
& ad7476_trigger_handler , NULL ) ;
2010-10-11 20:05:37 +04:00
if ( ret )
2021-04-01 20:17:57 +03:00
return ret ;
2010-10-11 20:05:37 +04:00
2012-09-17 16:26:00 +04:00
if ( st - > chip_info - > reset )
st - > chip_info - > reset ( st ) ;
2021-04-01 20:17:57 +03:00
return devm_iio_device_register ( & spi - > dev , indio_dev ) ;
2010-10-11 20:05:37 +04:00
}
static const struct spi_device_id ad7476_id [ ] = {
2021-04-25 19:31:53 +03:00
{ " ad7091 " , ID_AD7091 } ,
2012-09-17 16:26:00 +04:00
{ " ad7091r " , ID_AD7091R } ,
2021-04-25 19:31:53 +03:00
{ " ad7273 " , ID_AD7273 } ,
{ " ad7274 " , ID_AD7274 } ,
2012-09-10 13:33:00 +04:00
{ " ad7276 " , ID_AD7276 } ,
{ " ad7277 " , ID_AD7277 } ,
{ " ad7278 " , ID_AD7278 } ,
2010-10-11 20:05:37 +04:00
{ " ad7466 " , ID_AD7466 } ,
{ " ad7467 " , ID_AD7467 } ,
{ " ad7468 " , ID_AD7468 } ,
2021-04-25 19:31:53 +03:00
{ " ad7475 " , ID_AD7475 } ,
2012-09-10 12:34:00 +04:00
{ " ad7476 " , ID_AD7466 } ,
{ " ad7476a " , ID_AD7466 } ,
{ " ad7477 " , ID_AD7467 } ,
{ " ad7477a " , ID_AD7467 } ,
{ " ad7478 " , ID_AD7468 } ,
{ " ad7478a " , ID_AD7468 } ,
2010-10-11 20:05:37 +04:00
{ " ad7495 " , ID_AD7495 } ,
2012-09-10 12:34:00 +04:00
{ " ad7910 " , ID_AD7467 } ,
{ " ad7920 " , ID_AD7466 } ,
2012-09-10 12:34:00 +04:00
{ " ad7940 " , ID_AD7940 } ,
2018-01-14 23:32:39 +03:00
{ " adc081s " , ID_ADC081S } ,
{ " adc101s " , ID_ADC101S } ,
{ " adc121s " , ID_ADC121S } ,
2019-02-04 15:44:41 +03:00
{ " ads7866 " , ID_ADS7866 } ,
{ " ads7867 " , ID_ADS7867 } ,
{ " ads7868 " , ID_ADS7868 } ,
2020-12-16 11:36:39 +03:00
{ " ltc2314-14 " , ID_LTC2314_14 } ,
2010-10-11 20:05:37 +04:00
{ }
} ;
2011-11-16 11:53:31 +04:00
MODULE_DEVICE_TABLE ( spi , ad7476_id ) ;
2010-10-11 20:05:37 +04:00
static struct spi_driver ad7476_driver = {
. driver = {
. name = " ad7476 " ,
} ,
. probe = ad7476_probe ,
. id_table = ad7476_id ,
} ;
2011-11-16 13:13:39 +04:00
module_spi_driver ( ad7476_driver ) ;
2010-10-11 20:05:37 +04:00
2018-08-14 14:23:17 +03:00
MODULE_AUTHOR ( " Michael Hennerich <michael.hennerich@analog.com> " ) ;
2012-09-10 12:34:00 +04:00
MODULE_DESCRIPTION ( " Analog Devices AD7476 and similar 1-channel ADCs " ) ;
2010-10-11 20:05:37 +04:00
MODULE_LICENSE ( " GPL v2 " ) ;