Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 574fb258 authored by Jonathan Cameron's avatar Jonathan Cameron Committed by Greg Kroah-Hartman
Browse files

Staging: IIO: VTI sca3000 series accelerometer driver (spi)



Example of how a device with a hardware ring buffer is
handled within IIO.

Changes since V2:
* Moved to new registration functions giving much cleaner
  interface.

Signed-off-by: default avatarJonathan Cameron <jic23@cam.ac.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 7026ea4b
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -17,3 +17,11 @@ config LIS3L02DQ
	  Say yes 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.

config SCA3000
       depends on IIO_RING_BUFFER
       depends on SPI
       tristate "VTI SCA3000 series accelerometers"
       help
         Say yes here to build support for the VTI SCA3000 series of SPI
	 accelerometers. These devices use a hardware ring buffer.
 No newline at end of file
+3 −0
Original line number Diff line number Diff line
@@ -5,3 +5,6 @@ obj-$(CONFIG_KXSD9) += kxsd9.o

lis3l02dq-y		:= lis3l02dq_core.o
obj-$(CONFIG_LIS3L02DQ)	+= lis3l02dq.o

sca3000-y		:= sca3000_core.o sca3000_ring.o
obj-$(CONFIG_SCA3000)	+= sca3000.o
 No newline at end of file
+298 −0
Original line number Diff line number Diff line
/*
 * sca3000.c -- support VTI sca3000 series accelerometers
 *              via SPI
 *
 * Copyright (c) 2007 Jonathan Cameron <jic23@cam.ac.uk>
 *
 * Partly 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.
 *
 * Initial mode is direct measurement.
 *
 * Untested things
 *
 * Temperature reading (the e05 I'm testing with doesn't have a sensor)
 *
 * Free fall detection mode - supported but untested as I'm not droping my
 * dubious wire rig far enough to test it.
 *
 * Unsupported as yet
 *
 * Time stamping of data from ring. Various ideas on how to do this but none
 * are remotely simple. Suggestions welcome.
 *
 * Individual enabling disabling of channels going into ring buffer
 *
 * Overflow handling (this is signaled for all but 8 bit ring buffer mode.)
 *
 * Motion detector using AND combinations of signals.
 *
 * Note: Be very careful about not touching an register bytes marked
 * as reserved on the data sheet. They really mean it as changing convents of
 * some will cause the device to lock up.
 *
 * Known issues - on rare occasions the interrupts lock up. Not sure why as yet.
 * Can probably alleviate this by reading the interrupt register on start, but
 * that is really just brushing the problem under the carpet.
 */
#define SCA3000_WRITE_REG(a) (((a) << 2) | 0x02)
#define SCA3000_READ_REG(a) ((a) << 2)

#define SCA3000_REG_ADDR_REVID			0x00
#define SCA3000_REVID_MAJOR_MASK		0xf0
#define SCA3000_REVID_MINOR_MASK		0x0f

#define SCA3000_REG_ADDR_STATUS			0x02
#define SCA3000_LOCKED				0x20
#define SCA3000_EEPROM_CS_ERROR			0x02
#define SCA3000_SPI_FRAME_ERROR			0x01

/* All reads done using register decrement so no need to directly access LSBs */
#define SCA3000_REG_ADDR_X_MSB			0x05
#define SCA3000_REG_ADDR_Y_MSB			0x07
#define SCA3000_REG_ADDR_Z_MSB			0x09

#define SCA3000_REG_ADDR_RING_OUT		0x0f

/* Temp read untested - the e05 doesn't have the sensor */
#define SCA3000_REG_ADDR_TEMP_MSB		0x13

#define SCA3000_REG_ADDR_MODE			0x14
#define SCA3000_MODE_PROT_MASK			0x28

#define SCA3000_RING_BUF_ENABLE			0x80
#define SCA3000_RING_BUF_8BIT			0x40
/* Free fall detection triggers an interrupt if the acceleration
 * is below a threshold for equivalent of 25cm drop
 */
#define SCA3000_FREE_FALL_DETECT		0x10
#define SCA3000_MEAS_MODE_NORMAL		0x00
#define SCA3000_MEAS_MODE_OP_1			0x01
#define SCA3000_MEAS_MODE_OP_2			0x02

/* In motion detection mode the accelerations are band pass filtered
 * (aprox 1 - 25Hz) and then a programmable theshold used to trigger
 * and interrupt.
 */
#define SCA3000_MEAS_MODE_MOT_DET		0x03

#define SCA3000_REG_ADDR_BUF_COUNT		0x15

#define SCA3000_REG_ADDR_INT_STATUS		0x16

#define SCA3000_INT_STATUS_THREE_QUARTERS	0x80
#define SCA3000_INT_STATUS_HALF			0x40

#define SCA3000_INT_STATUS_FREE_FALL		0x08
#define SCA3000_INT_STATUS_Y_TRIGGER		0x04
#define SCA3000_INT_STATUS_X_TRIGGER		0x02
#define SCA3000_INT_STATUS_Z_TRIGGER		0x01

/* Used to allow accesss to multiplexed registers */
#define SCA3000_REG_ADDR_CTRL_SEL		0x18
/* Only available for SCA3000-D03 and SCA3000-D01 */
#define SCA3000_REG_CTRL_SEL_I2C_DISABLE	0x01
#define SCA3000_REG_CTRL_SEL_MD_CTRL		0x02
#define SCA3000_REG_CTRL_SEL_MD_Y_TH		0x03
#define SCA3000_REG_CTRL_SEL_MD_X_TH		0x04
#define SCA3000_REG_CTRL_SEL_MD_Z_TH		0x05
/* BE VERY CAREFUL WITH THIS, IF 3 BITS ARE NOT SET the device
   will not function */
#define SCA3000_REG_CTRL_SEL_OUT_CTRL		0x0B
#define SCA3000_OUT_CTRL_PROT_MASK		0xE0
#define SCA3000_OUT_CTRL_BUF_X_EN		0x10
#define SCA3000_OUT_CTRL_BUF_Y_EN		0x08
#define SCA3000_OUT_CTRL_BUF_Z_EN		0x04
#define SCA3000_OUT_CTRL_BUF_DIV_4		0x02
#define SCA3000_OUT_CTRL_BUF_DIV_2		0x01

/* Control which motion detector interrupts are on.
 * For now only OR combinations are supported.x
 */
#define SCA3000_MD_CTRL_PROT_MASK		0xC0
#define SCA3000_MD_CTRL_OR_Y			0x01
#define SCA3000_MD_CTRL_OR_X			0x02
#define SCA3000_MD_CTRL_OR_Z			0x04
/* Currently unsupported */
#define SCA3000_MD_CTRL_AND_Y			0x08
#define SCA3000_MD_CTRL_AND_X			0x10
#define SAC3000_MD_CTRL_AND_Z			0x20

/* Some control registers of complex access methods requiring this register to
 * be used to remove a lock.
 */
#define SCA3000_REG_ADDR_UNLOCK			0x1e

#define SCA3000_REG_ADDR_INT_MASK		0x21
#define SCA3000_INT_MASK_PROT_MASK		0x1C

#define SCA3000_INT_MASK_RING_THREE_QUARTER	0x80
#define SCA3000_INT_MASK_RING_HALF		0x40

#define SCA3000_INT_MASK_ALL_INTS		0x02
#define SCA3000_INT_MASK_ACTIVE_HIGH		0x01
#define SCA3000_INT_MASK_ACTIVE_LOW		0x00

/* Values of mulipexed registers (write to ctrl_data after select) */
#define SCA3000_REG_ADDR_CTRL_DATA		0x22

