2019-06-04 11:11:33 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2017-02-17 23:53:32 +03:00
/*
* Copyright ( c ) 2016 Golden Delicious Comp . GmbH & Co . KG
* Nikolaus Schaller < hns @ goldelico . com >
*/
# include <linux/i2c.h>
# include <linux/iio/iio.h>
# include "tsc2007.h"
struct tsc2007_iio {
struct tsc2007 * ts ;
} ;
# define TSC2007_CHAN_IIO(_chan, _name, _type, _chan_info) \
{ \
. datasheet_name = _name , \
. type = _type , \
. info_mask_separate = BIT ( IIO_CHAN_INFO_RAW ) | \
BIT ( _chan_info ) , \
. indexed = 1 , \
. channel = _chan , \
}
static const struct iio_chan_spec tsc2007_iio_channel [ ] = {
TSC2007_CHAN_IIO ( 0 , " x " , IIO_VOLTAGE , IIO_CHAN_INFO_RAW ) ,
TSC2007_CHAN_IIO ( 1 , " y " , IIO_VOLTAGE , IIO_CHAN_INFO_RAW ) ,
TSC2007_CHAN_IIO ( 2 , " z1 " , IIO_VOLTAGE , IIO_CHAN_INFO_RAW ) ,
TSC2007_CHAN_IIO ( 3 , " z2 " , IIO_VOLTAGE , IIO_CHAN_INFO_RAW ) ,
TSC2007_CHAN_IIO ( 4 , " adc " , IIO_VOLTAGE , IIO_CHAN_INFO_RAW ) ,
TSC2007_CHAN_IIO ( 5 , " rt " , IIO_VOLTAGE , IIO_CHAN_INFO_RAW ) , /* Ohms? */
TSC2007_CHAN_IIO ( 6 , " pen " , IIO_PRESSURE , IIO_CHAN_INFO_RAW ) ,
TSC2007_CHAN_IIO ( 7 , " temp0 " , IIO_TEMP , IIO_CHAN_INFO_RAW ) ,
TSC2007_CHAN_IIO ( 8 , " temp1 " , IIO_TEMP , IIO_CHAN_INFO_RAW ) ,
} ;
static int tsc2007_read_raw ( struct iio_dev * indio_dev ,
struct iio_chan_spec const * chan ,
int * val , int * val2 , long mask )
{
struct tsc2007_iio * iio = iio_priv ( indio_dev ) ;
struct tsc2007 * tsc = iio - > ts ;
int adc_chan = chan - > channel ;
int ret = 0 ;
if ( adc_chan > = ARRAY_SIZE ( tsc2007_iio_channel ) )
return - EINVAL ;
if ( mask ! = IIO_CHAN_INFO_RAW )
return - EINVAL ;
mutex_lock ( & tsc - > mlock ) ;
switch ( chan - > channel ) {
case 0 :
* val = tsc2007_xfer ( tsc , READ_X ) ;
break ;
case 1 :
* val = tsc2007_xfer ( tsc , READ_Y ) ;
break ;
case 2 :
* val = tsc2007_xfer ( tsc , READ_Z1 ) ;
break ;
case 3 :
* val = tsc2007_xfer ( tsc , READ_Z2 ) ;
break ;
case 4 :
* val = tsc2007_xfer ( tsc , ( ADC_ON_12BIT | TSC2007_MEASURE_AUX ) ) ;
break ;
case 5 : {
struct ts_event tc ;
tc . x = tsc2007_xfer ( tsc , READ_X ) ;
tc . z1 = tsc2007_xfer ( tsc , READ_Z1 ) ;
tc . z2 = tsc2007_xfer ( tsc , READ_Z2 ) ;
2017-02-23 10:49:02 +03:00
* val = tsc2007_calculate_resistance ( tsc , & tc ) ;
2017-02-17 23:53:32 +03:00
break ;
}
case 6 :
* val = tsc2007_is_pen_down ( tsc ) ;
break ;
case 7 :
* val = tsc2007_xfer ( tsc ,
( ADC_ON_12BIT | TSC2007_MEASURE_TEMP0 ) ) ;
break ;
case 8 :
* val = tsc2007_xfer ( tsc ,
( ADC_ON_12BIT | TSC2007_MEASURE_TEMP1 ) ) ;
break ;
}
/* Prepare for next touch reading - power down ADC, enable PENIRQ */
tsc2007_xfer ( tsc , PWRDOWN ) ;
mutex_unlock ( & tsc - > mlock ) ;
ret = IIO_VAL_INT ;
return ret ;
}
static const struct iio_info tsc2007_iio_info = {
. read_raw = tsc2007_read_raw ,
} ;
int tsc2007_iio_configure ( struct tsc2007 * ts )
{
struct iio_dev * indio_dev ;
struct tsc2007_iio * iio ;
int error ;
indio_dev = devm_iio_device_alloc ( & ts - > client - > dev , sizeof ( * iio ) ) ;
if ( ! indio_dev ) {
dev_err ( & ts - > client - > dev , " iio_device_alloc failed \n " ) ;
return - ENOMEM ;
}
iio = iio_priv ( indio_dev ) ;
iio - > ts = ts ;
indio_dev - > name = " tsc2007 " ;
indio_dev - > info = & tsc2007_iio_info ;
indio_dev - > modes = INDIO_DIRECT_MODE ;
indio_dev - > channels = tsc2007_iio_channel ;
indio_dev - > num_channels = ARRAY_SIZE ( tsc2007_iio_channel ) ;
error = devm_iio_device_register ( & ts - > client - > dev , indio_dev ) ;
if ( error ) {
dev_err ( & ts - > client - > dev ,
" iio_device_register() failed: %d \n " , error ) ;
return error ;
}
return 0 ;
}