2011-10-14 16:34:13 +01:00
/**
* Copyright ( c ) 2011 Jonathan Cameron
*
* 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 .
*
* A reference industrial I / O driver to illustrate the functionality available .
*
* There are numerous real drivers to illustrate the finer points .
* The purpose of this driver is to provide a driver with far more comments
* and explanatory notes than any ' real ' driver would have .
* Anyone starting out writing an IIO driver should first make sure they
* understand all of this driver except those bits specifically marked
* as being present to allow us to ' fake ' the presence of hardware .
*/
# include <linux/kernel.h>
# include <linux/slab.h>
# include <linux/module.h>
2016-04-25 16:15:52 +03:00
# include <linux/string.h>
2011-10-14 16:34:13 +01:00
2012-04-25 15:54:58 +01:00
# include <linux/iio/iio.h>
# include <linux/iio/sysfs.h>
# include <linux/iio/events.h>
# include <linux/iio/buffer.h>
2016-04-25 16:15:52 +03:00
# include <linux/iio/sw_device.h>
2011-10-14 16:34:14 +01:00
# include "iio_simple_dummy.h"
2011-10-14 16:34:13 +01:00
2017-10-16 17:18:43 +02:00
static const struct config_item_type iio_dummy_type = {
2016-04-25 16:15:52 +03:00
. ct_owner = THIS_MODULE ,
} ;
2011-10-14 16:34:13 +01:00
/**
* struct iio_dummy_accel_calibscale - realworld to register mapping
* @ val : first value in read_raw - here integer part .
* @ val2 : second value in read_raw etc - here micro part .
* @ regval : register value - magic device specific numbers .
*/
struct iio_dummy_accel_calibscale {
int val ;
int val2 ;
int regval ; /* what would be written to hardware */
} ;
static const struct iio_dummy_accel_calibscale dummy_scales [ ] = {
{ 0 , 100 , 0x8 } , /* 0.000100 */
{ 0 , 133 , 0x7 } , /* 0.000133 */
2012-12-19 17:56:00 +00:00
{ 733 , 13 , 0x9 } , /* 733.000013 */
2011-10-14 16:34:13 +01:00
} ;
2013-10-07 15:11:00 +01:00
# ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
/*
* simple event - triggered when value rises above
* a threshold
*/
static const struct iio_event_spec iio_dummy_event = {
. type = IIO_EV_TYPE_THRESH ,
. dir = IIO_EV_DIR_RISING ,
. mask_separate = BIT ( IIO_EV_INFO_VALUE ) | BIT ( IIO_EV_INFO_ENABLE ) ,
} ;
2014-11-10 14:45:34 +02:00
/*
* simple step detect event - triggered when a step is detected
*/
static const struct iio_event_spec step_detect_event = {
2015-01-11 21:10:12 +02:00
. type = IIO_EV_TYPE_CHANGE ,
2014-11-10 14:45:34 +02:00
. dir = IIO_EV_DIR_NONE ,
. mask_separate = BIT ( IIO_EV_INFO_ENABLE ) ,
} ;
/*
* simple transition event - triggered when the reported running confidence
* value rises above a threshold value
*/
static const struct iio_event_spec iio_running_event = {
. type = IIO_EV_TYPE_THRESH ,
. dir = IIO_EV_DIR_RISING ,
. mask_separate = BIT ( IIO_EV_INFO_VALUE ) | BIT ( IIO_EV_INFO_ENABLE ) ,
} ;
/*
* simple transition event - triggered when the reported walking confidence
* value falls under a threshold value
*/
static const struct iio_event_spec iio_walking_event = {
. type = IIO_EV_TYPE_THRESH ,
. dir = IIO_EV_DIR_FALLING ,
. mask_separate = BIT ( IIO_EV_INFO_VALUE ) | BIT ( IIO_EV_INFO_ENABLE ) ,
} ;
2013-10-07 15:11:00 +01:00
# endif
2011-10-14 16:34:13 +01:00
/*
* iio_dummy_channels - Description of available channels
*
* This array of structures tells the IIO core about what the device
* actually provides for a given channel .
*/
2012-08-09 08:51:00 +01:00
static const struct iio_chan_spec iio_dummy_channels [ ] = {
2011-10-14 16:34:13 +01:00
/* indexed ADC channel in_voltage0_raw etc */
{
. type = IIO_VOLTAGE ,
/* Channel has a numeric index of 0 */
. indexed = 1 ,
. channel = 0 ,
/* What other information is available? */
2013-02-19 21:12:21 +00:00
. info_mask_separate =
2012-04-15 17:41:27 +01:00
/*
* in_voltage0_raw
* Raw ( unscaled no bias removal etc ) measurement
* from the device .
*/
2013-02-19 21:12:21 +00:00
BIT ( IIO_CHAN_INFO_RAW ) |
2011-10-14 16:34:13 +01:00
/*
* in_voltage0_offset
* Offset for userspace to apply prior to scale
* when converting to standard units ( microvolts )
*/
2013-02-19 21:12:21 +00:00
BIT ( IIO_CHAN_INFO_OFFSET ) |
2011-10-14 16:34:13 +01:00
/*
* in_voltage0_scale
* Multipler for userspace to apply post offset
* when converting to standard units ( microvolts )
*/
2013-02-19 21:12:21 +00:00
BIT ( IIO_CHAN_INFO_SCALE ) ,
2013-09-08 14:57:00 +01:00
/*
* sampling_frequency
* The frequency in Hz at which the channels are sampled
*/
. info_mask_shared_by_dir = BIT ( IIO_CHAN_INFO_SAMP_FREQ ) ,
2011-10-14 16:34:15 +01:00
/* The ordering of elements in the buffer via an enum */
2015-10-26 13:48:23 -07:00
. scan_index = DUMMY_INDEX_VOLTAGE_0 ,
2011-10-14 16:34:15 +01:00
. scan_type = { /* Description of storage in buffer */
. sign = ' u ' , /* unsigned */
. realbits = 13 , /* 13 bits */
. storagebits = 16 , /* 16 bits used for storage */
. shift = 0 , /* zero shift */
} ,
2011-10-14 16:34:14 +01:00
# ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
2013-10-07 15:11:00 +01:00
. event_spec = & iio_dummy_event ,
. num_event_specs = 1 ,
2011-10-14 16:34:14 +01:00
# endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
2011-10-14 16:34:13 +01:00
} ,
/* Differential ADC channel in_voltage1-voltage2_raw etc*/
{
. type = IIO_VOLTAGE ,
. differential = 1 ,
/*
* Indexing for differential channels uses channel
* for the positive part , channel2 for the negative .
*/
. indexed = 1 ,
. channel = 1 ,
. channel2 = 2 ,
2012-04-15 17:41:27 +01:00
/*
* in_voltage1 - voltage2_raw
* Raw ( unscaled no bias removal etc ) measurement
* from the device .
*/
2013-02-19 21:12:21 +00:00
. info_mask_separate = BIT ( IIO_CHAN_INFO_RAW ) ,
2011-10-14 16:34:13 +01:00
/*
* in_voltage - voltage_scale
* Shared version of scale - shared by differential
* input channels of type IIO_VOLTAGE .
*/
2013-02-19 21:12:21 +00:00
. info_mask_shared_by_type = BIT ( IIO_CHAN_INFO_SCALE ) ,
2013-09-08 14:57:00 +01:00
/*
* sampling_frequency
* The frequency in Hz at which the channels are sampled
*/
2015-10-26 13:48:23 -07:00
. scan_index = DUMMY_INDEX_DIFFVOLTAGE_1M2 ,
2011-10-14 16:34:15 +01:00
. scan_type = { /* Description of storage in buffer */
. sign = ' s ' , /* signed */
. realbits = 12 , /* 12 bits */
. storagebits = 16 , /* 16 bits used for storage */
. shift = 0 , /* zero shift */
} ,
2011-10-14 16:34:13 +01:00
} ,
/* Differential ADC channel in_voltage3-voltage4_raw etc*/
{
. type = IIO_VOLTAGE ,
. differential = 1 ,
. indexed = 1 ,
. channel = 3 ,
. channel2 = 4 ,
2013-02-19 21:12:21 +00:00
. info_mask_separate = BIT ( IIO_CHAN_INFO_RAW ) ,
. info_mask_shared_by_type = BIT ( IIO_CHAN_INFO_SCALE ) ,
2013-09-08 14:57:00 +01:00
. info_mask_shared_by_dir = BIT ( IIO_CHAN_INFO_SAMP_FREQ ) ,
2015-10-26 13:48:23 -07:00
. scan_index = DUMMY_INDEX_DIFFVOLTAGE_3M4 ,
2011-10-14 16:34:15 +01:00
. scan_type = {
. sign = ' s ' ,
. realbits = 11 ,
. storagebits = 16 ,
. shift = 0 ,
} ,
2011-10-14 16:34:13 +01:00
} ,
/*
* ' modified ' ( i . e . axis specified ) acceleration channel
* in_accel_z_raw
*/
{
. type = IIO_ACCEL ,
. modified = 1 ,
/* Channel 2 is use for modifiers */
. channel2 = IIO_MOD_X ,
2013-02-19 21:12:21 +00:00
. info_mask_separate = BIT ( IIO_CHAN_INFO_RAW ) |
2011-10-14 16:34:13 +01:00
/*
2013-04-05 05:51:00 +01:00
* Internal bias and gain correction values . Applied
2011-10-14 16:34:13 +01:00
* by the hardware or driver prior to userspace
* seeing the readings . Typically part of hardware
* calibration .
*/
2013-04-05 05:51:00 +01:00
BIT ( IIO_CHAN_INFO_CALIBSCALE ) |
2013-02-19 21:12:21 +00:00
BIT ( IIO_CHAN_INFO_CALIBBIAS ) ,
2013-09-08 14:57:00 +01:00
. info_mask_shared_by_dir = BIT ( IIO_CHAN_INFO_SAMP_FREQ ) ,
2015-10-26 13:48:23 -07:00
. scan_index = DUMMY_INDEX_ACCELX ,
2011-10-14 16:34:15 +01:00
. scan_type = { /* Description of storage in buffer */
. sign = ' s ' , /* signed */
2012-06-15 19:27:10 +02:00
. realbits = 16 , /* 16 bits */
2011-10-14 16:34:15 +01:00
. storagebits = 16 , /* 16 bits used for storage */
. shift = 0 , /* zero shift */
} ,
} ,
/*
* Convenience macro for timestamps . 4 is the index in
* the buffer .
*/
IIO_CHAN_SOFT_TIMESTAMP ( 4 ) ,
/* DAC channel out_voltage0_raw */
{
. type = IIO_VOLTAGE ,
2013-02-19 21:12:21 +00:00
. info_mask_separate = BIT ( IIO_CHAN_INFO_RAW ) ,
2014-11-26 18:55:11 +01:00
. scan_index = - 1 , /* No buffer support */
2011-10-14 16:34:15 +01:00
. output = 1 ,
. indexed = 1 ,
. channel = 0 ,
2011-10-14 16:34:13 +01:00
} ,
2014-11-10 14:45:34 +02:00
{
. type = IIO_STEPS ,
. info_mask_shared_by_type = BIT ( IIO_CHAN_INFO_ENABLE ) |
BIT ( IIO_CHAN_INFO_CALIBHEIGHT ) ,
. info_mask_separate = BIT ( IIO_CHAN_INFO_PROCESSED ) ,
2014-11-26 18:55:11 +01:00
. scan_index = - 1 , /* No buffer support */
2014-11-10 14:45:34 +02:00
# ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
. event_spec = & step_detect_event ,
. num_event_specs = 1 ,
# endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
} ,
{
. type = IIO_ACTIVITY ,
. modified = 1 ,
. channel2 = IIO_MOD_RUNNING ,
. info_mask_separate = BIT ( IIO_CHAN_INFO_PROCESSED ) ,
2014-11-26 18:55:11 +01:00
. scan_index = - 1 , /* No buffer support */
2014-11-10 14:45:34 +02:00
# ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
. event_spec = & iio_running_event ,
. num_event_specs = 1 ,
# endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
} ,
{
. type = IIO_ACTIVITY ,
. modified = 1 ,
. channel2 = IIO_MOD_WALKING ,
. info_mask_separate = BIT ( IIO_CHAN_INFO_PROCESSED ) ,
2014-11-26 18:55:11 +01:00
. scan_index = - 1 , /* No buffer support */
2014-11-10 14:45:34 +02:00
# ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
. event_spec = & iio_walking_event ,
. num_event_specs = 1 ,
# endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
} ,
2011-10-14 16:34:13 +01:00
} ;
/**
* iio_dummy_read_raw ( ) - data read function .
* @ indio_dev : the struct iio_dev associated with this device instance
* @ chan : the channel whose data is to be read
* @ val : first element of returned value ( typically INT )
* @ val2 : second element of returned value ( typically MICRO )
2013-02-19 21:12:21 +00:00
* @ mask : what we actually want to read as per the info_mask_ *
* in iio_chan_spec .
2011-10-14 16:34:13 +01:00
*/
static int iio_dummy_read_raw ( struct iio_dev * indio_dev ,
struct iio_chan_spec const * chan ,
int * val ,
int * val2 ,
long mask )
{
struct iio_dummy_state * st = iio_priv ( indio_dev ) ;
int ret = - EINVAL ;
mutex_lock ( & st - > lock ) ;
switch ( mask ) {
2012-04-15 17:41:27 +01:00
case IIO_CHAN_INFO_RAW : /* magic value - channel value read */
2011-10-14 16:34:13 +01:00
switch ( chan - > type ) {
case IIO_VOLTAGE :
if ( chan - > output ) {
/* Set integer part to cached value */
* val = st - > dac_val ;
ret = IIO_VAL_INT ;
} else if ( chan - > differential ) {
if ( chan - > channel = = 1 )
* val = st - > differential_adc_val [ 0 ] ;
else
* val = st - > differential_adc_val [ 1 ] ;
ret = IIO_VAL_INT ;
} else {
* val = st - > single_ended_adc_val ;
ret = IIO_VAL_INT ;
}
break ;
case IIO_ACCEL :
* val = st - > accel_val ;
ret = IIO_VAL_INT ;
break ;
default :
break ;
}
break ;
2014-11-10 14:45:34 +02:00
case IIO_CHAN_INFO_PROCESSED :
switch ( chan - > type ) {
case IIO_STEPS :
* val = st - > steps ;
ret = IIO_VAL_INT ;
break ;
case IIO_ACTIVITY :
switch ( chan - > channel2 ) {
case IIO_MOD_RUNNING :
* val = st - > activity_running ;
ret = IIO_VAL_INT ;
break ;
case IIO_MOD_WALKING :
* val = st - > activity_walking ;
ret = IIO_VAL_INT ;
break ;
default :
break ;
}
break ;
default :
break ;
}
break ;
2011-10-26 17:41:36 +01:00
case IIO_CHAN_INFO_OFFSET :
2011-10-14 16:34:13 +01:00
/* only single ended adc -> 7 */
* val = 7 ;
ret = IIO_VAL_INT ;
break ;
2011-10-26 17:41:36 +01:00
case IIO_CHAN_INFO_SCALE :
2014-11-10 14:45:34 +02:00
switch ( chan - > type ) {
case IIO_VOLTAGE :
switch ( chan - > differential ) {
case 0 :
/* only single ended adc -> 0.001333 */
* val = 0 ;
* val2 = 1333 ;
ret = IIO_VAL_INT_PLUS_MICRO ;
break ;
case 1 :
2015-10-26 13:50:29 -07:00
/* all differential adc -> 0.000001344 */
2014-11-10 14:45:34 +02:00
* val = 0 ;
* val2 = 1344 ;
ret = IIO_VAL_INT_PLUS_NANO ;
}
break ;
default :
2011-10-26 17:41:36 +01:00
break ;
}
2011-10-14 16:34:13 +01:00
break ;
2011-10-26 17:41:36 +01:00
case IIO_CHAN_INFO_CALIBBIAS :
2011-10-14 16:34:13 +01:00
/* only the acceleration axis - read from cache */
* val = st - > accel_calibbias ;
ret = IIO_VAL_INT ;
break ;
2011-10-26 17:41:36 +01:00
case IIO_CHAN_INFO_CALIBSCALE :
2011-10-14 16:34:13 +01:00
* val = st - > accel_calibscale - > val ;
* val2 = st - > accel_calibscale - > val2 ;
ret = IIO_VAL_INT_PLUS_MICRO ;
break ;
2013-09-08 14:57:00 +01:00
case IIO_CHAN_INFO_SAMP_FREQ :
* val = 3 ;
* val2 = 33 ;
ret = IIO_VAL_INT_PLUS_NANO ;
break ;
2014-11-10 14:45:34 +02:00
case IIO_CHAN_INFO_ENABLE :
switch ( chan - > type ) {
case IIO_STEPS :
* val = st - > steps_enabled ;
ret = IIO_VAL_INT ;
break ;
default :
break ;
}
break ;
case IIO_CHAN_INFO_CALIBHEIGHT :
switch ( chan - > type ) {
case IIO_STEPS :
* val = st - > height ;
ret = IIO_VAL_INT ;
break ;
default :
break ;
}
break ;
2011-10-14 16:34:13 +01:00
default :
break ;
}
mutex_unlock ( & st - > lock ) ;
return ret ;
}
/**
* iio_dummy_write_raw ( ) - data write function .
* @ indio_dev : the struct iio_dev associated with this device instance
2012-12-19 17:56:00 +00:00
* @ chan : the channel whose data is to be written
2012-06-15 19:27:10 +02:00
* @ val : first element of value to set ( typically INT )
* @ val2 : second element of value to set ( typically MICRO )
2013-02-19 21:12:21 +00:00
* @ mask : what we actually want to write as per the info_mask_ *
* in iio_chan_spec .
2011-10-14 16:34:13 +01:00
*
* Note that all raw writes are assumed IIO_VAL_INT and info mask elements
* are assumed to be IIO_INT_PLUS_MICRO unless the callback write_raw_get_fmt
* in struct iio_info is provided by the driver .
*/
static int iio_dummy_write_raw ( struct iio_dev * indio_dev ,
struct iio_chan_spec const * chan ,
int val ,
int val2 ,
long mask )
{
int i ;
int ret = 0 ;
struct iio_dummy_state * st = iio_priv ( indio_dev ) ;
switch ( mask ) {
2012-04-15 17:41:27 +01:00
case IIO_CHAN_INFO_RAW :
2014-11-10 14:45:34 +02:00
switch ( chan - > type ) {
case IIO_VOLTAGE :
if ( chan - > output = = 0 )
return - EINVAL ;
2011-10-14 16:34:13 +01:00
2014-11-10 14:45:34 +02:00
/* Locking not required as writing single value */
mutex_lock ( & st - > lock ) ;
st - > dac_val = val ;
mutex_unlock ( & st - > lock ) ;
return 0 ;
default :
return - EINVAL ;
}
case IIO_CHAN_INFO_PROCESSED :
switch ( chan - > type ) {
case IIO_STEPS :
mutex_lock ( & st - > lock ) ;
st - > steps = val ;
mutex_unlock ( & st - > lock ) ;
return 0 ;
case IIO_ACTIVITY :
if ( val < 0 )
val = 0 ;
if ( val > 100 )
val = 100 ;
switch ( chan - > channel2 ) {
case IIO_MOD_RUNNING :
st - > activity_running = val ;
return 0 ;
case IIO_MOD_WALKING :
st - > activity_walking = val ;
return 0 ;
default :
return - EINVAL ;
}
break ;
default :
return - EINVAL ;
}
2013-04-05 05:51:00 +01:00
case IIO_CHAN_INFO_CALIBSCALE :
2011-10-14 16:34:13 +01:00
mutex_lock ( & st - > lock ) ;
/* Compare against table - hard matching here */
for ( i = 0 ; i < ARRAY_SIZE ( dummy_scales ) ; i + + )
if ( val = = dummy_scales [ i ] . val & &
val2 = = dummy_scales [ i ] . val2 )
break ;
if ( i = = ARRAY_SIZE ( dummy_scales ) )
ret = - EINVAL ;
else
st - > accel_calibscale = & dummy_scales [ i ] ;
mutex_unlock ( & st - > lock ) ;
return ret ;
2013-04-05 05:51:00 +01:00
case IIO_CHAN_INFO_CALIBBIAS :
mutex_lock ( & st - > lock ) ;
st - > accel_calibbias = val ;
mutex_unlock ( & st - > lock ) ;
return 0 ;
2014-11-10 14:45:34 +02:00
case IIO_CHAN_INFO_ENABLE :
switch ( chan - > type ) {
case IIO_STEPS :
mutex_lock ( & st - > lock ) ;
st - > steps_enabled = val ;
mutex_unlock ( & st - > lock ) ;
return 0 ;
default :
return - EINVAL ;
}
case IIO_CHAN_INFO_CALIBHEIGHT :
switch ( chan - > type ) {
case IIO_STEPS :
st - > height = val ;
return 0 ;
default :
return - EINVAL ;
}
2013-04-05 05:51:00 +01:00
2011-10-14 16:34:13 +01:00
default :
return - EINVAL ;
}
}
/*
* Device type specific information .
*/
static const struct iio_info iio_dummy_info = {
. read_raw = & iio_dummy_read_raw ,
. write_raw = & iio_dummy_write_raw ,
2011-10-14 16:34:14 +01:00
# ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
2013-12-07 10:45:00 +00:00
. read_event_config = & iio_simple_dummy_read_event_config ,
. write_event_config = & iio_simple_dummy_write_event_config ,
. read_event_value = & iio_simple_dummy_read_event_value ,
. write_event_value = & iio_simple_dummy_write_event_value ,
2011-10-14 16:34:14 +01:00
# endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
2011-10-14 16:34:13 +01:00
} ;
/**
* iio_dummy_init_device ( ) - device instance specific init
* @ indio_dev : the iio device structure
*
* Most drivers have one of these to set up default values ,
* reset the device to known state etc .
*/
static int iio_dummy_init_device ( struct iio_dev * indio_dev )
{
struct iio_dummy_state * st = iio_priv ( indio_dev ) ;
st - > dac_val = 0 ;
st - > single_ended_adc_val = 73 ;
st - > differential_adc_val [ 0 ] = 33 ;
st - > differential_adc_val [ 1 ] = - 34 ;
st - > accel_val = 34 ;
st - > accel_calibbias = - 7 ;
st - > accel_calibscale = & dummy_scales [ 0 ] ;
2014-11-10 14:45:34 +02:00
st - > steps = 47 ;
st - > activity_running = 98 ;
st - > activity_walking = 4 ;
2011-10-14 16:34:13 +01:00
return 0 ;
}
/**
* iio_dummy_probe ( ) - device instance probe
* @ index : an id number for this instance .
*
* Arguments are bus type specific .
* I2C : iio_dummy_probe ( struct i2c_client * client ,
* const struct i2c_device_id * id )
* SPI : iio_dummy_probe ( struct spi_device * spi )
*/
2016-04-25 16:15:52 +03:00
static struct iio_sw_device * iio_dummy_probe ( const char * name )
2011-10-14 16:34:13 +01:00
{
int ret ;
struct iio_dev * indio_dev ;
struct iio_dummy_state * st ;
2016-04-25 16:15:52 +03:00
struct iio_sw_device * swd ;
2011-10-14 16:34:13 +01:00
2016-04-25 16:15:52 +03:00
swd = kzalloc ( sizeof ( * swd ) , GFP_KERNEL ) ;
if ( ! swd ) {
ret = - ENOMEM ;
goto error_kzalloc ;
}
2011-10-14 16:34:13 +01:00
/*
* Allocate an IIO device .
*
* This structure contains all generic state
* information about the device instance .
* It also has a region ( accessed by iio_priv ( )
* for chip specific state information .
*/
2012-04-26 13:35:01 +02:00
indio_dev = iio_device_alloc ( sizeof ( * st ) ) ;
2015-03-31 12:51:38 +03:00
if ( ! indio_dev ) {
2011-10-14 16:34:13 +01:00
ret = - ENOMEM ;
goto error_ret ;
}
st = iio_priv ( indio_dev ) ;
mutex_init ( & st - > lock ) ;
iio_dummy_init_device ( indio_dev ) ;
/*
* With hardware : Set the parent device .
* indio_dev - > dev . parent = & spi - > dev ;
* indio_dev - > dev . parent = & client - > dev ;
*/
/*
* Make the iio_dev struct available to remove function .
* Bus equivalents
* i2c_set_clientdata ( client , indio_dev ) ;
* spi_set_drvdata ( spi , indio_dev ) ;
*/
2016-04-25 16:15:52 +03:00
swd - > device = indio_dev ;
2011-10-14 16:34:13 +01:00
/*
* Set the device name .
*
* This is typically a part number and obtained from the module
* id table .
* e . g . for i2c and spi :
* indio_dev - > name = id - > name ;
* indio_dev - > name = spi_get_device_id ( spi ) - > name ;
*/
2016-04-25 16:15:52 +03:00
indio_dev - > name = kstrdup ( name , GFP_KERNEL ) ;
2011-10-14 16:34:13 +01:00
/* Provide description of available channels */
indio_dev - > channels = iio_dummy_channels ;
indio_dev - > num_channels = ARRAY_SIZE ( iio_dummy_channels ) ;
/*
* Provide device type specific interface functions and
* constant data .
*/
indio_dev - > info = & iio_dummy_info ;
/* Specify that device provides sysfs type interfaces */
indio_dev - > modes = INDIO_DIRECT_MODE ;
2011-10-14 16:34:14 +01:00
ret = iio_simple_dummy_events_register ( indio_dev ) ;
2011-10-14 16:34:13 +01:00
if ( ret < 0 )
goto error_free_device ;
2011-10-14 16:34:15 +01:00
2014-11-26 18:55:11 +01:00
ret = iio_simple_dummy_configure_buffer ( indio_dev ) ;
2011-10-14 16:34:15 +01:00
if ( ret < 0 )
2012-09-12 12:06:00 +01:00
goto error_unregister_events ;
2011-10-14 16:34:15 +01:00
ret = iio_device_register ( indio_dev ) ;
if ( ret < 0 )
2012-09-12 12:06:00 +01:00
goto error_unconfigure_buffer ;
2011-10-14 16:34:15 +01:00
2016-04-25 16:15:52 +03:00
iio_swd_group_init_type_name ( swd , name , & iio_dummy_type ) ;
return swd ;
2011-10-14 16:34:15 +01:00
error_unconfigure_buffer :
iio_simple_dummy_unconfigure_buffer ( indio_dev ) ;
2011-10-14 16:34:14 +01:00
error_unregister_events :
iio_simple_dummy_events_unregister ( indio_dev ) ;
2011-10-14 16:34:13 +01:00
error_free_device :
2012-04-26 13:35:01 +02:00
iio_device_free ( indio_dev ) ;
2011-10-14 16:34:13 +01:00
error_ret :
2016-04-25 16:15:52 +03:00
kfree ( swd ) ;
error_kzalloc :
return ERR_PTR ( ret ) ;
2011-10-14 16:34:13 +01:00
}
/**
* iio_dummy_remove ( ) - device instance removal function
2016-04-25 16:15:52 +03:00
* @ swd : pointer to software IIO device abstraction
2011-10-14 16:34:13 +01:00
*
* Parameters follow those of iio_dummy_probe for buses .
*/
2016-04-25 16:15:52 +03:00
static int iio_dummy_remove ( struct iio_sw_device * swd )
2011-10-14 16:34:13 +01:00
{
/*
* Get a pointer to the device instance iio_dev structure
* from the bus subsystem . E . g .
* struct iio_dev * indio_dev = i2c_get_clientdata ( client ) ;
* struct iio_dev * indio_dev = spi_get_drvdata ( spi ) ;
*/
2016-04-25 16:15:52 +03:00
struct iio_dev * indio_dev = swd - > device ;
2011-10-14 16:34:13 +01:00
/* Unregister the device */
iio_device_unregister ( indio_dev ) ;
/* Device specific code to power down etc */
2011-10-14 16:34:15 +01:00
/* Buffered capture related cleanup */
iio_simple_dummy_unconfigure_buffer ( indio_dev ) ;
2011-10-14 16:34:14 +01:00
2015-05-30 11:20:16 +03:00
iio_simple_dummy_events_unregister ( indio_dev ) ;
2011-10-14 16:34:14 +01:00
2011-10-14 16:34:13 +01:00
/* Free all structures */
2016-04-25 16:15:52 +03:00
kfree ( indio_dev - > name ) ;
2012-04-26 13:35:01 +02:00
iio_device_free ( indio_dev ) ;
2011-10-14 16:34:13 +01:00
2016-04-25 16:15:52 +03:00
return 0 ;
}
2011-10-14 16:34:13 +01:00
/**
2016-04-25 16:15:52 +03:00
* module_iio_sw_device_driver ( ) - device driver registration
2011-10-14 16:34:13 +01:00
*
* Varies depending on bus type of the device . As there is no device
* here , call probe directly . For information on device registration
* i2c :
* Documentation / i2c / writing - clients
* spi :
* Documentation / spi / spi - summary
*/
2016-04-25 16:15:52 +03:00
static const struct iio_sw_device_ops iio_dummy_device_ops = {
. probe = iio_dummy_probe ,
. remove = iio_dummy_remove ,
} ;
2011-10-14 16:34:13 +01:00
2016-04-25 16:15:52 +03:00
static struct iio_sw_device_type iio_dummy_device = {
. name = " dummy " ,
. owner = THIS_MODULE ,
. ops = & iio_dummy_device_ops ,
} ;
2014-06-13 06:56:00 +01:00
2016-04-25 16:15:52 +03:00
module_iio_sw_device_driver ( iio_dummy_device ) ;
2011-10-14 16:34:13 +01:00
2012-09-02 21:34:59 +01:00
MODULE_AUTHOR ( " Jonathan Cameron <jic23@kernel.org> " ) ;
2011-10-14 16:34:13 +01:00
MODULE_DESCRIPTION ( " IIO dummy driver " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;