/* Measurment modes available on some sca3000 series chips. Code assumes others
 * may become available in the future.
 *
 * Bypass - Bypass the low-pass filter in the signal channel so as to increase
 *          signal bandwidth.
 *
 * Narrow - Narrow low-pass filtering of the signal channel and half output
 *          data rate by decimation.
 *
 * Wide - Widen low-pass filtering of signal channel to increase bandwidth
 */
#define SCA3000_OP_MODE_BYPASS			0x01
#define SCA3000_OP_MODE_NARROW			0x02
#define SCA3000_OP_MODE_WIDE			0x04
#define SCA3000_MAX_TX 6
#define SCA3000_MAX_RX 2

/**
 * struct sca3000_state - device instance state information
 * @us: 	 		the associated spi device
 * @info: 	  		chip variant information
 * @indio_dev: 	 		device information used by the IIO core
 * @interrupt_handler_ws: 	event interrupt handler for all events
 * @last_timestamp: 		the timestamp of the last event
 * @mo_det_use_count: 		reference counter for the motion detection unit
 * @lock: 		 	lock used to protect elements of sca3000_state
 * 	 			and the underlying device state.
 * @bpse: 		 	number of bits per scan element
 * @tx: 		 	dma-able transmit buffer
 * @rx: 		 	dma-able receive buffer
 **/
struct sca3000_state {
	struct spi_device		*us;
	const struct sca3000_chip_info	*info;
	struct iio_dev			*indio_dev;
	struct work_struct		interrupt_handler_ws;
	s64				last_timestamp;
	int				mo_det_use_count;
	struct mutex			lock;
	int				bpse;
	u8				*tx;
	/* not used during a ring buffer read */
	u8				*rx;
};

/**
 * struct sca3000_chip_info - model dependant parameters
 * @name: 			model identification
 * @temp_output:		some devices have temperature sensors.
 * @measurement_mode_freq:	normal mode sampling frequency
 * @option_mode_1:		first optional mode. Not all models have one
 * @option_mode_1_freq:		option mode 1 sampling frequency
 * @option_mode_2:		second optional mode. Not all chips have one
 * @option_mode_2_freq:		option mode 2 sampling frequency
 *
 * This structure is used to hold information about the functionality of a given
 * sca3000 variant.
 **/
struct sca3000_chip_info {
	const char		*name;
	bool			temp_output;
	int			measurement_mode_freq;
	int			option_mode_1;
	int			option_mode_1_freq;
	int			option_mode_2;
	int			option_mode_2_freq;
};

/**
 * sca3000_read_data() read a series of values from the device
 * @dev:		device
 * @reg_address_high:	start address (decremented read)
 * @rx:			pointer where recieved data is placed. Callee
 *			responsible for freeing this.
 * @len:		number of bytes to read
 *
 * The main lock must be held.
 **/
int sca3000_read_data(struct sca3000_state *st,
		      u8 reg_address_high,
		      u8 **rx_p,
		      int len);

/**
 * sca3000_write_reg() write a single register
 * @address:	address of register on chip
 * @val:	value to be written to register
 *
 * The main lock must be held.
 **/
int sca3000_write_reg(struct sca3000_state *st, u8 address, u8 val);

/* Conversion function for use with the ring buffer when in 11bit mode */
static inline int sca3000_11bit_convert(uint8_t msb, uint8_t lsb)
{
	int16_t val;

	val = ((lsb >> 3) & 0x1C) | (msb << 5);
	val |= (val & (1 << 12)) ? 0xE000 : 0;

	return val;
};

static inline int sca3000_13bit_convert(uint8_t msb, uint8_t lsb)
{
	s16 val;

	val = ((lsb >> 3) & 0x1F) | (msb << 5);
	/* sign fill */
	val |= (val & (1 << 12)) ? 0xE000 : 0;

	return val;
};


#ifdef CONFIG_IIO_RING_BUFFER
/**
 * sca3000_register_ring_funcs() setup the ring state change functions
 **/
void sca3000_register_ring_funcs(struct iio_dev *indio_dev);

/**
 * sca3000_configure_ring() - allocate and configure ring buffer
 * @indio_dev: iio-core device whose ring is to be configured
 *
 * The hardware ring buffer needs far fewer ring buffer functions than
 * a software one as a lot of things are handled automatically.
 * This function also tells the iio core that our device supports a
 * hardware ring buffer mode.
 **/
int sca3000_configure_ring(struct iio_dev *indio_dev);

/**
 * sca3000_unconfigure_ring() - deallocate the ring buffer
 * @indio_dev: iio-core device whose ring we are freeing
 **/
void sca3000_unconfigure_ring(struct iio_dev *indio_dev);

/**
 * sca3000_ring_int_process() handles ring related event pushing and escalation
 * @val:	the event code
 **/
void sca3000_ring_int_process(u8 val, struct iio_ring_buffer *ring);

#else
static inline void sca3000_register_ring_funcs(struct iio_dev *indio_dev) {};

static inline
int sca3000_register_ring_access_and_init(struct iio_dev *indio_dev)
{
	return 0;
};

static inline void sca3000_ring_int_process(u8 val, void *ring) {};

#endif
+1509 −0

File added.

Preview size limit exceeded, changes collapsed.

+331 −0
Original line number Diff line number Diff line
/*
 * sca3000_ring.c -- support VTI sca3000 series accelerometers via SPI
 *
 * 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.
 *
 * Copyright (c) 2009 Jonathan Cameron <jic23@cam.ac.uk>
 *
 */

#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/spi/spi.h>
#include <linux/sysfs.h>

#include "../iio.h"
#include "../sysfs.h"
#include "../ring_generic.h"
#include "../ring_hw.h"
#include "accel.h"
#include "sca3000.h"

/* RFC / future work
 *
 * The internal ring buffer doesn't actually change what it holds depending
 * on which signals are enabled etc, merely whether you can read them.
 * As such the scan mode selection is somewhat different than for a software
 * ring buffer and changing it actually covers any data already in the buffer.
 * Currently scan elements aren't configured so it doesn't matter.
 */

/**
 * sca3000_rip_hw_rb() - main ring access function, pulls data from ring
 * @r:			the ring
 * @count:		number of samples to try and pull
 * @data:		output the actual samples pulled from the hw ring
 * @dead_offset:	cheating a bit here: Set to 1 so as to allow for the
 *			leading byte used in bus comms.
 *
 * Currently does not provide timestamps.  As the hardware doesn't add them they
 * can only be inferred aproximately from ring buffer events such as 50% full
 * and knowledge of when buffer was last emptied.  This is left to userspace.
 **/
static int sca3000_rip_hw_rb(struct iio_ring_buffer *r,
			     size_t count, u8 **data, int *dead_offset)
{
	struct iio_hw_ring_buffer *hw_ring = iio_to_hw_ring_buf(r);
	struct iio_dev *indio_dev = hw_ring->private;
	struct sca3000_state *st = indio_dev->dev_data;
	u8 *rx;
	int ret, num_available, num_read = 0;
	int bytes_per_sample = 1;

	if (st->bpse == 11)
		bytes_per_sample = 2;

	mutex_lock(&st->lock);
	/* Check how much data is available:
	 * RFC: Implement an ioctl to not bother checking whether there
	 * is enough data in the ring?  Afterall, if we are responding
	 * to an interrupt we have a minimum content guaranteed so it
	 * seems slight silly to waste time checking it is there.
	 */
	ret = sca3000_read_data(st,
				SCA3000_REG_ADDR_BUF_COUNT,
				&rx, 1);
	if (ret)
		goto error_ret;
	else
		num_available = rx[1];
	/* num_available is the total number of samples available
	 * i.e. number of time points * number of channels.
	 */
	kfree(rx);
	if (count > num_available * bytes_per_sample)
		num_read = num_available*bytes_per_sample;
	else
		num_read = count - (count % (bytes_per_sample));

	/* Avoid the read request byte */
	*dead_offset = 1;
	ret = sca3000_read_data(st,
				SCA3000_REG_ADDR_RING_OUT,
				data, num_read);
error_ret:
	mutex_unlock(&st->lock);

	return ret ? ret : num_read;
}

