Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 162482
b: refs/heads/master
c: 574fb25
h: refs/heads/master
v: v3
  • Loading branch information
Jonathan Cameron authored and Greg Kroah-Hartman committed Sep 15, 2009
1 parent 902803a commit ea4877d
Show file tree
Hide file tree
Showing 7 changed files with 2,172 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7026ea4b52cf23a76507b5bddc92f394603c689e
refs/heads/master: 574fb258d63658e4564c32c1940068a3bad666a0
8 changes: 8 additions & 0 deletions trunk/drivers/staging/iio/accel/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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.
3 changes: 3 additions & 0 deletions trunk/drivers/staging/iio/accel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
298 changes: 298 additions & 0 deletions trunk/drivers/staging/iio/accel/sca3000.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,298 @@
/*
* 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

Loading

0 comments on commit ea4877d

Please sign in to comment.