2019-05-24 13:04:09 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2012-11-13 17:28:00 +04:00
/*
* Common library for ADIS16XXX devices
*
* Copyright 2012 Analog Devices Inc .
* Author : Lars - Peter Clausen < lars @ metafoo . de >
*/
# include <linux/interrupt.h>
# include <linux/kernel.h>
# include <linux/spi/spi.h>
# include <linux/export.h>
# include <linux/iio/iio.h>
# include <linux/iio/trigger.h>
2012-11-13 17:28:00 +04:00
# include <linux/iio/imu/adis.h>
2012-11-13 17:28:00 +04:00
static int adis_data_rdy_trigger_set_state ( struct iio_trigger * trig ,
bool state )
{
2013-03-25 12:58:00 +04:00
struct adis * adis = iio_trigger_get_drvdata ( trig ) ;
2012-11-13 17:28:00 +04:00
return adis_enable_irq ( adis , state ) ;
}
static const struct iio_trigger_ops adis_trigger_ops = {
. set_trigger_state = & adis_data_rdy_trigger_set_state ,
} ;
2020-04-13 11:24:40 +03:00
static void adis_trigger_setup ( struct adis * adis )
{
adis - > trig - > dev . parent = & adis - > spi - > dev ;
adis - > trig - > ops = & adis_trigger_ops ;
iio_trigger_set_drvdata ( adis - > trig , adis ) ;
}
2020-04-13 11:24:41 +03:00
static int adis_validate_irq_flag ( struct adis * adis )
{
/*
* Typically this devices have data ready either on the rising edge or
* on the falling edge of the data ready pin . This checks enforces that
* one of those is set in the drivers . . . It defaults to
* IRQF_TRIGGER_RISING for backward compatibility wiht devices that
* don ' t support changing the pin polarity .
*/
if ( ! adis - > irq_flag ) {
adis - > irq_flag = IRQF_TRIGGER_RISING ;
return 0 ;
} else if ( adis - > irq_flag ! = IRQF_TRIGGER_RISING & &
adis - > irq_flag ! = IRQF_TRIGGER_FALLING ) {
dev_err ( & adis - > spi - > dev , " Invalid IRQ mask: %08lx \n " ,
adis - > irq_flag ) ;
return - EINVAL ;
}
return 0 ;
}
2012-11-13 17:28:00 +04:00
2020-04-13 11:24:40 +03:00
/**
* devm_adis_probe_trigger ( ) - Sets up trigger for a managed adis device
* @ adis : The adis device
* @ indio_dev : The IIO device
*
* Returns 0 on success or a negative error code
*/
int devm_adis_probe_trigger ( struct adis * adis , struct iio_dev * indio_dev )
{
int ret ;
adis - > trig = devm_iio_trigger_alloc ( & adis - > spi - > dev , " %s-dev%d " ,
indio_dev - > name , indio_dev - > id ) ;
if ( ! adis - > trig )
return - ENOMEM ;
adis_trigger_setup ( adis ) ;
2020-04-13 11:24:41 +03:00
ret = adis_validate_irq_flag ( adis ) ;
if ( ret )
return ret ;
2020-04-13 11:24:40 +03:00
ret = devm_request_irq ( & adis - > spi - > dev , adis - > spi - > irq ,
& iio_trigger_generic_data_rdy_poll ,
2020-04-13 11:24:41 +03:00
adis - > irq_flag ,
2020-04-13 11:24:40 +03:00
indio_dev - > name ,
adis - > trig ) ;
if ( ret )
return ret ;
return devm_iio_trigger_register ( & adis - > spi - > dev , adis - > trig ) ;
}
EXPORT_SYMBOL_GPL ( devm_adis_probe_trigger ) ;