/* This is only valid with all 3 elements enabled */
static int sca3000_ring_get_length(struct iio_ring_buffer *r)
{
	return 64;
}

/* only valid if resolution is kept at 11bits */
static int sca3000_ring_get_bpd(struct iio_ring_buffer *r)
{
	return 6;
}
static void sca3000_ring_release(struct device *dev)
{
	struct iio_ring_buffer *r = to_iio_ring_buffer(dev);
	kfree(iio_to_hw_ring_buf(r));
}

static IIO_RING_ENABLE_ATTR;
static IIO_RING_BPS_ATTR;
static IIO_RING_LENGTH_ATTR;

/**
 * sca3000_show_ring_bpse() -sysfs function to query bits per sample from ring
 * @dev: ring buffer device
 * @attr: this device attribute
 * @buf: buffer to write to
 **/
static ssize_t sca3000_show_ring_bpse(struct device *dev,
				      struct device_attribute *attr,
				      char *buf)
{
	int len = 0, ret;
	u8 *rx;
	struct iio_ring_buffer *r = dev_get_drvdata(dev);
	struct sca3000_state *st = r->indio_dev->dev_data;

	mutex_lock(&st->lock);
	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
	if (ret)
		goto error_ret;
	len = sprintf(buf, "%d\n", (rx[1] & SCA3000_RING_BUF_8BIT) ? 8 : 11);
	kfree(rx);
error_ret:
	mutex_unlock(&st->lock);

	return ret ? ret : len;
}

/**
 * sca3000_store_ring_bpse() - bits per scan element
 * @dev: ring buffer device
 * @attr: attribute called from
 * @buf: input from userspace
 * @len: length of input
 **/
static ssize_t sca3000_store_ring_bpse(struct device *dev,
				      struct device_attribute *attr,
				      const char *buf,
				      size_t len)
{
	struct iio_ring_buffer *r = dev_get_drvdata(dev);
	struct sca3000_state *st = r->indio_dev->dev_data;
	int ret;
	u8 *rx;
	long val;
	ret = strict_strtol(buf, 10, &val);
	if (ret)
		return ret;

	mutex_lock(&st->lock);

	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
	if (!ret)
		switch (val) {
		case 8:
			ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
						rx[1] | SCA3000_RING_BUF_8BIT);
			st->bpse = 8;
			break;
		case 11:
			ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
						rx[1] & ~SCA3000_RING_BUF_8BIT);
			st->bpse = 11;
			break;
		default:
			ret = -EINVAL;
			break;
		}
	mutex_unlock(&st->lock);

	return ret ? ret : len;
}

static IIO_CONST_ATTR(bpse_available, "8 11");

static IIO_DEV_ATTR_BPSE(S_IRUGO | S_IWUSR,
			      sca3000_show_ring_bpse,
			      sca3000_store_ring_bpse);

/*
 * Ring buffer attributes
 * This device is a bit unusual in that the sampling frequency and bpse
 * only apply to the ring buffer.  At all times full rate and accuracy
 * is available via direct reading from registers.
 */
static struct attribute *iio_ring_attributes[] = {
	&dev_attr_length.attr,
	&dev_attr_bps.attr,
	&dev_attr_ring_enable.attr,
	&iio_dev_attr_bpse.dev_attr.attr,
	&iio_const_attr_bpse_available.dev_attr.attr,
	NULL,
};

static struct attribute_group sca3000_ring_attr = {
	.attrs = iio_ring_attributes,
};

static struct attribute_group *sca3000_ring_attr_groups[] = {
	&sca3000_ring_attr,
	NULL
};

