Re: [PATCH] staging:iio:lis3l02dq drop separate driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 03/07/16 15:07, Jonathan Cameron wrote:
> Retire this venerable driver as the basic support is now in the
> generic st-sensors accelerometer driver.
> 
> There are a few missing features in the new driver:
> * Threshold events.
> * Access to the calibration adjustment registers (patch shortly)
> 
> In exchange it brings a cleaner and more maintainable code base that actually
> gets tested more than once every few years.  I'll actually be suprised
> if anyone other than me has a board with one of these on that is running
> an up to date kernel.
> 
> Signed-off-by: Jonathan Cameron <jic23@xxxxxxxxxx>
This is more for info than expecting any comments. Just dropping
a staging driver that is now 'more or less' covered by a non staging
driver.

Applied to the togreg branch of iio.git - initially pushed out as
testing for the autobuilders to see what I messed up.

Thanks,

Jonathan
> ---
>  drivers/staging/iio/accel/Kconfig          |  14 -
>  drivers/staging/iio/accel/Makefile         |   4 -
>  drivers/staging/iio/accel/lis3l02dq.h      | 217 --------
>  drivers/staging/iio/accel/lis3l02dq_core.c | 814 -----------------------------
>  drivers/staging/iio/accel/lis3l02dq_ring.c | 428 ---------------
>  5 files changed, 1477 deletions(-)
> 
> diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig
> index f066aa30f0ac..1c994b57c7d2 100644
> --- a/drivers/staging/iio/accel/Kconfig
> +++ b/drivers/staging/iio/accel/Kconfig
> @@ -51,20 +51,6 @@ config ADIS16240
>  	  To compile this driver as a module, say M here: the module will be
>  	  called adis16240.
>  
> -config LIS3L02DQ
> -	tristate "ST Microelectronics LIS3L02DQ Accelerometer Driver"
> -	depends on SPI
> -	select IIO_TRIGGER if IIO_BUFFER
> -	depends on !IIO_BUFFER || IIO_KFIFO_BUF
> -	depends on GPIOLIB || COMPILE_TEST
> -	help
> -	  Say Y here to build SPI support for the ST microelectronics
> -	  accelerometer. The driver supplies direct access via sysfs files
> -	  and an event interface via a character device.
> -
> -	  To compile this driver as a module, say M here: the module will be
> -	  called lis3l02dq.
> -
>  config SCA3000
>  	depends on IIO_BUFFER
>  	depends on SPI
> diff --git a/drivers/staging/iio/accel/Makefile b/drivers/staging/iio/accel/Makefile
> index 415329c96f0c..1810a434a755 100644
> --- a/drivers/staging/iio/accel/Makefile
> +++ b/drivers/staging/iio/accel/Makefile
> @@ -14,9 +14,5 @@ obj-$(CONFIG_ADIS16209) += adis16209.o
>  adis16240-y             := adis16240_core.o
>  obj-$(CONFIG_ADIS16240) += adis16240.o
>  
> -lis3l02dq-y		:= lis3l02dq_core.o
> -lis3l02dq-$(CONFIG_IIO_BUFFER) += lis3l02dq_ring.o
> -obj-$(CONFIG_LIS3L02DQ)	+= lis3l02dq.o
> -
>  sca3000-y		:= sca3000_core.o sca3000_ring.o
>  obj-$(CONFIG_SCA3000)	+= sca3000.o
> diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h
> deleted file mode 100644
> index 6bd3d4d5bc9d..000000000000
> --- a/drivers/staging/iio/accel/lis3l02dq.h
> +++ /dev/null
> @@ -1,217 +0,0 @@
> -/*
> - * LISL02DQ.h -- support STMicroelectronics LISD02DQ
> - *               3d 2g Linear Accelerometers via SPI
> - *
> - * Copyright (c) 2007 Jonathan Cameron <jic23@xxxxxxxxxx>
> - *
> - * Loosely based upon tle62x0.c
> - *
> - * 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.
> - */
> -
> -#ifndef SPI_LIS3L02DQ_H_
> -#define SPI_LIS3L02DQ_H_
> -#define LIS3L02DQ_READ_REG(a) ((a) | 0x80)
> -#define LIS3L02DQ_WRITE_REG(a) a
> -
> -/* Calibration parameters */
> -#define LIS3L02DQ_REG_OFFSET_X_ADDR		0x16
> -#define LIS3L02DQ_REG_OFFSET_Y_ADDR		0x17
> -#define LIS3L02DQ_REG_OFFSET_Z_ADDR		0x18
> -
> -#define LIS3L02DQ_REG_GAIN_X_ADDR		0x19
> -#define LIS3L02DQ_REG_GAIN_Y_ADDR		0x1A
> -#define LIS3L02DQ_REG_GAIN_Z_ADDR		0x1B
> -
> -/* Control Register (1 of 2) */
> -#define LIS3L02DQ_REG_CTRL_1_ADDR		0x20
> -/* Power ctrl - either bit set corresponds to on*/
> -#define LIS3L02DQ_REG_CTRL_1_PD_ON		0xC0
> -
> -/* Decimation Factor  */
> -#define LIS3L02DQ_DEC_MASK			0x30
> -#define LIS3L02DQ_REG_CTRL_1_DF_128		0x00
> -#define LIS3L02DQ_REG_CTRL_1_DF_64		0x10
> -#define LIS3L02DQ_REG_CTRL_1_DF_32		0x20
> -#define LIS3L02DQ_REG_CTRL_1_DF_8		(0x10 | 0x20)
> -
> -/* Self Test Enable */
> -#define LIS3L02DQ_REG_CTRL_1_SELF_TEST_ON	0x08
> -
> -/* Axes enable ctrls */
> -#define LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE	0x04
> -#define LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE	0x02
> -#define LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE	0x01
> -
> -/* Control Register (2 of 2) */
> -#define LIS3L02DQ_REG_CTRL_2_ADDR		0x21
> -
> -/* Block Data Update only after MSB and LSB read */
> -#define LIS3L02DQ_REG_CTRL_2_BLOCK_UPDATE	0x40
> -
> -/* Set to big endian output */
> -#define LIS3L02DQ_REG_CTRL_2_BIG_ENDIAN		0x20
> -
> -/* Reboot memory content */
> -#define LIS3L02DQ_REG_CTRL_2_REBOOT_MEMORY	0x10
> -
> -/* Interrupt Enable - applies data ready to the RDY pad */
> -#define LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT	0x08
> -
> -/* Enable Data Ready Generation - relationship with previous unclear in docs */
> -#define LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION 0x04
> -
> -/* SPI 3 wire mode */
> -#define LIS3L02DQ_REG_CTRL_2_THREE_WIRE_SPI_MODE	0x02
> -
> -/* Data alignment, default is 12 bit right justified
> - * - option for 16 bit left justified
> - */
> -#define LIS3L02DQ_REG_CTRL_2_DATA_ALIGNMENT_16_BIT_LEFT_JUSTIFIED	0x01
> -
> -/* Interrupt related stuff */
> -#define LIS3L02DQ_REG_WAKE_UP_CFG_ADDR			0x23
> -
> -/* Switch from or combination of conditions to and */
> -#define LIS3L02DQ_REG_WAKE_UP_CFG_BOOLEAN_AND		0x80
> -
> -/* Latch interrupt request,
> - * if on ack must be given by reading the ack register
> - */
> -#define LIS3L02DQ_REG_WAKE_UP_CFG_LATCH_SRC		0x40
> -
> -/* Z Interrupt on High (above threshold) */
> -#define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_HIGH	0x20
> -/* Z Interrupt on Low */
> -#define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_LOW	0x10
> -/* Y Interrupt on High */
> -#define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Y_HIGH	0x08
> -/* Y Interrupt on Low */
> -#define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Y_LOW	0x04
> -/* X Interrupt on High */
> -#define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_HIGH	0x02
> -/* X Interrupt on Low */
> -#define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_LOW 0x01
> -
> -/* Register that gives description of what caused interrupt
> - * - latched if set in CFG_ADDRES
> - */
> -#define LIS3L02DQ_REG_WAKE_UP_SRC_ADDR			0x24
> -/* top bit ignored */
> -/* Interrupt Active */
> -#define LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_ACTIVATED	0x40
> -/* Interupts that have been triggered */
> -#define LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_HIGH	0x20
> -#define LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_LOW	0x10
> -#define LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_HIGH	0x08
> -#define LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_LOW	0x04
> -#define LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_HIGH	0x02
> -#define LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_LOW	0x01
> -
> -#define LIS3L02DQ_REG_WAKE_UP_ACK_ADDR			0x25
> -
> -/* Status register */
> -#define LIS3L02DQ_REG_STATUS_ADDR			0x27
> -/* XYZ axis data overrun - first is all overrun? */
> -#define LIS3L02DQ_REG_STATUS_XYZ_OVERRUN		0x80
> -#define LIS3L02DQ_REG_STATUS_Z_OVERRUN			0x40
> -#define LIS3L02DQ_REG_STATUS_Y_OVERRUN			0x20
> -#define LIS3L02DQ_REG_STATUS_X_OVERRUN			0x10
> -/* XYZ new data available - first is all 3 available? */
> -#define LIS3L02DQ_REG_STATUS_XYZ_NEW_DATA		0x08
> -#define LIS3L02DQ_REG_STATUS_Z_NEW_DATA			0x04
> -#define LIS3L02DQ_REG_STATUS_Y_NEW_DATA			0x02
> -#define LIS3L02DQ_REG_STATUS_X_NEW_DATA			0x01
> -
> -/* The accelerometer readings - low and high bytes.
> - * Form of high byte dependent on justification set in ctrl reg
> - */
> -#define LIS3L02DQ_REG_OUT_X_L_ADDR			0x28
> -#define LIS3L02DQ_REG_OUT_X_H_ADDR			0x29
> -#define LIS3L02DQ_REG_OUT_Y_L_ADDR			0x2A
> -#define LIS3L02DQ_REG_OUT_Y_H_ADDR			0x2B
> -#define LIS3L02DQ_REG_OUT_Z_L_ADDR			0x2C
> -#define LIS3L02DQ_REG_OUT_Z_H_ADDR			0x2D
> -
> -/* Threshold values for all axes and both above and below thresholds
> - * - i.e. there is only one value
> - */
> -#define LIS3L02DQ_REG_THS_L_ADDR			0x2E
> -#define LIS3L02DQ_REG_THS_H_ADDR			0x2F
> -
> -#define LIS3L02DQ_DEFAULT_CTRL1 (LIS3L02DQ_REG_CTRL_1_PD_ON	      \
> -				 | LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE \
> -				 | LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE \
> -				 | LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE \
> -				 | LIS3L02DQ_REG_CTRL_1_DF_128)
> -
> -#define LIS3L02DQ_DEFAULT_CTRL2	0
> -
> -#define LIS3L02DQ_MAX_TX 12
> -#define LIS3L02DQ_MAX_RX 12
> -/**
> - * struct lis3l02dq_state - device instance specific data
> - * @us:			actual spi_device
> - * @trig:		data ready trigger registered with iio
> - * @buf_lock:		mutex to protect tx and rx
> - * @tx:			transmit buffer
> - * @rx:			receive buffer
> - **/
> -struct lis3l02dq_state {
> -	struct spi_device		*us;
> -	struct iio_trigger		*trig;
> -	struct mutex			buf_lock;
> -	int				gpio;
> -	bool				trigger_on;
> -
> -	u8	tx[LIS3L02DQ_MAX_RX] ____cacheline_aligned;
> -	u8	rx[LIS3L02DQ_MAX_RX] ____cacheline_aligned;
> -};
> -
> -int lis3l02dq_spi_read_reg_8(struct iio_dev *indio_dev,
> -			     u8 reg_address,
> -			     u8 *val);
> -
> -int lis3l02dq_spi_write_reg_8(struct iio_dev *indio_dev,
> -			      u8 reg_address,
> -			      u8 val);
> -
> -int lis3l02dq_disable_all_events(struct iio_dev *indio_dev);
> -
> -#ifdef CONFIG_IIO_BUFFER
> -/* At the moment triggers are only used for buffer
> - * filling. This may change!
> - */
> -void lis3l02dq_remove_trigger(struct iio_dev *indio_dev);
> -int lis3l02dq_probe_trigger(struct iio_dev *indio_dev);
> -
> -int lis3l02dq_configure_buffer(struct iio_dev *indio_dev);
> -void lis3l02dq_unconfigure_buffer(struct iio_dev *indio_dev);
> -
> -irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private);
> -#define lis3l02dq_th lis3l02dq_data_rdy_trig_poll
> -
> -#else /* CONFIG_IIO_BUFFER */
> -#define lis3l02dq_th lis3l02dq_nobuffer
> -
> -static inline void lis3l02dq_remove_trigger(struct iio_dev *indio_dev)
> -{
> -}
> -
> -static inline int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
> -{
> -	return 0;
> -}
> -
> -static int lis3l02dq_configure_buffer(struct iio_dev *indio_dev)
> -{
> -	return 0;
> -}
> -
> -static inline void lis3l02dq_unconfigure_buffer(struct iio_dev *indio_dev)
> -{
> -}
> -#endif /* CONFIG_IIO_BUFFER */
> -#endif /* SPI_LIS3L02DQ_H_ */
> diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
> deleted file mode 100644
> index 5c3410a74fdb..000000000000
> --- a/drivers/staging/iio/accel/lis3l02dq_core.c
> +++ /dev/null
> @@ -1,814 +0,0 @@
> -/*
> - * lis3l02dq.c	support STMicroelectronics LISD02DQ
> - *		3d 2g Linear Accelerometers via SPI
> - *
> - * Copyright (c) 2007 Jonathan Cameron <jic23@xxxxxxxxxx>
> - *
> - * 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.
> - *
> - * Settings:
> - * 16 bit left justified mode used.
> - */
> -
> -#include <linux/interrupt.h>
> -#include <linux/irq.h>
> -#include <linux/gpio.h>
> -#include <linux/of_gpio.h>
> -#include <linux/mutex.h>
> -#include <linux/device.h>
> -#include <linux/kernel.h>
> -#include <linux/spi/spi.h>
> -#include <linux/slab.h>
> -#include <linux/sysfs.h>
> -#include <linux/module.h>
> -
> -#include <linux/iio/iio.h>
> -#include <linux/iio/sysfs.h>
> -#include <linux/iio/events.h>
> -#include <linux/iio/buffer.h>
> -
> -#include "lis3l02dq.h"
> -
> -/* At the moment the spi framework doesn't allow global setting of cs_change.
> - * It's in the likely to be added comment at the top of spi.h.
> - * This means that use cannot be made of spi_write etc.
> - */
> -/* direct copy of the irq_default_primary_handler */
> -#ifndef CONFIG_IIO_BUFFER
> -static irqreturn_t lis3l02dq_nobuffer(int irq, void *private)
> -{
> -	return IRQ_WAKE_THREAD;
> -}
> -#endif
> -
> -/**
> - * lis3l02dq_spi_read_reg_8() - read single byte from a single register
> - * @indio_dev: iio_dev for this actual device
> - * @reg_address: the address of the register to be read
> - * @val: pass back the resulting value
> - **/
> -int lis3l02dq_spi_read_reg_8(struct iio_dev *indio_dev,
> -			     u8 reg_address, u8 *val)
> -{
> -	struct lis3l02dq_state *st = iio_priv(indio_dev);
> -	int ret;
> -	struct spi_transfer xfer = {
> -		.tx_buf = st->tx,
> -		.rx_buf = st->rx,
> -		.bits_per_word = 8,
> -		.len = 2,
> -	};
> -
> -	mutex_lock(&st->buf_lock);
> -	st->tx[0] = LIS3L02DQ_READ_REG(reg_address);
> -	st->tx[1] = 0;
> -
> -	ret = spi_sync_transfer(st->us, &xfer, 1);
> -	*val = st->rx[1];
> -	mutex_unlock(&st->buf_lock);
> -
> -	return ret;
> -}
> -
> -/**
> - * lis3l02dq_spi_write_reg_8() - write single byte to a register
> - * @indio_dev: iio_dev for this device
> - * @reg_address: the address of the register to be written
> - * @val: the value to write
> - **/
> -int lis3l02dq_spi_write_reg_8(struct iio_dev *indio_dev,
> -			      u8 reg_address,
> -			      u8 val)
> -{
> -	int ret;
> -	struct lis3l02dq_state *st = iio_priv(indio_dev);
> -
> -	mutex_lock(&st->buf_lock);
> -	st->tx[0] = LIS3L02DQ_WRITE_REG(reg_address);
> -	st->tx[1] = val;
> -	ret = spi_write(st->us, st->tx, 2);
> -	mutex_unlock(&st->buf_lock);
> -
> -	return ret;
> -}
> -
> -/**
> - * lisl302dq_spi_write_reg_s16() - write 2 bytes to a pair of registers
> - * @indio_dev: iio_dev for this device
> - * @lower_reg_address: the address of the lower of the two registers.
> - *               Second register is assumed to have address one greater.
> - * @value: value to be written
> - **/
> -static int lis3l02dq_spi_write_reg_s16(struct iio_dev *indio_dev,
> -				       u8 lower_reg_address,
> -				       s16 value)
> -{
> -	int ret;
> -	struct lis3l02dq_state *st = iio_priv(indio_dev);
> -	struct spi_transfer xfers[] = { {
> -			.tx_buf = st->tx,
> -			.bits_per_word = 8,
> -			.len = 2,
> -			.cs_change = 1,
> -		}, {
> -			.tx_buf = st->tx + 2,
> -			.bits_per_word = 8,
> -			.len = 2,
> -		},
> -	};
> -
> -	mutex_lock(&st->buf_lock);
> -	st->tx[0] = LIS3L02DQ_WRITE_REG(lower_reg_address);
> -	st->tx[1] = value & 0xFF;
> -	st->tx[2] = LIS3L02DQ_WRITE_REG(lower_reg_address + 1);
> -	st->tx[3] = (value >> 8) & 0xFF;
> -
> -	ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
> -	mutex_unlock(&st->buf_lock);
> -
> -	return ret;
> -}
> -
> -static int lis3l02dq_read_reg_s16(struct iio_dev *indio_dev,
> -				  u8 lower_reg_address,
> -				  int *val)
> -{
> -	struct lis3l02dq_state *st = iio_priv(indio_dev);
> -	int ret;
> -	s16 tempval;
> -	struct spi_transfer xfers[] = { {
> -			.tx_buf = st->tx,
> -			.rx_buf = st->rx,
> -			.bits_per_word = 8,
> -			.len = 2,
> -			.cs_change = 1,
> -		}, {
> -			.tx_buf = st->tx + 2,
> -			.rx_buf = st->rx + 2,
> -			.bits_per_word = 8,
> -			.len = 2,
> -		},
> -	};
> -
> -	mutex_lock(&st->buf_lock);
> -	st->tx[0] = LIS3L02DQ_READ_REG(lower_reg_address);
> -	st->tx[1] = 0;
> -	st->tx[2] = LIS3L02DQ_READ_REG(lower_reg_address + 1);
> -	st->tx[3] = 0;
> -
> -	ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
> -	if (ret) {
> -		dev_err(&st->us->dev, "problem when reading 16 bit register");
> -		goto error_ret;
> -	}
> -	tempval = (s16)(st->rx[1]) | ((s16)(st->rx[3]) << 8);
> -
> -	*val = tempval;
> -error_ret:
> -	mutex_unlock(&st->buf_lock);
> -	return ret;
> -}
> -
> -enum lis3l02dq_rm_ind {
> -	LIS3L02DQ_ACCEL,
> -	LIS3L02DQ_GAIN,
> -	LIS3L02DQ_BIAS,
> -};
> -
> -static u8 lis3l02dq_axis_map[3][3] = {
> -	[LIS3L02DQ_ACCEL] = { LIS3L02DQ_REG_OUT_X_L_ADDR,
> -			      LIS3L02DQ_REG_OUT_Y_L_ADDR,
> -			      LIS3L02DQ_REG_OUT_Z_L_ADDR },
> -	[LIS3L02DQ_GAIN] = { LIS3L02DQ_REG_GAIN_X_ADDR,
> -			     LIS3L02DQ_REG_GAIN_Y_ADDR,
> -			     LIS3L02DQ_REG_GAIN_Z_ADDR },
> -	[LIS3L02DQ_BIAS] = { LIS3L02DQ_REG_OFFSET_X_ADDR,
> -			     LIS3L02DQ_REG_OFFSET_Y_ADDR,
> -			     LIS3L02DQ_REG_OFFSET_Z_ADDR }
> -};
> -
> -static int lis3l02dq_read_thresh(struct iio_dev *indio_dev,
> -				 const struct iio_chan_spec *chan,
> -				 enum iio_event_type type,
> -				 enum iio_event_direction dir,
> -				 enum iio_event_info info,
> -				 int *val, int *val2)
> -{
> -	int ret;
> -
> -	ret = lis3l02dq_read_reg_s16(indio_dev, LIS3L02DQ_REG_THS_L_ADDR, val);
> -	if (ret)
> -		return ret;
> -	return IIO_VAL_INT;
> -}
> -
> -static int lis3l02dq_write_thresh(struct iio_dev *indio_dev,
> -				  const struct iio_chan_spec *chan,
> -				  enum iio_event_type type,
> -				  enum iio_event_direction dir,
> -				  enum iio_event_info info,
> -				  int val, int val2)
> -{
> -	u16 value = val;
> -
> -	return lis3l02dq_spi_write_reg_s16(indio_dev,
> -					   LIS3L02DQ_REG_THS_L_ADDR,
> -					   value);
> -}
> -
> -static int lis3l02dq_write_raw(struct iio_dev *indio_dev,
> -			       struct iio_chan_spec const *chan,
> -			       int val,
> -			       int val2,
> -			       long mask)
> -{
> -	int ret = -EINVAL, reg;
> -	u8 uval;
> -	s8 sval;
> -
> -	switch (mask) {
> -	case IIO_CHAN_INFO_CALIBBIAS:
> -		if (val > 255 || val < -256)
> -			return -EINVAL;
> -		sval = val;
> -		reg = lis3l02dq_axis_map[LIS3L02DQ_BIAS][chan->address];
> -		ret = lis3l02dq_spi_write_reg_8(indio_dev, reg, sval);
> -		break;
> -	case IIO_CHAN_INFO_CALIBSCALE:
> -		if (val & ~0xFF)
> -			return -EINVAL;
> -		uval = val;
> -		reg = lis3l02dq_axis_map[LIS3L02DQ_GAIN][chan->address];
> -		ret = lis3l02dq_spi_write_reg_8(indio_dev, reg, uval);
> -		break;
> -	}
> -	return ret;
> -}
> -
> -static int lis3l02dq_read_raw(struct iio_dev *indio_dev,
> -			      struct iio_chan_spec const *chan,
> -			      int *val,
> -			      int *val2,
> -			      long mask)
> -{
> -	u8 utemp;
> -	s8 stemp;
> -	ssize_t ret = 0;
> -	u8 reg;
> -
> -	switch (mask) {
> -	case IIO_CHAN_INFO_RAW:
> -		/* Take the iio_dev status lock */
> -		mutex_lock(&indio_dev->mlock);
> -		if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
> -			ret = -EBUSY;
> -		} else {
> -			reg = lis3l02dq_axis_map
> -				[LIS3L02DQ_ACCEL][chan->address];
> -			ret = lis3l02dq_read_reg_s16(indio_dev, reg, val);
> -		}
> -		mutex_unlock(&indio_dev->mlock);
> -		if (ret < 0)
> -			goto error_ret;
> -		return IIO_VAL_INT;
> -	case IIO_CHAN_INFO_SCALE:
> -		*val = 0;
> -		*val2 = 9580;
> -		return IIO_VAL_INT_PLUS_MICRO;
> -	case IIO_CHAN_INFO_CALIBSCALE:
> -		reg = lis3l02dq_axis_map[LIS3L02DQ_GAIN][chan->address];
> -		ret = lis3l02dq_spi_read_reg_8(indio_dev, reg, &utemp);
> -		if (ret)
> -			goto error_ret;
> -		/* to match with what previous code does */
> -		*val = utemp;
> -		return IIO_VAL_INT;
> -
> -	case IIO_CHAN_INFO_CALIBBIAS:
> -		reg = lis3l02dq_axis_map[LIS3L02DQ_BIAS][chan->address];
> -		ret = lis3l02dq_spi_read_reg_8(indio_dev, reg, (u8 *)&stemp);
> -		/* to match with what previous code does */
> -		*val = stemp;
> -		return IIO_VAL_INT;
> -	}
> -error_ret:
> -	return ret;
> -}
> -
> -static ssize_t lis3l02dq_read_frequency(struct device *dev,
> -					struct device_attribute *attr,
> -					char *buf)
> -{
> -	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> -	int ret, len = 0;
> -	s8 t;
> -
> -	ret = lis3l02dq_spi_read_reg_8(indio_dev,
> -				       LIS3L02DQ_REG_CTRL_1_ADDR,
> -				       (u8 *)&t);
> -	if (ret)
> -		return ret;
> -	t &= LIS3L02DQ_DEC_MASK;
> -	switch (t) {
> -	case LIS3L02DQ_REG_CTRL_1_DF_128:
> -		len = sprintf(buf, "280\n");
> -		break;
> -	case LIS3L02DQ_REG_CTRL_1_DF_64:
> -		len = sprintf(buf, "560\n");
> -		break;
> -	case LIS3L02DQ_REG_CTRL_1_DF_32:
> -		len = sprintf(buf, "1120\n");
> -		break;
> -	case LIS3L02DQ_REG_CTRL_1_DF_8:
> -		len = sprintf(buf, "4480\n");
> -		break;
> -	}
> -	return len;
> -}
> -
> -static ssize_t lis3l02dq_write_frequency(struct device *dev,
> -					 struct device_attribute *attr,
> -					 const char *buf,
> -					 size_t len)
> -{
> -	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> -	unsigned long val;
> -	int ret;
> -	u8 t;
> -
> -	ret = kstrtoul(buf, 10, &val);
> -	if (ret)
> -		return ret;
> -
> -	mutex_lock(&indio_dev->mlock);
> -	ret = lis3l02dq_spi_read_reg_8(indio_dev,
> -				       LIS3L02DQ_REG_CTRL_1_ADDR,
> -				       &t);
> -	if (ret)
> -		goto error_ret_mutex;
> -	/* Wipe the bits clean */
> -	t &= ~LIS3L02DQ_DEC_MASK;
> -	switch (val) {
> -	case 280:
> -		t |= LIS3L02DQ_REG_CTRL_1_DF_128;
> -		break;
> -	case 560:
> -		t |= LIS3L02DQ_REG_CTRL_1_DF_64;
> -		break;
> -	case 1120:
> -		t |= LIS3L02DQ_REG_CTRL_1_DF_32;
> -		break;
> -	case 4480:
> -		t |= LIS3L02DQ_REG_CTRL_1_DF_8;
> -		break;
> -	default:
> -		ret = -EINVAL;
> -		goto error_ret_mutex;
> -	}
> -
> -	ret = lis3l02dq_spi_write_reg_8(indio_dev,
> -					LIS3L02DQ_REG_CTRL_1_ADDR,
> -					t);
> -
> -error_ret_mutex:
> -	mutex_unlock(&indio_dev->mlock);
> -
> -	return ret ? ret : len;
> -}
> -
> -static int lis3l02dq_initial_setup(struct iio_dev *indio_dev)
> -{
> -	struct lis3l02dq_state *st = iio_priv(indio_dev);
> -	int ret;
> -	u8 val, valtest;
> -
> -	st->us->mode = SPI_MODE_3;
> -
> -	spi_setup(st->us);
> -
> -	val = LIS3L02DQ_DEFAULT_CTRL1;
> -	/* Write suitable defaults to ctrl1 */
> -	ret = lis3l02dq_spi_write_reg_8(indio_dev,
> -					LIS3L02DQ_REG_CTRL_1_ADDR,
> -					val);
> -	if (ret) {
> -		dev_err(&st->us->dev, "problem with setup control register 1");
> -		goto err_ret;
> -	}
> -	/* Repeat as sometimes doesn't work first time? */
> -	ret = lis3l02dq_spi_write_reg_8(indio_dev,
> -					LIS3L02DQ_REG_CTRL_1_ADDR,
> -					val);
> -	if (ret) {
> -		dev_err(&st->us->dev, "problem with setup control register 1");
> -		goto err_ret;
> -	}
> -
> -	/*
> -	 * Read back to check this has worked acts as loose test of correct
> -	 * chip
> -	 */
> -	ret = lis3l02dq_spi_read_reg_8(indio_dev,
> -				       LIS3L02DQ_REG_CTRL_1_ADDR,
> -				       &valtest);
> -	if (ret || (valtest != val)) {
> -		dev_err(&indio_dev->dev,
> -			"device not playing ball %d %d\n", valtest, val);
> -		ret = -EINVAL;
> -		goto err_ret;
> -	}
> -
> -	val = LIS3L02DQ_DEFAULT_CTRL2;
> -	ret = lis3l02dq_spi_write_reg_8(indio_dev,
> -					LIS3L02DQ_REG_CTRL_2_ADDR,
> -					val);
> -	if (ret) {
> -		dev_err(&st->us->dev, "problem with setup control register 2");
> -		goto err_ret;
> -	}
> -
> -	val = LIS3L02DQ_REG_WAKE_UP_CFG_LATCH_SRC;
> -	ret = lis3l02dq_spi_write_reg_8(indio_dev,
> -					LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
> -					val);
> -	if (ret)
> -		dev_err(&st->us->dev, "problem with interrupt cfg register");
> -err_ret:
> -
> -	return ret;
> -}
> -
> -static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
> -			      lis3l02dq_read_frequency,
> -			      lis3l02dq_write_frequency);
> -
> -static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("280 560 1120 4480");
> -
> -static irqreturn_t lis3l02dq_event_handler(int irq, void *private)
> -{
> -	struct iio_dev *indio_dev = private;
> -	u8 t;
> -
> -	s64 timestamp = iio_get_time_ns(indio_dev);
> -
> -	lis3l02dq_spi_read_reg_8(indio_dev,
> -				 LIS3L02DQ_REG_WAKE_UP_SRC_ADDR,
> -				 &t);
> -
> -	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_HIGH)
> -		iio_push_event(indio_dev,
> -			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
> -						  0,
> -						  IIO_MOD_Z,
> -						  IIO_EV_TYPE_THRESH,
> -						  IIO_EV_DIR_RISING),
> -			       timestamp);
> -
> -	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_LOW)
> -		iio_push_event(indio_dev,
> -			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
> -						  0,
> -						  IIO_MOD_Z,
> -						  IIO_EV_TYPE_THRESH,
> -						  IIO_EV_DIR_FALLING),
> -			       timestamp);
> -
> -	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_HIGH)
> -		iio_push_event(indio_dev,
> -			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
> -						  0,
> -						  IIO_MOD_Y,
> -						  IIO_EV_TYPE_THRESH,
> -						  IIO_EV_DIR_RISING),
> -			       timestamp);
> -
> -	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_LOW)
> -		iio_push_event(indio_dev,
> -			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
> -						  0,
> -						  IIO_MOD_Y,
> -						  IIO_EV_TYPE_THRESH,
> -						  IIO_EV_DIR_FALLING),
> -			       timestamp);
> -
> -	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_HIGH)
> -		iio_push_event(indio_dev,
> -			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
> -						  0,
> -						  IIO_MOD_X,
> -						  IIO_EV_TYPE_THRESH,
> -						  IIO_EV_DIR_RISING),
> -			       timestamp);
> -
> -	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_LOW)
> -		iio_push_event(indio_dev,
> -			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
> -						  0,
> -						  IIO_MOD_X,
> -						  IIO_EV_TYPE_THRESH,
> -						  IIO_EV_DIR_FALLING),
> -			       timestamp);
> -
> -	/* Ack and allow for new interrupts */
> -	lis3l02dq_spi_read_reg_8(indio_dev,
> -				 LIS3L02DQ_REG_WAKE_UP_ACK_ADDR,
> -				 &t);
> -
> -	return IRQ_HANDLED;
> -}
> -
> -static const struct iio_event_spec lis3l02dq_event[] = {
> -	{
> -		.type = IIO_EV_TYPE_THRESH,
> -		.dir = IIO_EV_DIR_RISING,
> -		.mask_separate = BIT(IIO_EV_INFO_ENABLE),
> -		.mask_shared_by_type = BIT(IIO_EV_INFO_VALUE),
> -	}, {
> -		.type = IIO_EV_TYPE_THRESH,
> -		.dir = IIO_EV_DIR_FALLING,
> -		.mask_separate = BIT(IIO_EV_INFO_ENABLE),
> -		.mask_shared_by_type = BIT(IIO_EV_INFO_VALUE),
> -	}
> -};
> -
> -#define LIS3L02DQ_CHAN(index, mod)				\
> -	{							\
> -		.type = IIO_ACCEL,				\
> -		.modified = 1,					\
> -		.channel2 = mod,				\
> -		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	\
> -			BIT(IIO_CHAN_INFO_CALIBSCALE) |		\
> -			BIT(IIO_CHAN_INFO_CALIBBIAS),		\
> -		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
> -		.address = index,				\
> -		.scan_index = index,				\
> -		.scan_type = {					\
> -			.sign = 's',				\
> -			.realbits = 12,				\
> -			.storagebits = 16,			\
> -		},						\
> -		.event_spec = lis3l02dq_event,			\
> -		.num_event_specs = ARRAY_SIZE(lis3l02dq_event),	\
> -	 }
> -
> -static const struct iio_chan_spec lis3l02dq_channels[] = {
> -	LIS3L02DQ_CHAN(0, IIO_MOD_X),
> -	LIS3L02DQ_CHAN(1, IIO_MOD_Y),
> -	LIS3L02DQ_CHAN(2, IIO_MOD_Z),
> -	IIO_CHAN_SOFT_TIMESTAMP(3)
> -};
> -
> -static int lis3l02dq_read_event_config(struct iio_dev *indio_dev,
> -				       const struct iio_chan_spec *chan,
> -				       enum iio_event_type type,
> -				       enum iio_event_direction dir)
> -{
> -	u8 val;
> -	int ret;
> -	u8 mask = 1 << (chan->channel2 * 2 + (dir == IIO_EV_DIR_RISING));
> -
> -	ret = lis3l02dq_spi_read_reg_8(indio_dev,
> -				       LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
> -				       &val);
> -	if (ret < 0)
> -		return ret;
> -
> -	return !!(val & mask);
> -}
> -
> -int lis3l02dq_disable_all_events(struct iio_dev *indio_dev)
> -{
> -	int ret;
> -	u8 control, val;
> -
> -	ret = lis3l02dq_spi_read_reg_8(indio_dev,
> -				       LIS3L02DQ_REG_CTRL_2_ADDR,
> -				       &control);
> -
> -	control &= ~LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT;
> -	ret = lis3l02dq_spi_write_reg_8(indio_dev,
> -					LIS3L02DQ_REG_CTRL_2_ADDR,
> -					control);
> -	if (ret)
> -		goto error_ret;
> -	/* Also for consistency clear the mask */
> -	ret = lis3l02dq_spi_read_reg_8(indio_dev,
> -				       LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
> -				       &val);
> -	if (ret)
> -		goto error_ret;
> -	val &= ~0x3f;
> -
> -	ret = lis3l02dq_spi_write_reg_8(indio_dev,
> -					LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
> -					val);
> -	if (ret)
> -		goto error_ret;
> -
> -	ret = control;
> -error_ret:
> -	return ret;
> -}
> -
> -static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
> -					const struct iio_chan_spec *chan,
> -					enum iio_event_type type,
> -					enum iio_event_direction dir,
> -					int state)
> -{
> -	int ret = 0;
> -	u8 val, control;
> -	u8 currentlyset;
> -	bool changed = false;
> -	u8 mask = 1 << (chan->channel2 * 2 + (dir == IIO_EV_DIR_RISING));
> -
> -	mutex_lock(&indio_dev->mlock);
> -	/* read current control */
> -	ret = lis3l02dq_spi_read_reg_8(indio_dev,
> -				       LIS3L02DQ_REG_CTRL_2_ADDR,
> -				       &control);
> -	if (ret)
> -		goto error_ret;
> -	ret = lis3l02dq_spi_read_reg_8(indio_dev,
> -				       LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
> -				       &val);
> -	if (ret < 0)
> -		goto error_ret;
> -	currentlyset = val & mask;
> -
> -	if (!currentlyset && state) {
> -		changed = true;
> -		val |= mask;
> -	} else if (currentlyset && !state) {
> -		changed = true;
> -		val &= ~mask;
> -	}
> -
> -	if (changed) {
> -		ret = lis3l02dq_spi_write_reg_8(indio_dev,
> -						LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
> -						val);
> -		if (ret)
> -			goto error_ret;
> -		control = val & 0x3f ?
> -			(control | LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT) :
> -			(control & ~LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT);
> -		ret = lis3l02dq_spi_write_reg_8(indio_dev,
> -						LIS3L02DQ_REG_CTRL_2_ADDR,
> -						control);
> -		if (ret)
> -			goto error_ret;
> -	}
> -
> -error_ret:
> -	mutex_unlock(&indio_dev->mlock);
> -	return ret;
> -}
> -
> -static struct attribute *lis3l02dq_attributes[] = {
> -	&iio_dev_attr_sampling_frequency.dev_attr.attr,
> -	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
> -	NULL
> -};
> -
> -static const struct attribute_group lis3l02dq_attribute_group = {
> -	.attrs = lis3l02dq_attributes,
> -};
> -
> -static const struct iio_info lis3l02dq_info = {
> -	.read_raw = &lis3l02dq_read_raw,
> -	.write_raw = &lis3l02dq_write_raw,
> -	.read_event_value = &lis3l02dq_read_thresh,
> -	.write_event_value = &lis3l02dq_write_thresh,
> -	.write_event_config = &lis3l02dq_write_event_config,
> -	.read_event_config = &lis3l02dq_read_event_config,
> -	.driver_module = THIS_MODULE,
> -	.attrs = &lis3l02dq_attribute_group,
> -};
> -
> -static int lis3l02dq_probe(struct spi_device *spi)
> -{
> -	int ret;
> -	struct lis3l02dq_state *st;
> -	struct iio_dev *indio_dev;
> -
> -	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
> -	if (!indio_dev)
> -		return -ENOMEM;
> -	st = iio_priv(indio_dev);
> -	/* this is only used for removal purposes */
> -	spi_set_drvdata(spi, indio_dev);
> -
> -	st->us = spi;
> -	st->gpio = of_get_gpio(spi->dev.of_node, 0);
> -	mutex_init(&st->buf_lock);
> -	indio_dev->name = spi->dev.driver->name;
> -	indio_dev->dev.parent = &spi->dev;
> -	indio_dev->info = &lis3l02dq_info;
> -	indio_dev->channels = lis3l02dq_channels;
> -	indio_dev->num_channels = ARRAY_SIZE(lis3l02dq_channels);
> -
> -	indio_dev->modes = INDIO_DIRECT_MODE;
> -
> -	ret = lis3l02dq_configure_buffer(indio_dev);
> -	if (ret)
> -		return ret;
> -
> -	if (spi->irq) {
> -		ret = request_threaded_irq(st->us->irq,
> -					   &lis3l02dq_th,
> -					   &lis3l02dq_event_handler,
> -					   IRQF_TRIGGER_RISING,
> -					   "lis3l02dq",
> -					   indio_dev);
> -		if (ret)
> -			goto error_unreg_buffer_funcs;
> -
> -		ret = lis3l02dq_probe_trigger(indio_dev);
> -		if (ret)
> -			goto error_free_interrupt;
> -	}
> -
> -	/* Get the device into a sane initial state */
> -	ret = lis3l02dq_initial_setup(indio_dev);
> -	if (ret)
> -		goto error_remove_trigger;
> -
> -	ret = iio_device_register(indio_dev);
> -	if (ret)
> -		goto error_remove_trigger;
> -
> -	return 0;
> -
> -error_remove_trigger:
> -	if (spi->irq)
> -		lis3l02dq_remove_trigger(indio_dev);
> -error_free_interrupt:
> -	if (spi->irq)
> -		free_irq(st->us->irq, indio_dev);
> -error_unreg_buffer_funcs:
> -	lis3l02dq_unconfigure_buffer(indio_dev);
> -	return ret;
> -}
> -
> -/* Power down the device */
> -static int lis3l02dq_stop_device(struct iio_dev *indio_dev)
> -{
> -	int ret;
> -	struct lis3l02dq_state *st = iio_priv(indio_dev);
> -	u8 val = 0;
> -
> -	mutex_lock(&indio_dev->mlock);
> -	ret = lis3l02dq_spi_write_reg_8(indio_dev,
> -					LIS3L02DQ_REG_CTRL_1_ADDR,
> -					val);
> -	if (ret) {
> -		dev_err(&st->us->dev, "problem with turning device off: ctrl1");
> -		goto err_ret;
> -	}
> -
> -	ret = lis3l02dq_spi_write_reg_8(indio_dev,
> -					LIS3L02DQ_REG_CTRL_2_ADDR,
> -					val);
> -	if (ret)
> -		dev_err(&st->us->dev, "problem with turning device off: ctrl2");
> -err_ret:
> -	mutex_unlock(&indio_dev->mlock);
> -	return ret;
> -}
> -
> -/* fixme, confirm ordering in this function */
> -static int lis3l02dq_remove(struct spi_device *spi)
> -{
> -	struct iio_dev *indio_dev = spi_get_drvdata(spi);
> -	struct lis3l02dq_state *st = iio_priv(indio_dev);
> -
> -	iio_device_unregister(indio_dev);
> -
> -	lis3l02dq_disable_all_events(indio_dev);
> -	lis3l02dq_stop_device(indio_dev);
> -
> -	if (spi->irq)
> -		free_irq(st->us->irq, indio_dev);
> -
> -	lis3l02dq_remove_trigger(indio_dev);
> -	lis3l02dq_unconfigure_buffer(indio_dev);
> -
> -	return 0;
> -}
> -
> -static struct spi_driver lis3l02dq_driver = {
> -	.driver = {
> -		.name = "lis3l02dq",
> -	},
> -	.probe = lis3l02dq_probe,
> -	.remove = lis3l02dq_remove,
> -};
> -module_spi_driver(lis3l02dq_driver);
> -
> -MODULE_AUTHOR("Jonathan Cameron <jic23@xxxxxxxxxx>");
> -MODULE_DESCRIPTION("ST LIS3L02DQ Accelerometer SPI driver");
> -MODULE_LICENSE("GPL v2");
> -MODULE_ALIAS("spi:lis3l02dq");
> diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
> deleted file mode 100644
> index 50c162e0c31f..000000000000
> --- a/drivers/staging/iio/accel/lis3l02dq_ring.c
> +++ /dev/null
> @@ -1,428 +0,0 @@
> -#include <linux/interrupt.h>
> -#include <linux/gpio.h>
> -#include <linux/mutex.h>
> -#include <linux/kernel.h>
> -#include <linux/spi/spi.h>
> -#include <linux/slab.h>
> -#include <linux/export.h>
> -
> -#include <linux/iio/iio.h>
> -#include <linux/iio/kfifo_buf.h>
> -#include <linux/iio/trigger.h>
> -#include <linux/iio/trigger_consumer.h>
> -#include "lis3l02dq.h"
> -
> -/**
> - * combine_8_to_16() utility function to munge two u8s into u16
> - **/
> -static inline u16 combine_8_to_16(u8 lower, u8 upper)
> -{
> -	u16 _lower = lower;
> -	u16 _upper = upper;
> -
> -	return _lower | (_upper << 8);
> -}
> -
> -/**
> - * lis3l02dq_data_rdy_trig_poll() the event handler for the data rdy trig
> - **/
> -irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private)
> -{
> -	struct iio_dev *indio_dev = private;
> -	struct lis3l02dq_state *st = iio_priv(indio_dev);
> -
> -	if (st->trigger_on) {
> -		iio_trigger_poll(st->trig);
> -		return IRQ_HANDLED;
> -	}
> -
> -	return IRQ_WAKE_THREAD;
> -}
> -
> -static const u8 read_all_tx_array[] = {
> -	LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_X_L_ADDR), 0,
> -	LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_X_H_ADDR), 0,
> -	LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_Y_L_ADDR), 0,
> -	LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_Y_H_ADDR), 0,
> -	LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_Z_L_ADDR), 0,
> -	LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_Z_H_ADDR), 0,
> -};
> -
> -/**
> - * lis3l02dq_read_all() Reads all channels currently selected
> - * @indio_dev:	IIO device state
> - * @rx_array:	(dma capable) receive array, must be at least
> - *		4*number of channels
> - **/
> -static int lis3l02dq_read_all(struct iio_dev *indio_dev, u8 *rx_array)
> -{
> -	struct lis3l02dq_state *st = iio_priv(indio_dev);
> -	struct spi_transfer *xfers;
> -	struct spi_message msg;
> -	int ret, i, j = 0;
> -
> -	xfers = kcalloc(bitmap_weight(indio_dev->active_scan_mask,
> -				      indio_dev->masklength) * 2,
> -			sizeof(*xfers), GFP_KERNEL);
> -	if (!xfers)
> -		return -ENOMEM;
> -
> -	mutex_lock(&st->buf_lock);
> -
> -	for (i = 0; i < ARRAY_SIZE(read_all_tx_array) / 4; i++)
> -		if (test_bit(i, indio_dev->active_scan_mask)) {
> -			/* lower byte */
> -			xfers[j].tx_buf = st->tx + (2 * j);
> -			st->tx[2 * j] = read_all_tx_array[i * 4];
> -			st->tx[2 * j + 1] = 0;
> -			if (rx_array)
> -				xfers[j].rx_buf = rx_array + (j * 2);
> -			xfers[j].bits_per_word = 8;
> -			xfers[j].len = 2;
> -			xfers[j].cs_change = 1;
> -			j++;
> -
> -			/* upper byte */
> -			xfers[j].tx_buf = st->tx + (2 * j);
> -			st->tx[2 * j] = read_all_tx_array[i * 4 + 2];
> -			st->tx[2 * j + 1] = 0;
> -			if (rx_array)
> -				xfers[j].rx_buf = rx_array + (j * 2);
> -			xfers[j].bits_per_word = 8;
> -			xfers[j].len = 2;
> -			xfers[j].cs_change = 1;
> -			j++;
> -		}
> -
> -	/* After these are transmitted, the rx_buff should have
> -	 * values in alternate bytes
> -	 */
> -	spi_message_init(&msg);
> -	for (j = 0; j < bitmap_weight(indio_dev->active_scan_mask,
> -				      indio_dev->masklength) * 2; j++)
> -		spi_message_add_tail(&xfers[j], &msg);
> -
> -	ret = spi_sync(st->us, &msg);
> -	mutex_unlock(&st->buf_lock);
> -	kfree(xfers);
> -
> -	return ret;
> -}
> -
> -static int lis3l02dq_get_buffer_element(struct iio_dev *indio_dev,
> -					u8 *buf)
> -{
> -	int ret, i;
> -	u8 *rx_array;
> -	s16 *data = (s16 *)buf;
> -	int scan_count = bitmap_weight(indio_dev->active_scan_mask,
> -				       indio_dev->masklength);
> -
> -	rx_array = kcalloc(4, scan_count, GFP_KERNEL);
> -	if (!rx_array)
> -		return -ENOMEM;
> -	ret = lis3l02dq_read_all(indio_dev, rx_array);
> -	if (ret < 0) {
> -		kfree(rx_array);
> -		return ret;
> -	}
> -	for (i = 0; i < scan_count; i++)
> -		data[i] = combine_8_to_16(rx_array[i * 4 + 1],
> -					rx_array[i * 4 + 3]);
> -	kfree(rx_array);
> -
> -	return i * sizeof(data[0]);
> -}
> -
> -static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p)
> -{
> -	struct iio_poll_func *pf = p;
> -	struct iio_dev *indio_dev = pf->indio_dev;
> -	int len = 0;
> -	char *data;
> -
> -	data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
> -	if (!data)
> -		goto done;
> -
> -	if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
> -		len = lis3l02dq_get_buffer_element(indio_dev, data);
> -
> -	iio_push_to_buffers_with_timestamp(indio_dev, data, pf->timestamp);
> -
> -	kfree(data);
> -done:
> -	iio_trigger_notify_done(indio_dev->trig);
> -	return IRQ_HANDLED;
> -}
> -
> -/* Caller responsible for locking as necessary. */
> -static int
> -__lis3l02dq_write_data_ready_config(struct iio_dev *indio_dev, bool state)
> -{
> -	int ret;
> -	u8 valold;
> -	bool currentlyset;
> -	struct lis3l02dq_state *st = iio_priv(indio_dev);
> -
> -	/* Get the current event mask register */
> -	ret = lis3l02dq_spi_read_reg_8(indio_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) {
> -		/* Disable the data ready signal */
> -		valold &= ~LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;
> -
> -		/* The double write is to overcome a hardware bug? */
> -		ret = lis3l02dq_spi_write_reg_8(indio_dev,
> -						LIS3L02DQ_REG_CTRL_2_ADDR,
> -						valold);
> -		if (ret)
> -			goto error_ret;
> -		ret = lis3l02dq_spi_write_reg_8(indio_dev,
> -						LIS3L02DQ_REG_CTRL_2_ADDR,
> -						valold);
> -		if (ret)
> -			goto error_ret;
> -		st->trigger_on = false;
> -	/* Enable requested */
> -	} else if (state && !currentlyset) {
> -		/* If not set, enable requested
> -		 * first disable all events
> -		 */
> -		ret = lis3l02dq_disable_all_events(indio_dev);
> -		if (ret < 0)
> -			goto error_ret;
> -
> -		valold = ret |
> -			LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;
> -
> -		st->trigger_on = true;
> -		ret = lis3l02dq_spi_write_reg_8(indio_dev,
> -						LIS3L02DQ_REG_CTRL_2_ADDR,
> -						valold);
> -		if (ret)
> -			goto error_ret;
> -	}
> -
> -	return 0;
> -error_ret:
> -	return ret;
> -}
> -
> -/**
> - * lis3l02dq_data_rdy_trigger_set_state() set datardy interrupt state
> - *
> - * If disabling the interrupt also does a final read to ensure it is clear.
> - * This is only important in some cases where the scan enable elements are
> - * switched before the buffer is reenabled.
> - **/
> -static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig,
> -						bool state)
> -{
> -	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
> -	int ret = 0;
> -	u8 t;
> -
> -	__lis3l02dq_write_data_ready_config(indio_dev, state);
> -	if (!state) {
> -		/*
> -		 * A possible quirk with the handler is currently worked around
> -		 * by ensuring outstanding read events are cleared.
> -		 */
> -		ret = lis3l02dq_read_all(indio_dev, NULL);
> -	}
> -	lis3l02dq_spi_read_reg_8(indio_dev,
> -				 LIS3L02DQ_REG_WAKE_UP_SRC_ADDR,
> -				 &t);
> -	return ret;
> -}
> -
> -/**
> - * lis3l02dq_trig_try_reen() try reenabling irq for data rdy trigger
> - * @trig:	the datardy trigger
> - */
> -static int lis3l02dq_trig_try_reen(struct iio_trigger *trig)
> -{
> -	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
> -	struct lis3l02dq_state *st = iio_priv(indio_dev);
> -	int i;
> -
> -	/* If gpio still high (or high again)
> -	 * In theory possible we will need to do this several times
> -	 */
> -	for (i = 0; i < 5; i++)
> -		if (gpio_get_value(st->gpio))
> -			lis3l02dq_read_all(indio_dev, NULL);
> -		else
> -			break;
> -	if (i == 5)
> -		pr_info("Failed to clear the interrupt for lis3l02dq\n");
> -
> -	/* irq reenabled so success! */
> -	return 0;
> -}
> -
> -static const struct iio_trigger_ops lis3l02dq_trigger_ops = {
> -	.owner = THIS_MODULE,
> -	.set_trigger_state = &lis3l02dq_data_rdy_trigger_set_state,
> -	.try_reenable = &lis3l02dq_trig_try_reen,
> -};
> -
> -int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
> -{
> -	int ret;
> -	struct lis3l02dq_state *st = iio_priv(indio_dev);
> -
> -	st->trig = iio_trigger_alloc("lis3l02dq-dev%d", indio_dev->id);
> -	if (!st->trig) {
> -		ret = -ENOMEM;
> -		goto error_ret;
> -	}
> -
> -	st->trig->dev.parent = &st->us->dev;
> -	st->trig->ops = &lis3l02dq_trigger_ops;
> -	iio_trigger_set_drvdata(st->trig, indio_dev);
> -	ret = iio_trigger_register(st->trig);
> -	if (ret)
> -		goto error_free_trig;
> -
> -	return 0;
> -
> -error_free_trig:
> -	iio_trigger_free(st->trig);
> -error_ret:
> -	return ret;
> -}
> -
> -void lis3l02dq_remove_trigger(struct iio_dev *indio_dev)
> -{
> -	struct lis3l02dq_state *st = iio_priv(indio_dev);
> -
> -	iio_trigger_unregister(st->trig);
> -	iio_trigger_free(st->trig);
> -}
> -
> -void lis3l02dq_unconfigure_buffer(struct iio_dev *indio_dev)
> -{
> -	iio_dealloc_pollfunc(indio_dev->pollfunc);
> -	iio_kfifo_free(indio_dev->buffer);
> -}
> -
> -static int lis3l02dq_buffer_postenable(struct iio_dev *indio_dev)
> -{
> -	/* Disable unwanted channels otherwise the interrupt will not clear */
> -	u8 t;
> -	int ret;
> -	bool oneenabled = false;
> -
> -	ret = lis3l02dq_spi_read_reg_8(indio_dev,
> -				       LIS3L02DQ_REG_CTRL_1_ADDR,
> -				       &t);
> -	if (ret)
> -		goto error_ret;
> -
> -	if (test_bit(0, indio_dev->active_scan_mask)) {
> -		t |= LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE;
> -		oneenabled = true;
> -	} else {
> -		t &= ~LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE;
> -	}
> -	if (test_bit(1, indio_dev->active_scan_mask)) {
> -		t |= LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE;
> -		oneenabled = true;
> -	} else {
> -		t &= ~LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE;
> -	}
> -	if (test_bit(2, indio_dev->active_scan_mask)) {
> -		t |= LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE;
> -		oneenabled = true;
> -	} else {
> -		t &= ~LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE;
> -	}
> -	if (!oneenabled) /* what happens in this case is unknown */
> -		return -EINVAL;
> -	ret = lis3l02dq_spi_write_reg_8(indio_dev,
> -					LIS3L02DQ_REG_CTRL_1_ADDR,
> -					t);
> -	if (ret)
> -		goto error_ret;
> -
> -	return iio_triggered_buffer_postenable(indio_dev);
> -error_ret:
> -	return ret;
> -}
> -
> -/* Turn all channels on again */
> -static int lis3l02dq_buffer_predisable(struct iio_dev *indio_dev)
> -{
> -	u8 t;
> -	int ret;
> -
> -	ret = iio_triggered_buffer_predisable(indio_dev);
> -	if (ret)
> -		goto error_ret;
> -
> -	ret = lis3l02dq_spi_read_reg_8(indio_dev,
> -				       LIS3L02DQ_REG_CTRL_1_ADDR,
> -				       &t);
> -	if (ret)
> -		goto error_ret;
> -	t |= LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE |
> -		LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE |
> -		LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE;
> -
> -	ret = lis3l02dq_spi_write_reg_8(indio_dev,
> -					LIS3L02DQ_REG_CTRL_1_ADDR,
> -					t);
> -
> -error_ret:
> -	return ret;
> -}
> -
> -static const struct iio_buffer_setup_ops lis3l02dq_buffer_setup_ops = {
> -	.postenable = &lis3l02dq_buffer_postenable,
> -	.predisable = &lis3l02dq_buffer_predisable,
> -};
> -
> -int lis3l02dq_configure_buffer(struct iio_dev *indio_dev)
> -{
> -	int ret;
> -	struct iio_buffer *buffer;
> -
> -	buffer = iio_kfifo_allocate();
> -	if (!buffer)
> -		return -ENOMEM;
> -
> -	iio_device_attach_buffer(indio_dev, buffer);
> -
> -	buffer->scan_timestamp = true;
> -	indio_dev->setup_ops = &lis3l02dq_buffer_setup_ops;
> -
> -	/* Functions are NULL as we set handler below */
> -	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
> -						 &lis3l02dq_trigger_handler,
> -						 0,
> -						 indio_dev,
> -						 "lis3l02dq_consumer%d",
> -						 indio_dev->id);
> -
> -	if (!indio_dev->pollfunc) {
> -		ret = -ENOMEM;
> -		goto error_iio_sw_rb_free;
> -	}
> -
> -	indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
> -	return 0;
> -
> -error_iio_sw_rb_free:
> -	iio_kfifo_free(indio_dev->buffer);
> -	return ret;
> -}
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-iio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux