/* Caller responsible for locking as necessary. */
static int
__lis3l02dq_write_data_ready_config(struct device *dev,
				    struct iio_event_handler_list *list,
				    bool state)
{
	int ret;
	u8 valold;
	bool currentlyset;
	struct iio_dev *indio_dev = dev_get_drvdata(dev);

/* Get the current event mask register */
	ret = lis3l02dq_spi_read_reg_8(dev,
				       LIS3L02DQ_REG_CTRL_2_ADDR,
				       &valold);
	if (ret)
		goto error_ret;
/* Find out if data ready is already on */
	currentlyset
		= valold & LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;

/* Disable requested */
	if (!state && currentlyset) {

		valold &= ~LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;
		/* The double write is to overcome a hardware bug?*/
		ret = lis3l02dq_spi_write_reg_8(dev,
						LIS3L02DQ_REG_CTRL_2_ADDR,
						&valold);
		if (ret)
			goto error_ret;
		ret = lis3l02dq_spi_write_reg_8(dev,
						LIS3L02DQ_REG_CTRL_2_ADDR,
						&valold);
		if (ret)
			goto error_ret;

		iio_remove_event_from_list(list,
					   &indio_dev->interrupts[0]
					   ->ev_list);

/* Enable requested */
	} else if (state && !currentlyset) {
		/* if not set, enable requested */
		valold |= LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;
		iio_add_event_to_list(list, &indio_dev->interrupts[0]->ev_list);
		ret = lis3l02dq_spi_write_reg_8(dev,
						LIS3L02DQ_REG_CTRL_2_ADDR,
						&valold);
		if (ret)
			goto error_ret;
	}

	return 0;
error_ret:
	return ret;
}
Esempio n. 2
0
/**
 * adis16240_data_rdy_trigger_set_state() set datardy interrupt state
 **/
static int adis16240_data_rdy_trigger_set_state(struct iio_trigger *trig,
						bool state)
{
	struct adis16240_state *st = trig->private_data;
	struct iio_dev *indio_dev = st->indio_dev;
	int ret = 0;

	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
	ret = adis16240_set_irq(&st->indio_dev->dev, state);
	if (state == false) {
		iio_remove_event_from_list(&iio_event_data_rdy_trig,
					   &indio_dev->interrupts[0]
					   ->ev_list);
		flush_scheduled_work();
	} else {
		iio_add_event_to_list(&iio_event_data_rdy_trig,
				      &indio_dev->interrupts[0]->ev_list);
	}
	return ret;
}
/**
 * adis16300_data_rdy_trigger_set_state() set datardy interrupt state
 **/
static int adis16300_data_rdy_trigger_set_state(struct iio_trigger *trig,
						bool state)
{
	struct adis16300_state *st = trig->private_data;
	struct iio_dev *indio_dev = st->indio_dev;
	int ret = 0;

	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
	ret = adis16300_set_irq(&st->indio_dev->dev, state);
	if (state == false) {
		iio_remove_event_from_list(&iio_event_data_rdy_trig,
					   &indio_dev->interrupts[0]
					   ->ev_list);
		/* possible quirk with handler currently worked around
		   by ensuring the work queue is empty */
		flush_scheduled_work();
	} else {
		iio_add_event_to_list(&iio_event_data_rdy_trig,
				      &indio_dev->interrupts[0]->ev_list);
	}
	return ret;
}