static struct device_type sca3000_ring_type = {
	.release = sca3000_ring_release,
	.groups = sca3000_ring_attr_groups,
};

static struct iio_ring_buffer *sca3000_rb_allocate(struct iio_dev *indio_dev)
{
	struct iio_ring_buffer *buf;
	struct iio_hw_ring_buffer *ring;

	ring = kzalloc(sizeof *ring, GFP_KERNEL);
	if (!ring)
		return 0;
	ring->private = indio_dev;
	buf = &ring->buf;
	iio_ring_buffer_init(buf, indio_dev);
	buf->dev.type = &sca3000_ring_type;
	device_initialize(&buf->dev);
	buf->dev.parent = &indio_dev->dev;
	dev_set_drvdata(&buf->dev, (void *)buf);

	return buf;
}

static inline void sca3000_rb_free(struct iio_ring_buffer *r)
{
	if (r)
		iio_put_ring_buffer(r);
}

int sca3000_configure_ring(struct iio_dev *indio_dev)
{
	indio_dev->ring = sca3000_rb_allocate(indio_dev);
	if (indio_dev->ring == NULL)
		return -ENOMEM;
	indio_dev->modes |= INDIO_RING_HARDWARE_BUFFER;

	indio_dev->ring->access.rip_lots = &sca3000_rip_hw_rb;
	indio_dev->ring->access.get_length = &sca3000_ring_get_length;
	indio_dev->ring->access.get_bpd = &sca3000_ring_get_bpd;

	return 0;
}

void sca3000_unconfigure_ring(struct iio_dev *indio_dev)
{
	sca3000_rb_free(indio_dev->ring);
}

static inline
int __sca3000_hw_ring_state_set(struct iio_dev *indio_dev, bool state)
{
	struct sca3000_state *st = indio_dev->dev_data;
	int ret;
	u8 *rx;

	mutex_lock(&st->lock);
	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
	if (ret)
		goto error_ret;
	if (state) {
		printk(KERN_INFO "supposedly enabling ring buffer\n");
		ret = sca3000_write_reg(st,
					SCA3000_REG_ADDR_MODE,
					(rx[1] | SCA3000_RING_BUF_ENABLE));
	} else
		ret = sca3000_write_reg(st,
					SCA3000_REG_ADDR_MODE,
					(rx[1] & ~SCA3000_RING_BUF_ENABLE));
	kfree(rx);
error_ret:
	mutex_unlock(&st->lock);

	return ret;
}
/**
 * sca3000_hw_ring_preenable() hw ring buffer preenable function
 *
 * Very simple enable function as the chip will allows normal reads
 * during ring buffer operation so as long as it is indeed running
 * before we notify the core, the precise ordering does not matter.
 **/
static int sca3000_hw_ring_preenable(struct iio_dev *indio_dev)
{
	return __sca3000_hw_ring_state_set(indio_dev, 1);
}

static int sca3000_hw_ring_postdisable(struct iio_dev *indio_dev)
{
	return __sca3000_hw_ring_state_set(indio_dev, 0);
}

void sca3000_register_ring_funcs(struct iio_dev *indio_dev)
{
	indio_dev->ring->preenable = &sca3000_hw_ring_preenable;
	indio_dev->ring->postdisable = &sca3000_hw_ring_postdisable;
}

/**
 * sca3000_ring_int_process() ring specific interrupt handling.
 *
 * This is only split from the main interrupt handler so as to
 * reduce the amount of code if the ring buffer is not enabled.
 **/
void sca3000_ring_int_process(u8 val, struct iio_ring_buffer *ring)
{
	if (val & SCA3000_INT_STATUS_THREE_QUARTERS)
		iio_push_or_escallate_ring_event(ring,
						 IIO_EVENT_CODE_RING_75_FULL,
						 0);
	else if (val & SCA3000_INT_STATUS_HALF)
		iio_push_ring_event(ring,
				    IIO_EVENT_CODE_RING_50_FULL, 0);
}
Loading