Re: [spi-devel-general] Accelerometer, Gyros and ADC's etc withinthe kernel.

From: Jonathan Cameron
Date: Mon May 26 2008 - 12:23:46 EST


Dear All,

This email is intended to summarize the results of the discussions over
the last week or so and to open up to further comments on the way foward.

The original question was related to garnering opinions on how and where to
support devices such as accelerometers, gyros, general purpose ADCs (and
possibly DACs). Typical interfaces are SPI and I2C, rates varying from 10Hz
to many kHz. Real time and buffered access needed depending on application.

Conclusions:

1. The hwmon subsystem is unsuitable as it is intended to provide
relatively low frequency cached updates of sensor readings.

2. Definitely a bad idea to simply put such drivers in the relevant bus
subsystems due to unmaintainability and probable long term interface
divergence due to differing maintainers.

3. Whilst input subsystem is probably the only place that these sorts
of device could be currently included this would come at the cost of
input_dev being too fat and undesirable anonymization of the devices

4. Some stuff to be learned from comedi project (www.comedi.org).
Based on a quick browse of their documentation it looks like there
may be stuff to learn on what sort of userspace interfaces are interesting
but the drivers themselves are (as Matt originally stated) io-port based.

5. General consensus seems to be on a new subsytem (we'll bash out a
suitable name later - for now I don't want a name effectively guiding
the functionality!)

What's next

Obviously the exact functionality of this subsystem is going to be somewhat
up in the air until we have a wide range of devices supported.

The minimum needed seems to be a control interface to configure the devices
and some level of event interface (similar to input subsystem) to indicate to
userspace programs that something of interest to them has occured.
As configuration of the devices is a relatively infrequent event
(at least in the applications I work with), it seems to me that a suitable sys
interface, under a new class would provide this.

Types of parameter:

Chip related:
read/write -- Offsets, gains, sensor biases.
read only -- Factory set versions of the above, version numbers etc.

Mode related:
Some chips will operative in buffered and unbuffered modes.
Things like single ended vs differential modes on ADCs.

Interface related:
Like the input subsystem, things like parameters of an associated character
device, and the type of events this may return. This would allow different
complexities of event depending on what is going on. Down the line this may
allow the turning off and on of individual events as appropriate. For example,
if no-one is interested in an interrupt event such as freefall detection of an
accelerometer then depending on hardware support we may be a) able to turn
it off and free the relevant interrupt, or b) simply free the relevant interrupt
and ignore the event.

Simple read of current value:
As the devices will not always be generating interrupts, it probably also makes
sense to have interfaces here to get the current values of readings. Either this
will be from a cached value in an interrupt providing device, or actually initialise
a read from the device if appropriate.

The other interface element would be a stripped down /dev/ device similar to those
used by the input subsystem. However, it may make sense to have an independent one
of these for each and every chip present? Does it make sense to ever aggregate these,
or should this effectively be left to select calls in the userspace code? There is also an
issue here of whether we want to group similar devices. I.e. should we group all
accelerometers? My personal view is, not at the moment as it would complicate the
handling of devices combining several types of sensor.

The fun bit of this subsystem will be in how buffering of incoming data is accomplished.
As an example, lets say we want a 100Hz set of readings from the device. Several
possibilities exist:

a) The device itself has a ring buffer (the VTI accelerometers are an example of this). If this is the case, how would people suggest we go about reading from the ring buffer in
the event of an interrupt (typically 3/4 full). We could have a the kernel module interpret
this interrupt and effectively fill a ring buffer in the kernel from the hardware one. This
is efficient on interrupts and the kernel based ring buffer could have a size controllable
through the sys interface.

b) The device triggers an interrupt on each 'data ready' after sampling some analog
measurement. Do we generate an event on each of these? (seems like overkill to me)
or again use a ring buffer in the kernel to store the results and perhaps send an event
out after a (sysfs interface controlled) number of readings. If a near real-time app is
wanting the data, then this would be set to zero to indicate need to send an event on each
reading. The ST LIS3L02DQ accelerometer falls into this category. Complexities here
are concerned with the need to look directly at the relevant gpio value in order to establish
whether another even has occured before the bottom half of the interrupt has run. See
the LIS3L02DQ driver I posted to the spi-devel mailing list for an example.

c) The device samples only on a request over the bus. Either these could only be read
from via the sysfs interface or an event sent through the dev character device. Also feasible would be a board specific element of the platform_data, perhaps specifying
functions to initialize a hardware periodic clock interrupt or similar
(I've done this before, but it was clunky - at high rates you frequently miss interrupts.)
The MAX123x and MAX1363 ADCs fall into this category.

Obviously the challenge in all this is to keep the number of interrupts and indeed events (in
the input subsystem sense of sending to userspace via a char device) to a minimum.

For other issues such as time stamping, whilst vital, to a certain extent may need to be
handled within largely within the individual drivers (due to the different types of read above).
Clearly the subsystem should provide helper functions for this wherever possible.

All comments welcome and thanks to everyone who contributed to the original discussion.


--

Jonathan Cameron
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/