diff mbox

[01/11] misc: inv_mpu primary header file and README file.

Message ID 1309486707-1658-1-git-send-email-nroyer@invensense.com (mailing list archive)
State New, archived
Headers show

Commit Message

Nathan Royer July 1, 2011, 2:18 a.m. UTC
This files defines the userspace interface and how to integrate it into a
platform.

Signed-off-by: Nathan Royer <nroyer@invensense.com>
---

This is the first of many patch files for the inv_mpu driver in its current
state.  This is our first time submitting this driver, so I expect there to be
a lot wrong with it, and expect to need to fix many things.

The inv_mpu driver attepts to implement a Motion Processing Unit interface.  As
a unit, an accelerometer, magnetometer, gyroscope, and/or altimiter data is
fused together to produce calibrated data and a quaternion.

The inv_mpu driver interface is currently implemented as a misc device, but may
need to change to include both sysfs attributes and input devices.  I think
that we will continue to need the ioctl interface, but many of the ioctls can
be replace by attributes and/or input devices.

The mpu3050 has an i2c master interface designed to control an accelerometer
and a Digital Motion Processor (DMP) used to perform sensor fusion on the
gyroscope and accelerometer.  This data is then read out of the mpu3050 fifo
and sent to userspace for distribution and optional propritary processing, such
as fusion with a compass to produce a 9 axis quaternion.

Some question I have at the start are:
1) Is there a master design or standard interface for Motion Processing
devices, specifically ones that do calibration, sensor fusion, and or have a
micro-controller to do some of this work.
2) Is there a standard way to integrate user space components with kernel side
components.
3) Should data be pushed back to the driver from userspace, and made available
as an input device or should it remain as a character device.
4) Can a 4 element quaternion be added to input.h:
ABS_QUATERNION_1 ABS_QUATERNION_I ABS_QUATERNION_J ABS_QUATERNION_K
for <1, i, j, k>
5) Should we instead use a rotation vector as defined in the Android sensor:
http://developer.android.com/reference/android/hardware/SensorEvent.html
6) Are there any other major design concerns?
7) Can an input device also have a character device interface for proprietary
customization.

 drivers/misc/inv_mpu/README |  104 ++++++++++++
 include/linux/mpu.h         |  365 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 469 insertions(+), 0 deletions(-)
 create mode 100644 drivers/misc/inv_mpu/README
 create mode 100644 include/linux/mpu.h

Comments

Greg Kroah-Hartman July 1, 2011, 3:09 a.m. UTC | #1
On Thu, Jun 30, 2011 at 07:18:17PM -0700, Nathan Royer wrote:
> This files defines the userspace interface and how to integrate it into a
> platform.
> 
> Signed-off-by: Nathan Royer <nroyer@invensense.com>
> ---
> 
> This is the first of many patch files for the inv_mpu driver in its current
> state.  This is our first time submitting this driver, so I expect there to be
> a lot wrong with it, and expect to need to fix many things.
> 
> The inv_mpu driver attepts to implement a Motion Processing Unit interface.  As
> a unit, an accelerometer, magnetometer, gyroscope, and/or altimiter data is
> fused together to produce calibrated data and a quaternion.
> 
> The inv_mpu driver interface is currently implemented as a misc device, but may
> need to change to include both sysfs attributes and input devices.  I think
> that we will continue to need the ioctl interface, but many of the ioctls can
> be replace by attributes and/or input devices.
> 
> The mpu3050 has an i2c master interface designed to control an accelerometer
> and a Digital Motion Processor (DMP) used to perform sensor fusion on the
> gyroscope and accelerometer.  This data is then read out of the mpu3050 fifo
> and sent to userspace for distribution and optional propritary processing, such
> as fusion with a compass to produce a 9 axis quaternion.
> 
> Some question I have at the start are:
> 1) Is there a master design or standard interface for Motion Processing
> devices, specifically ones that do calibration, sensor fusion, and or have a
> micro-controller to do some of this work.
> 2) Is there a standard way to integrate user space components with kernel side
> components.
> 3) Should data be pushed back to the driver from userspace, and made available
> as an input device or should it remain as a character device.
> 4) Can a 4 element quaternion be added to input.h:
> ABS_QUATERNION_1 ABS_QUATERNION_I ABS_QUATERNION_J ABS_QUATERNION_K
> for <1, i, j, k>
> 5) Should we instead use a rotation vector as defined in the Android sensor:
> http://developer.android.com/reference/android/hardware/SensorEvent.html
> 6) Are there any other major design concerns?

Shouldn't you be using the iio subsystem for the kernel/user interface
as I think it handles most of this for you already, right?

> 7) Can an input device also have a character device interface for proprietary
> customization.

What do you mean by this?

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Chris Wolfe July 1, 2011, 3:59 a.m. UTC | #2
On Thu, Jun 30, 2011 at 7:18 PM, Nathan Royer <nroyer@invensense.com> wrote:
> The mpu3050 has an i2c master interface designed to control an accelerometer
> and a Digital Motion Processor (DMP) used to perform sensor fusion on the
> gyroscope and accelerometer.  This data is then read out of the mpu3050 fifo
> and sent to userspace for distribution and optional propritary processing, such
> as fusion with a compass to produce a 9 axis quaternion.

Sorry, just took a quick pass so I may be missing changes. Is this
driver to the stage where someone can practically initialize the 3050
and read low-level data without having the InvenSense MPL already
installed? (and without basically doing I2C reads and writes from
userspace)

As Greg K-H pointed out, IIO provides a lot of the support code for
this kind of driver. Have a look at drivers/staging/iio/imu and the
sibling directories. They provide a framework for reporting the
low-level data in a standard fashion, and some extra attributes to
load the DMP firmware would be easy to add.

I'm disconnected over the weekend, but will touch base with you and
Mike Housholder on Tuesday. Getting this upstream would be great, so
we ought to share notes.

Chris
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Alan Cox July 1, 2011, 7:29 a.m. UTC | #3
> Shouldn't you be using the iio subsystem for the kernel/user interface
> as I think it handles most of this for you already, right?

The input layer will for a general driver, in fact an mpu3050 driver
just went into the input layer although there are some other bits in
this one that perhaps will want adding to it.

Alan
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Alan Cox July 1, 2011, 7:53 a.m. UTC | #4
> 1) Is there a master design or standard interface for Motion
> Processing devices, specifically ones that do calibration, sensor
> fusion, and or have a micro-controller to do some of this work.

Not specifically - but for the most part it shouldn't matter. We have
interfaces like request_firmware() to load firmware and we have
interfaces for input devices and for 

> 2) Is there a standard way to integrate user space components with
> kernel side components.

Use the standard kernel interfaces. If specific processing is needed in
user space the to go into the kernel it needs to be such that those
interfaces can be used in an open manner (this normally comes up with
3D graphics hardware rather than input), either by documenting the
interface or providing an open implementation.

> 3) Should data be pushed back to the driver from userspace, and made
> available as an input device or should it remain as a character
> device. 

The ektf2136 driver currently getting tidied up provides both. You can
open it either as an input driver directly, or you can access raw event
data in a documented for and do clever things with the data and feed it
back to the input layer via uevent.

> 6) Are there any other major design concerns? 

We have an initial mpu3050 driver which provides basic functionality
(from Wistron/Intel), normal Linux practice would be to extend and
improve that.

> 7) Can an input device also have a character device interface for
> proprietary customization.

That depends what you mean and what for. Fundamentally there is no
reason a device cannot present multiple interfaces although you might
need to lock between them.

> +Programming the chip using /dev/mpu
> +----------------------------------
> +Programming of MPU3050 is done by first opening the /dev/mpu file and
> +then performing a series of IOCTLS on the handle returned.  The
> IOCTL codes can +be found in mpu.h.  Typically this is done by the
> mllite library in user +space.

Is this published with source or sufficient documentation for someone
to write their own ? Note btw the usual expectation would be that the
kernel driver uses request_firmware to load firmware as needed for that
part of the process.

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jonathan Cameron July 1, 2011, 9 a.m. UTC | #5
On 07/01/11 04:09, Greg KH wrote:
> On Thu, Jun 30, 2011 at 07:18:17PM -0700, Nathan Royer wrote:
>> This files defines the userspace interface and how to integrate it into a
>> platform.
>>
>> Signed-off-by: Nathan Royer <nroyer@invensense.com>
>> ---
>>
>> This is the first of many patch files for the inv_mpu driver in its current
>> state.  This is our first time submitting this driver, so I expect there to be
>> a lot wrong with it, and expect to need to fix many things.
>>
>> The inv_mpu driver attepts to implement a Motion Processing Unit interface.  As
>> a unit, an accelerometer, magnetometer, gyroscope, and/or altimiter data is
>> fused together to produce calibrated data and a quaternion.
>>
>> The inv_mpu driver interface is currently implemented as a misc device, but may
>> need to change to include both sysfs attributes and input devices.  I think
>> that we will continue to need the ioctl interface, but many of the ioctls can
>> be replace by attributes and/or input devices.
>>
>> The mpu3050 has an i2c master interface designed to control an accelerometer
>> and a Digital Motion Processor (DMP) used to perform sensor fusion on the
>> gyroscope and accelerometer.  This data is then read out of the mpu3050 fifo
>> and sent to userspace for distribution and optional propritary processing, such
>> as fusion with a compass to produce a 9 axis quaternion.
>>
>> Some question I have at the start are:
>> 1) Is there a master design or standard interface for Motion Processing
>> devices, specifically ones that do calibration, sensor fusion, and or have a
>> micro-controller to do some of this work.
Some of Analog's parts are doing a very basic form of this (bit of integration etc).
Ultimately in their case it is transparent, so they just look like additional data
channels.  Here it looks more sophisticated.

>> 2) Is there a standard way to integrate user space components with kernel side
>> components.
>> 3) Should data be pushed back to the driver from userspace, and made available
>> as an input device or should it remain as a character device.
Depends on the use case.  If you have to do userspace processing, then uinput
does this nicely.
>> 4) Can a 4 element quaternion be added to input.h:
>> ABS_QUATERNION_1 ABS_QUATERNION_I ABS_QUATERNION_J ABS_QUATERNION_K
>> for <1, i, j, k>
>> 5) Should we instead use a rotation vector as defined in the Android sensor:
>> http://developer.android.com/reference/android/hardware/SensorEvent.html
If you hardware is producing quaternions directly you are not going to want to
the necessary sin / cos in kernel. Trivial in userspace though.
>> 6) Are there any other major design concerns?
The big one Alan and Jean have commented on.  This device just has slave i2c devices
they should have their own drivers if at all possible.
> 
> Shouldn't you be using the iio subsystem for the kernel/user interface
> as I think it handles most of this for you already, right?
Few bits we haven't seen before, but nothing that can't be easily added.
We do have a usual question here of whether this is better as an input device
though. Dmitry, what is your view on this one?  Certainly doesn't want to end
up in misc.  Alan (in other branch) has highlighted an existing driver for the
mpu part.
> 
>> 7) Can an input device also have a character device interface for proprietary
>> customization.
> 
> What do you mean by this?
> 
> greg k-h
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jonathan Cameron July 1, 2011, 9:08 a.m. UTC | #6
On 07/01/11 03:18, Nathan Royer wrote:
> This files defines the userspace interface and how to integrate it into a
> platform.
> 
> Signed-off-by: Nathan Royer <nroyer@invensense.com>
> ---
> 
> This is the first of many patch files for the inv_mpu driver in its current
> state.  This is our first time submitting this driver, so I expect there to be
> a lot wrong with it, and expect to need to fix many things.
Just out of interest, can you give details of what other patches are to come?
I'm guessing more sensor drivers and I hate discovering I'm implementing drivers
for devices that someone already has working code for!
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Nathan Royer July 1, 2011, 4:39 p.m. UTC | #7
> Just out of interest, can you give details of what other patches are to
> come?
> I'm guessing more sensor drivers and I hate discovering I'm
> implementing drivers
> for devices that someone already has working code for!

I wanted to start off with only 1 driver for each type of slave and with
only the MPU3050 and exclude the MPU6050 until we figure out exactly the
best way to fit this into the kernel.

The current full list of drivers we have developed in this architecture
are as follows:
MPU3050 and MPU6050 support in mldl_cfg.c
# sesnors - accel
accel/mpu6050.c
accel/kxsd9.c
accel/kxtf9.c
accel/bma150.c
accel/bma222.c
accel/bma250.c
accel/mma8450.c
accel/mma845x.c
accel/lis331.c
accel/lsm303a.c
accel/adxl34x.c
accel/lis3dh.c
# sensors - compass
compass/ak8975.c
compass/ak8972.c
compass/ami30x.c
compass/ami306.c
compass/hmc5883.c
compass/lsm303m.c
compass/yas529.c
compass/yas530.c
compass/mmc314x.c
compass/hscdtd002b.c
compass/hscdtd004a.c
# sensors - pressure
pressure/bma085.c
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Arnd Bergmann July 1, 2011, 9:04 p.m. UTC | #8
On Friday 01 July 2011 04:18:17 Nathan Royer wrote:
> +/* Structure for the following IOCTS's
> + * MPU_CONFIG_GYRO
> + * MPU_CONFIG_ACCEL
> + * MPU_CONFIG_COMPASS
> + * MPU_CONFIG_PRESSURE
> + * MPU_GET_CONFIG_GYRO
> + * MPU_GET_CONFIG_ACCEL
> + * MPU_GET_CONFIG_COMPASS
> + * MPU_GET_CONFIG_PRESSURE
> + *
> + * @key one of enum ext_slave_config_key
> + * @len length of data pointed to by data
> + * @apply zero if communication with the chip is not necessary, false otherwise
> + *        This flag can be used to select cached data or to refresh cashed data
> + *        cache data to be pushed later or push immediately.  If true and the
> + *        slave is on the secondary bus the MPU will first enger bypass mode
> + *        before calling the slaves .config or .get_config funcion
> + * @data pointer to the data to confgure or get
> + */
> +struct ext_slave_config {
> +       __u8 key;
> +       __u16 len;
> +       __u8 apply;
> +       void *data;
> +};

I'm a bit worried about the ioctl interface, it seems overloaded and has
problems with 32/64 bit compatibility. In general, having void pointers
in an structure that is used as an ioctl argument is a sign that the
interface is too complex. In fact, there are a number of reasons why you
should try to avoid pointers in there completely.

You should also try to avoid padding in structures. The definition you
have could be any of 64/96/128 bytes long depending on the architecture,
and leak kernel stack data.

Having separate commands on a single device file in order to do the
same operation on distinct pieces of hardware sounds like a wrong
abstraction of your devices. Instead, it would seem more appropriate
to represent each hardware endpoint (gyro/accel/compass/...) as one
character device, and let each of them export the same minimum set of
commands. However, the suggestion to use an existing subsystem (iio,
input, hwmon, ...) for each of the endpoints as appropriate would fit
better into the existing use cases.

I haven't been able to figure out if all those endpoints are just
I2C devices and could be handled by i2c drivers for those subsystems,
or if you have another hardware interface that groups of them. In the
latter case, would an MFD driver work for this? The idea of that is
essentially to prove a new bus_type without having to do all the
abstraction work when you already know all the devices behind it.


	Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Alan Cox July 4, 2011, 8:16 a.m. UTC | #9
> > accel/bma150.c
> An input driver exists for that one. (cc'd Eric)

[Two input drivers - bma023 which I posted covers it too ;)]

> > # sensors - compass
> > compass/ak8975.c

We have a driver for this (I posted a while back)

> > compass/ak8972.c

> > compass/ami30x.c

AMI304 is identical to the AK8974 which we already have - Gram Hsieh
posted patches for this a while ago

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Eric Andersson July 4, 2011, 8:06 p.m. UTC | #10
> > # sensors - pressure
> > pressure/bma085.c
> As Manuel Stahl confirmed he also has a driver for this.

FYI - We are working on a new version of the bmp085 driver with support for
some new pressure sensors from Bosch Sensortec. The plan is to
contribute that code in a near future.
Nathan Royer July 6, 2011, 1:49 a.m. UTC | #11
> > > accel/bma150.c
> > An input driver exists for that one. (cc'd Eric)
>
> [Two input drivers - bma023 which I posted covers it too ;)]
>
> > > # sensors - compass
> > > compass/ak8975.c
>
> We have a driver for this (I posted a while back)
>
> > > compass/ak8972.c
>
> > > compass/ami30x.c
>
> AMI304 is identical to the AK8974 which we already have - Gram Hsieh
> posted patches for this a while ago

It seems that some sensors are in input and but that most are in iio.
Obviously I don't want to dissent with both and put ours in misc, so how
do we make this better?  Should we work on cleaning this up.  If so should
we start moving the drivers that are in input to iio.

If this is the right thing to do, I could start working on merging the
current mpu3050 input interface and our misc interface to the iio
interface.  I'm still trying to wrap my head around the iio framework, but
I think one of the things I need is a uinput like interface for iio
(perhaps it exists, I just haven't figured it out yet).  If the DMP is
used, a buffer for the FIFO data would be created, and user space would be
responsible to push the sensor data back to iio after sensor fusion and
calibration.  Without the DMP, each sensor driver would act independently
providing their own raw data.

We still need a way to read and write registers and DMP memory during
runtime from user space.
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jonathan Cameron July 6, 2011, 9:07 a.m. UTC | #12
On 07/06/11 02:49, Nathan Royer wrote:
>>>> accel/bma150.c
>>> An input driver exists for that one. (cc'd Eric)
>>
>> [Two input drivers - bma023 which I posted covers it too ;)]
>>
>>>> # sensors - compass
>>>> compass/ak8975.c
>>
>> We have a driver for this (I posted a while back)
>>
>>>> compass/ak8972.c
>>
>>>> compass/ami30x.c
>>
>> AMI304 is identical to the AK8974 which we already have - Gram Hsieh
>> posted patches for this a while ago
> 
> It seems that some sensors are in input and but that most are in iio.
> Obviously I don't want to dissent with both and put ours in misc, so how
> do we make this better? 
Definitely not misc - we don't want to end up with drivers in there purely
because they might fit in two other places!
> Should we work on cleaning this up.  If so should
> we start moving the drivers that are in input to iio.
Will cause all sorts of userspace issues.  a) iio is still in staging
and for good reason.  I really ought to update our todo list!
b) We don't have a transparent way to provide input interfaces for iio
devices - so that will mean mass abi breakge.  There have been some
discussions about how to do this (see Mark Brown's suggestions a month
or so ago), be it for very different reason.

Anyhow, I'm personally in favour of the current divide:
Basically if it's for human input (primarily) it goes in input (decision
on that is Dmitry's). Otherwise, IIO is happy to take drivers that don't
fit elsewhere (we deliberately have very wide scope).
> 
> If this is the right thing to do, I could start working on merging the
> current mpu3050 input interface and our misc interface to the iio
> interface.  I'm still trying to wrap my head around the iio framework, but
> I think one of the things I need is a uinput like interface for iio
> (perhaps it exists, I just haven't figured it out yet).
Nope. Not previously had a use case.
Unlike input we don't have a whole host of userspace code that is expecting to
receive data in a particular format so we don't have the standard use
case for uinput  (cc'd Manuel and Michael who have done a lot more on the userspace
end of IIO than I have + linux-iio for everyone else).  We do have a prototype
uinput based bridge to push event into input.  It is only intended for those rare
cases where someone really wants to use a 1000 dolar IMU as a mouse. Not relevant
here though.

> If the DMP is
err, DMP?
> used, a buffer for the FIFO data would be created, and user space would be
> responsible to push the sensor data back to iio after sensor fusion and
> calibration.  Without the DMP, each sensor driver would act independently
> providing their own raw data.

Strangely enough, your need to push data back is not dissimilar to what we have
discussed in the past for DACs. Right now we only have a slow and simple interface
for DACs, mainly because doing anything clever requires some fairly nasty additions
to the host bus drivers and no one has had the time.  Michael has almost
certainly thought more on this than I ever have!
> 
> We still need a way to read and write registers and DMP memory during
> runtime from user space.
I guess the DMP is the on device processor? So what you write varies a lot
with what firmware is loaded?

So let me just check I understand the data flow here.

Example

Magnetometer -> kernel -> userspace interface -> hideously complex algorithm ->
kernel -> mpu -> mpu fusion algorithm in relevant firmware -> userspace ?

So how do we know the mpu wants data?  Obvious options that might be the case
a) on chip fifo with flow control.
b) interrupt to request data?
c) Always feed latest value and it runs unsynchronised.

Do we actually have that hideously complex algorithm in userspace element
or did I invent that part?  If not, we might want to use some in kernel
hooks to pass the data back bypassing userspace entirely.

Jonathan 
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Alan Cox July 6, 2011, 10:54 a.m. UTC | #13
> It seems that some sensors are in input and but that most are in iio.
> Obviously I don't want to dissent with both and put ours in misc, so
> how do we make this better?  Should we work on cleaning this up.  If
> so should we start moving the drivers that are in input to iio.

IIO provides a lot more flexibility and is rather newer, input provides
a more focussed interface. In some cases it may make sense to provide
different interfaces to each (eg atomspheric pressure doesn't fit well
into input, but 3 axis accelerometers fit perfectly)

> We still need a way to read and write registers and DMP memory during
> runtime from user space.

You probably want a driver for the MPU itself whih provides the
needed glue and also control interfaces (firmware load etc). That may
well be a drivers/misc item as I imagine that part is quite unique and
specialised.
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Nathan Royer July 6, 2011, 8:25 p.m. UTC | #14
> It is only intended for those rare
> cases where someone really wants to use a 1000 dolar IMU as a mouse.
> Not relevant here though.

We have a mouse application that is significantly less expensive than
$1000, so it might actually be relevant, in the future.

> > If the DMP is
> err, DMP?

Digital Motion Processor.  It is what we call the built in micro
controller on the mpu3050 that does sensor fusion.

> > used, a buffer for the FIFO data would be created, and user space
> would be
> > responsible to push the sensor data back to iio after sensor fusion
> and
> > calibration.  Without the DMP, each sensor driver would act
> independently
> > providing their own raw data.
>
> Strangely enough, your need to push data back is not dissimilar to what
> we have
> discussed in the past for DACs. Right now we only have a slow and
> simple interface
> for DACs, mainly because doing anything clever requires some fairly
> nasty additions
> to the host bus drivers and no one has had the time.  Michael has
> almost
> certainly thought more on this than I ever have!

A slow interface might be ok.  Highest traffic is usually in the low 10's
of bytes at 30hz.

> > We still need a way to read and write registers and DMP memory during
> > runtime from user space.
> I guess the DMP is the on device processor? So what you write varies a
> lot
> with what firmware is loaded?

Yes that is correct.

> So let me just check I understand the data flow here.
>
> Example
>
> Magnetometer -> kernel -> userspace interface -> hideously complex
> algorithm ->
> kernel -> mpu -> mpu fusion algorithm in relevant firmware -> userspace
> ?

Hideously complex algorithm or HCA for short :)

Your data path is more relevant for the mpu6050.  I'll explain what it
currently looks like on each chip 2 chips.  For the 3050 it looks like
this:
=======================
Accel -> mpu3050 -> DMP (6 Axis fusion) -> FIFO
         (gyro)                   ^
                                  |
                               Kernel
                                  |
FIFO -> Kernel -> user space -> 9 Axis fusion + HCA's-> application
                                  ^
                                  |
Compass -> kernel -> user space --/

For the mpu6050:
================
Compass -> mpu6050   -> DMP (9 Axis Fusion) -> Kernel -> User Space HCA's
-> Apps
          (gyro + accel)     ^                               |
                             |                               |
                             \---------------- Kernel <------/


As you might have seen we don't have an input or an iio interface for user
space to retrieve data.  Currently applications have to link in our MPL,
either standalone, or as a daemon, or something similar like the Android
sensor HAL.  What I'm trying to figure out is once data is ready to be
provided to applications, where should it come from, input, IIO, or a
daemon, before I start that part of development.  It seems like IIO was
built more for raw data, but that input has a facility to handle processed
data.

> So how do we know the mpu wants data?  Obvious options that might be
> the case
> a) on chip fifo with flow control.
> b) interrupt to request data?
> c) Always feed latest value and it runs unsynchronized.

The MPL (Motion Processing Library user space library that includes HCA's)
makes the decision when to feed data down, and does it in an
unsynchronized way.  It will do it shortly after processing a FIFO data
packet, but the timing does not need to be precise.

> Do we actually have that hideously complex algorithm in userspace
> element
> or did I invent that part?  If not, we might want to use some in kernel
> hooks to pass the data back bypassing userspace entirely.

Yes the HCA's exists.  They include 9 axis fusion, compass calibration
algorithms, and a number of other proprietary algorithms.  We've tried to
design the MPL so that they can be removed and still provide basic
functionality.  This basic functionality is available to be pushed into
the kernel if necessary, but we will still need a way to support the
HCA's.
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Nathan Royer July 6, 2011, 9:27 p.m. UTC | #15
> > It seems that some sensors are in input and but that most are in iio.
> > Obviously I don't want to dissent with both and put ours in misc, so
> > how do we make this better?  Should we work on cleaning this up.  If
> > so should we start moving the drivers that are in input to iio.
>
> IIO provides a lot more flexibility and is rather newer, input provides
> a more focussed interface. In some cases it may make sense to provide
> different interfaces to each (eg atomspheric pressure doesn't fit well
> into input, but 3 axis accelerometers fit perfectly)
>
> > We still need a way to read and write registers and DMP memory during
> > runtime from user space.
>
> You probably want a driver for the MPU itself whih provides the
> needed glue and also control interfaces (firmware load etc). That may
> well be a drivers/misc item as I imagine that part is quite unique and
> specialised.

If I understand you correctly, you are suggesting that we create two
drivers for the mpu3050 part.  An MPU (Motion Processing Unit) driver and
a standalone Gyroscope driver.  The MPU if present would turn each sensor
(accel, compass, gyro, pressure) into an MPU slave, load and configure the
firmware, and provide a user space interface for customization and runtime
communication with the Hideously Complicated Algorithms (HCA's).

Each sensor driver would have two operating modes, standalone, and slave
to the MPU trying to re-use as much code as possible.  Current drivers
that have a standalone interface would need the slave interface added, and
those that we've written would need the stand alone interface added.
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Alan Cox July 7, 2011, 7:40 a.m. UTC | #16
> If I understand you correctly, you are suggesting that we create two
> drivers for the mpu3050 part.  An MPU (Motion Processing Unit) driver and
> a standalone Gyroscope driver.  The MPU if present would turn each sensor
> (accel, compass, gyro, pressure) into an MPU slave, load and configure the
> firmware, and provide a user space interface for customization and runtime
> communication with the Hideously Complicated Algorithms (HCA's).

Its hard to judge with what has been explained so far but the device
appears to be very different in the two operating modes so it might make
sense to have it as two drivers (or one driver with two very distinct
modes)

> Each sensor driver would have two operating modes, standalone, and slave
> to the MPU trying to re-use as much code as possible.  Current drivers
> that have a standalone interface would need the slave interface added, and
> those that we've written would need the stand alone interface added.

Can the slave interface appears to be an i²c bus too or is the interface
too different (ie could the smart mode create an i²c bus that it uses to
talk to the drivers to configure them for 'smart' mode)

I'm not entirely sure at this point I understand quite how all the pieces
fit together.

Alan
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Nathan Royer July 8, 2011, 1:25 a.m. UTC | #17
> Its hard to judge with what has been explained so far but the device
> appears to be very different in the two operating modes so it might
> make
> sense to have it as two drivers (or one driver with two very distinct
> modes)

I'm thinking two distinct drivers.  One we should call the MPU controller
and the other the gyro driver.

Comparing it to the i2c architecture.  In the board file, each i2c bus is
initialized with information about each device on the bus.  An i2c_client
is created for each device and their probe functions called allowing the
driver to use the i2c_client to communicate with the device.

For the MPU controller, it would be similar registration, but the slaves
would be given to the MPU controller to control.  In the board file the
MPU controller would be initialized with which devices that it should
control.  The MPU controller would then probe each device for the
interface used to control it.  If that device is not probed then it should
act alone, otherwise it should allow the MPU controller to control it.

Regarding the interface, I'm still confused on how to resolve the
iio/input decision.  Should the devices use both?  I think the final
interface would be a combination of possibly all 3 interfaces, misc,
input, and iio.

Below is a discussion of the IOCTL's, how they are currently used, and how
I'm thinking about mapping them in between the 3 interfaces.

Our MPL needs the platform data, mostly the orientation of each device.
The relevant information can be made available as iio sysfs attributes for
each device. ========================================
#define MPU_GET_EXT_SLAVE_PLATFORM_DATA	\
	_IOWR(MPU_IOCTL, 0x02, struct ext_slave_platform_data)
#define MPU_GET_MPU_PLATFORM_DATA	\
	_IOWR(MPU_IOCTL, 0x02, struct mpu_platform_data)
#define MPU_GET_EXT_SLAVE_DESCR	\
	_IOWR(MPU_IOCTL, 0x02, struct ext_slave_descr)

These are simple register reads and register writes.  These can be
replaced with iio sysfs attributes for the gyro driver.
=======================================
#define MPU_READ		_IOWR(MPU_IOCTL, 0x10, struct
mpu_read_write)
#define MPU_WRITE		_IOW(MPU_IOCTL,  0x10, struct
mpu_read_write)

The following is used to interact at runtime with the DMP.  These will
need to remain as ioctls to drivers/misc/inv_mpu
========================================
#define MPU_READ_MEM		_IOWR(MPU_IOCTL, 0x11, struct
mpu_read_write)
#define MPU_WRITE_MEM		_IOW(MPU_IOCTL,  0x11, struct
mpu_read_write)
#define MPU_READ_FIFO		_IOWR(MPU_IOCTL, 0x12, struct
mpu_read_write)
#define MPU_WRITE_FIFO		_IOW(MPU_IOCTL,  0x12, struct
mpu_read_write)

These were used for reading raw data from each slave.  These can be
replaced by an appropriate IIO interface for raw data, implemented
separately by each slave driver.  Input can be then used for calibrated
data and can be fed back via uinput from user space.
========================================
#define MPU_READ_COMPASS	_IOR(MPU_IOCTL, 0x12, __u8)
#define MPU_READ_ACCEL		_IOR(MPU_IOCTL, 0x13, __u8)
#define MPU_READ_PRESSURE	_IOR(MPU_IOCTL, 0x14, __u8)

These are used to configure each slave.  These can be replaced by sysfs
attributes implemented by each slave driver in iio.
========================================================
#define MPU_CONFIG_GYRO		_IOW(MPU_IOCTL, 0x20, struct
ext_slave_config)
#define MPU_CONFIG_ACCEL	_IOW(MPU_IOCTL, 0x21, struct
ext_slave_config)
#define MPU_CONFIG_COMPASS	_IOW(MPU_IOCTL, 0x22, struct
ext_slave_config)
#define MPU_CONFIG_PRESSURE	_IOW(MPU_IOCTL, 0x23, struct
ext_slave_config)

#define MPU_GET_CONFIG_GYRO	_IOWR(MPU_IOCTL, 0x20, struct
ext_slave_config)
#define MPU_GET_CONFIG_ACCEL	_IOWR(MPU_IOCTL, 0x21, struct
ext_slave_config)
#define MPU_GET_CONFIG_COMPASS	_IOWR(MPU_IOCTL, 0x22, struct
ext_slave_config)
#define MPU_GET_CONFIG_PRESSURE	_IOWR(MPU_IOCTL, 0x23, struct
ext_slave_config)

This was used to start or stop the system.  This can be replaced with iio
sysfs power mode attribute for each slave, and an additional one for the
MPU controller.
=========================================
#define MPU_SUSPEND		_IOW(MPU_IOCTL, 0x30, __u32)
#define MPU_RESUME		_IOW(MPU_IOCTL, 0x31, __u32)

Selecting on /dev/mpu will return a MPU_PM_EVENT_SUSPEND_PREPARE or
MPU_PM_EVENT_POST_SUSPEND allowing user space to decide if it wants to
leave anything powered on when suspended.  This in conjunction with the
IGNORE_SYSTEM_SUSPEND allows the DMP plus gyro and/or accel to continue
running while the main processor is suspended.  This can be used to wake
up the main processor on a particular motion event, or to record motion
events to be reported when the processor later wakes up.  This ioctl
signals that user space has finished configuring all sensors and the MPU
controller and that the MPU controller can continue.
=======================================
#define MPU_PM_EVENT_HANDLED	_IO(MPU_IOCTL, 0x32)

Requested sensors is a common place to know which sensors are on, and to
specify which sensors to turn on the next time the system is started.
This can be removed since it is redundant with power mode attributes I'm
proposing be used by each slave and the MPU controller.
=======================================
#define MPU_GET_REQUESTED_SENSORS	_IOR(MPU_IOCTL, 0x40, __u8)
#define MPU_SET_REQUESTED_SENSORS	_IOW(MPU_IOCTL, 0x40, __u8)

See my note on MPU_PM_EVENT_HANDLED above.  This can be made a SysFs
attribute of drivers/misc/inv_mpu
=======================================
#define MPU_GET_IGNORE_SYSTEM_SUSPEND	_IOR(MPU_IOCTL, 0x41, __u8)
#define MPU_SET_IGNORE_SYSTEM_SUSPEND	_IOW(MPU_IOCTL, 0x41, __u8)

These are bitfield of how the MPU controller state.  Which devices are
currently suspended, which devices are running, if the i2c master is
bypassed, if the DMP is running.  This can be made a SysFs attribute, and
perhaps removed.
=======================================
#define MPU_GET_MLDL_STATUS		_IOR(MPU_IOCTL, 0x42, __u8)

This is a bitfield showing the status of which of the master i2c channels
have been enabled.  The mpu3050 has 1 channel, and the mpu6050 has 5
channels.  This can become a sysfs attribute
=======================================
#define MPU_GET_I2C_SLAVES_ENABLED	_IOR(MPU_IOCTL, 0x43, __u8)

After all is said and done this is files that would be made available:
/dev/mpu
	Iotcl interface for memory and fifo reads writes, read for events
include pm events and irq events.

/sys/bus/iio/devices/device[ACCEL]/power_state
/sys/bus/iio/devices/device[ACCEL]/accel_x_raw
/sys/bus/iio/devices/device[ACCEL]/accel_y_raw
/sys/bus/iio/devices/device[ACCEL]/accel_z_raw
/sys/bus/iio/devices/device[ACCEL]/<other attributes as appropriate>

/sys/bus/iio/devices/device[MAGN]/power_state
/sys/bus/iio/devices/device[MAGN]/magn_x_raw
/sys/bus/iio/devices/device[MAGN]/magn_y_raw
/sys/bus/iio/devices/device[MAGN]/magn_z_raw
/sys/bus/iio/devices/device[MAGN]/<other attributes as appropriate>

/sys/bus/iio/devices/device[GYRO]/power_state
/sys/bus/iio/devices/device[GYRO]/gyro_x_raw
/sys/bus/iio/devices/device[GYRO]/gyro_y_raw
/sys/bus/iio/devices/device[GYRO]/gyro_z_raw
/sys/bus/iio/devices/device[GYRO]/<other attributes as appropriate>

Then for input ABS_X, ABS_Y and ABS_Z for each of the sensors containing
calibrated data.  There are a number of other computed data values we
would want to make available, but these can also be made available in user
space by the MPL if necessary.

> Can the slave interface appears to be an i? bus too or is the
> interface
> too different (ie could the smart mode create an i? bus that it uses
> to
> talk to the drivers to configure them for 'smart' mode)

I'm not exactly sure of the details of what you are suggesting, but
somehow telling a slave that it is now being used in 'smart' mode is fine,
as long as the MPU controller can still read back the information it needs
to control it, for example setting up the mpu3050 i2c master.

> I'm not entirely sure at this point I understand quite how all the
> pieces
> fit together.

It is a fairly complicated system, and why I want to get a good idea of
what we want long term before working on further changes.
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/misc/inv_mpu/README b/drivers/misc/inv_mpu/README
new file mode 100644
index 0000000..ce592c8
--- /dev/null
+++ b/drivers/misc/inv_mpu/README
@@ -0,0 +1,104 @@ 
+Kernel driver mpu
+=====================
+
+Supported chips:
+  * InvenSense IMU3050
+    Prefix: 'mpu3050'
+    Datasheet:
+        PS-MPU-3000A-00.2.4b.pdf
+
+Author: InvenSense <http://invensense.com>
+
+Description
+-----------
+The mpu is a motion processor unit that controls the mpu3050 gyroscope, a slave
+accelerometer, a compass and a pressure sensor.  This document describes how to
+install the driver into a Linux kernel.
+
+Sysfs entries
+-------------
+/dev/mpu
+/dev/mpuirq
+/dev/accelirq
+/dev/compassirq
+/dev/pressureirq
+
+General Remarks MPU3050
+-----------------------
+* Valid addresses for the MPU3050 is 0x68.
+* Accelerometer must be on the secondary I2C bus for MPU3050, the
+  magnetometer must be on the primary bus and pressure sensor must
+  be on the primary bus.
+
+Programming the chip using /dev/mpu
+----------------------------------
+Programming of MPU3050 is done by first opening the /dev/mpu file and
+then performing a series of IOCTLS on the handle returned.  The IOCTL codes can
+be found in mpu.h.  Typically this is done by the mllite library in user
+space.
+
+Board and Platform Data
+-----------------------
+
+In order for the driver to work, board and platform data specific to the device
+needs to be added to the board file.  A mpu_platform_data structure must
+be created and populated and set in the i2c_board_info_structure.  For details
+of each structure member see mpu.h.  All values below are simply an example and
+should be modified for your platform.
+
+#include <linux/mpu.h>
+
+static struct mpu_platform_data mpu3050_data = {
+	.int_config  = 0x10,
+	.orientation = {  -1,  0,  0,
+			   0,  1,  0,
+			   0,  0, -1 },
+};
+
+/* accel */
+static struct ext_slave_platform_data inv_mpu_kxtf9_data = {
+	.bus         = EXT_SLAVE_BUS_SECONDARY,
+	.orientation = {  -1,  0,  0,
+			  0,  1,  0,
+			  0,  0, -1 },
+};
+/* compass */
+static struct ext_slave_platform_data inv_mpu_ak8975_data = {
+	.bus         = EXT_SLAVE_BUS_PRIMARY,
+	.orientation = { 1, 0, 0,
+			 0, 1, 0,
+			 0, 0, 1 },
+};
+
+static struct i2c_board_info __initdata panda_inv_mpu_i2c4_boardinfo[] = {
+	{
+		I2C_BOARD_INFO("mpu3050", 0x68),
+		.irq = (IH_GPIO_BASE + MPUIRQ_GPIO),
+		.platform_data = &mpu3050_data,
+	},
+	{
+		I2C_BOARD_INFO("kxtf9", 0x0F),
+		.irq = (IH_GPIO_BASE + ACCEL_IRQ_GPIO),
+		.platform_data = &inv_mpu_kxtf9_data
+	},
+	{
+		I2C_BOARD_INFO("ak8975", 0x0E),
+		.irq = (IH_GPIO_BASE + COMPASS_IRQ_GPIO),
+		.platform_data = &inv_mpu_ak8975_data,
+	},
+};
+
+Typically the IRQ is a GPIO input pin and needs to be configured properly.  If
+in the above example GPIO 168 corresponds to IRQ 299, the following should be
+done as well:
+
+#define MPU_GPIO_IRQ 168
+
+    gpio_request(MPU_GPIO_IRQ,"MPUIRQ");
+    gpio_direction_input(MPU_GPIO_IRQ)
+
+Dynamic Debug
+=============
+
+The mpu3050 makes use of dynamic debug.  For details on how to use this
+refer to Documentation/dynamic-debug-howto.txt
diff --git a/include/linux/mpu.h b/include/linux/mpu.h
new file mode 100644
index 0000000..18d2da0
--- /dev/null
+++ b/include/linux/mpu.h
@@ -0,0 +1,365 @@ 
+/*
+	$License:
+	Copyright (C) 2011 InvenSense Corporation, All Rights Reserved.
+
+	This program is free software; you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation; either version 2 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program.  If not, see <http://www.gnu.org/licenses/>.
+	$
+ */
+
+#ifndef __MPU_H_
+#define __MPU_H_
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+/* Number of axes on each sensor */
+#define GYRO_NUM_AXES               (3)
+#define ACCEL_NUM_AXES              (3)
+#define COMPASS_NUM_AXES            (3)
+
+struct mpu_read_write {
+	/* Memory address or register address depending on ioctl */
+	__u16 address;
+	__u16 length;
+	__u8 *data;
+};
+
+enum mpuirq_data_type {
+	MPUIRQ_DATA_TYPE_MPU_IRQ,
+	MPUIRQ_DATA_TYPE_SLAVE_IRQ,
+	MPUIRQ_DATA_TYPE_PM_EVENT,
+	MPUIRQ_DATA_TYPE_NUM_TYPES,
+};
+
+/* User space PM event notification */
+#define MPU_PM_EVENT_SUSPEND_PREPARE (3)
+#define MPU_PM_EVENT_POST_SUSPEND    (4)
+
+struct mpuirq_data {
+	__u32 interruptcount;
+	__u64 irqtime;
+	__u32 data_type;
+	__s32 data;
+};
+
+enum ext_slave_config_key {
+	MPU_SLAVE_CONFIG_ODR_SUSPEND,
+	MPU_SLAVE_CONFIG_ODR_RESUME,
+	MPU_SLAVE_CONFIG_FSR_SUSPEND,
+	MPU_SLAVE_CONFIG_FSR_RESUME,
+	MPU_SLAVE_CONFIG_MOT_THS,
+	MPU_SLAVE_CONFIG_NMOT_THS,
+	MPU_SLAVE_CONFIG_MOT_DUR,
+	MPU_SLAVE_CONFIG_NMOT_DUR,
+	MPU_SLAVE_CONFIG_IRQ_SUSPEND,
+	MPU_SLAVE_CONFIG_IRQ_RESUME,
+	MPU_SLAVE_WRITE_REGISTERS,
+	MPU_SLAVE_READ_REGISTERS,
+	MPU_SLAVE_CONFIG_INTERNAL_REFERENCE,
+	/* AMI 306 specific config keys */
+	MPU_SLAVE_PARAM,
+	MPU_SLAVE_WINDOW,
+	MPU_SLAVE_READWINPARAMS,
+	MPU_SLAVE_SEARCHOFFSET,
+	/* AKM specific config keys */
+	MPU_SLAVE_READ_SCALE,
+	/* MPU3050 and MPU6050 Keys */
+	MPU_SLAVE_INT_CONFIG,
+	MPU_SLAVE_EXT_SYNC,
+	MPU_SLAVE_FULL_SCALE,
+	MPU_SLAVE_LPF,
+	MPU_SLAVE_CLK_SRC,
+	MPU_SLAVE_DIVIDER,
+	MPU_SLAVE_DMP_ENABLE,
+	MPU_SLAVE_FIFO_ENABLE,
+	MPU_SLAVE_DMP_CFG1,
+	MPU_SLAVE_DMP_CFG2,
+	MPU_SLAVE_TC,
+	MPU_SLAVE_GYRO,
+	MPU_SLAVE_ADDR,
+	MPU_SLAVE_PRODUCT_REVISION,
+	MPU_SLAVE_SILICON_REVISION,
+	MPU_SLAVE_PRODUCT_ID,
+	MPU_SLAVE_GYRO_SENS_TRIM,
+	MPU_SLAVE_ACCEL_SENS_TRIM,
+	MPU_SLAVE_RAM,
+	/* -------------------------- */
+	MPU_SLAVE_CONFIG_NUM_CONFIG_KEYS
+};
+
+/* For the MPU_SLAVE_CONFIG_IRQ_SUSPEND and MPU_SLAVE_CONFIG_IRQ_RESUME */
+enum ext_slave_config_irq_type {
+	MPU_SLAVE_IRQ_TYPE_NONE,
+	MPU_SLAVE_IRQ_TYPE_MOTION,
+	MPU_SLAVE_IRQ_TYPE_DATA_READY,
+};
+
+/* Structure for the following IOCTS's
+ * MPU_CONFIG_GYRO
+ * MPU_CONFIG_ACCEL
+ * MPU_CONFIG_COMPASS
+ * MPU_CONFIG_PRESSURE
+ * MPU_GET_CONFIG_GYRO
+ * MPU_GET_CONFIG_ACCEL
+ * MPU_GET_CONFIG_COMPASS
+ * MPU_GET_CONFIG_PRESSURE
+ *
+ * @key one of enum ext_slave_config_key
+ * @len length of data pointed to by data
+ * @apply zero if communication with the chip is not necessary, false otherwise
+ *        This flag can be used to select cached data or to refresh cashed data
+ *        cache data to be pushed later or push immediately.  If true and the
+ *        slave is on the secondary bus the MPU will first enger bypass mode
+ *        before calling the slaves .config or .get_config funcion
+ * @data pointer to the data to confgure or get
+ */
+struct ext_slave_config {
+	__u8 key;
+	__u16 len;
+	__u8 apply;
+	void *data;
+};
+
+enum ext_slave_type {
+	EXT_SLAVE_TYPE_GYROSCOPE,
+	EXT_SLAVE_TYPE_ACCEL,
+	EXT_SLAVE_TYPE_COMPASS,
+	EXT_SLAVE_TYPE_PRESSURE,
+	/*EXT_SLAVE_TYPE_TEMPERATURE */
+
+	EXT_SLAVE_NUM_TYPES
+};
+
+enum ext_slave_id {
+	ID_INVALID = 0,
+
+	ACCEL_ID_LIS331,
+	ACCEL_ID_LSM303A,
+	ACCEL_ID_LIS3DH,
+	ACCEL_ID_KXSD9,
+	ACCEL_ID_KXTF9,
+	ACCEL_ID_BMA150,
+	ACCEL_ID_BMA222,
+	ACCEL_ID_BMA250,
+	ACCEL_ID_ADXL34X,
+	ACCEL_ID_MMA8450,
+	ACCEL_ID_MMA845X,
+	ACCEL_ID_MPU6050,
+
+	COMPASS_ID_AK8975,
+	COMPASS_ID_AK8972,
+	COMPASS_ID_AMI30X,
+	COMPASS_ID_AMI306,
+	COMPASS_ID_YAS529,
+	COMPASS_ID_YAS530,
+	COMPASS_ID_HMC5883,
+	COMPASS_ID_LSM303M,
+	COMPASS_ID_MMC314X,
+	COMPASS_ID_HSCDTD002B,
+	COMPASS_ID_HSCDTD004A,
+
+	PRESSURE_ID_BMA085,
+};
+
+enum ext_slave_endian {
+	EXT_SLAVE_BIG_ENDIAN,
+	EXT_SLAVE_LITTLE_ENDIAN,
+	EXT_SLAVE_FS8_BIG_ENDIAN,
+	EXT_SLAVE_FS16_BIG_ENDIAN,
+};
+
+enum ext_slave_bus {
+	EXT_SLAVE_BUS_INVALID = -1,
+	EXT_SLAVE_BUS_PRIMARY = 0,
+	EXT_SLAVE_BUS_SECONDARY = 1
+};
+
+
+/**
+ *  struct ext_slave_platform_data - Platform data for mpu3050 and mpu6050
+ *  slave devices
+ *
+ *  @get_slave_descr: Function pointer to retrieve the struct ext_slave_descr
+ *                    for this slave
+ *  @irq: the irq number attached to the slave if any.
+ *  @adapt_num: the I2C adapter number.
+ *  @bus: the bus the slave is attached to: enum ext_slave_bus
+ *  @address: the I2C slave address of the slave device.
+ *  @orientation: the mounting matrix of the device relative to MPU.
+ *  @irq_data: private data for the slave irq handler
+ *  @private_data: additional data, user customizable.  Not touched by the MPU
+ *                 driver.
+ *
+ * The orientation matricies are 3x3 rotation matricies
+ * that are applied to the data to rotate from the mounting orientation to the
+ * platform orientation.  The values must be one of 0, 1, or -1 and each row and
+ * column should have exactly 1 non-zero value.
+ */
+struct ext_slave_platform_data {
+	__u8 type;
+	__u32 irq;
+	__u32 adapt_num;
+	__u32 bus;
+	__u8 address;
+	__s8 orientation[9];
+	void *irq_data;
+	void *private_data;
+};
+
+struct fix_pnt_range {
+	__s32 mantissa;
+	__s32 fraction;
+};
+
+static inline long range_fixedpoint_to_long_mg(struct fix_pnt_range rng)
+{
+	return (long)(rng.mantissa * 1000 + rng.fraction / 10);
+}
+
+struct ext_slave_read_trigger {
+	__u8 reg;
+	__u8 value;
+};
+
+/**
+ *  struct ext_slave_descr - Description of the slave device for programming.
+ *
+ *  @suspend:	function pointer to put the device in suspended state
+ *  @resume:	function pointer to put the device in running state
+ *  @read:	function that reads the device data
+ *  @init:	function used to preallocate memory used by the driver
+ *  @exit:	function used to free memory allocated for the driver
+ *  @config:	function used to configure the device
+ *  @get_config:function used to get the device's configuration
+ *
+ *  @name:	text name of the device
+ *  @type:	device type. enum ext_slave_type
+ *  @id:	enum ext_slave_id
+ *  @read_reg:	starting register address to retrieve data.
+ *  @read_len:	length in bytes of the sensor data.  Typically  6.
+ *  @endian:	byte order of the data. enum ext_slave_endian
+ *  @range:	full scale range of the slave ouput: struct fix_pnt_range
+ *  @trigger:	If reading data first requires writing a register this is the
+ *		data to write.
+ *
+ *  Defines the functions and information about the slave the mpu3050 and
+ *  mpu6050 needs to use the slave device.
+ */
+struct ext_slave_descr {
+	int (*init) (void *mlsl_handle,
+		     struct ext_slave_descr *slave,
+		     struct ext_slave_platform_data *pdata);
+	int (*exit) (void *mlsl_handle,
+		     struct ext_slave_descr *slave,
+		     struct ext_slave_platform_data *pdata);
+	int (*suspend) (void *mlsl_handle,
+			struct ext_slave_descr *slave,
+			struct ext_slave_platform_data *pdata);
+	int (*resume) (void *mlsl_handle,
+		       struct ext_slave_descr *slave,
+		       struct ext_slave_platform_data *pdata);
+	int (*read) (void *mlsl_handle,
+		     struct ext_slave_descr *slave,
+		     struct ext_slave_platform_data *pdata,
+		     __u8 *data);
+	int (*config) (void *mlsl_handle,
+		       struct ext_slave_descr *slave,
+		       struct ext_slave_platform_data *pdata,
+		       struct ext_slave_config *config);
+	int (*get_config) (void *mlsl_handle,
+			   struct ext_slave_descr *slave,
+			   struct ext_slave_platform_data *pdata,
+			   struct ext_slave_config *config);
+
+	char *name;
+	__u8 type;
+	__u8 id;
+	__u8 read_reg;
+	__u8 read_len;
+	__u8 endian;
+	struct fix_pnt_range range;
+	struct ext_slave_read_trigger *trigger;
+};
+
+/**
+ * struct mpu_platform_data - Platform data for the mpu driver
+ * @int_config:		Bits [7:3] of the int config register.
+ * @level_shifter:	0: VLogic, 1: VDD
+ * @orientation:	Orientation matrix of the gyroscope
+ *
+ * Contains platform specific information on how to configure the MPU3050 to
+ * work on this platform.  The orientation matricies are 3x3 rotation matricies
+ * that are applied to the data to rotate from the mounting orientation to the
+ * platform orientation.  The values must be one of 0, 1, or -1 and each row and
+ * column should have exactly 1 non-zero value.
+ */
+struct mpu_platform_data {
+	__u8 int_config;
+	__u8 level_shifter;
+	__s8 orientation[GYRO_NUM_AXES * GYRO_NUM_AXES];
+};
+
+#define MPU_IOCTL (0x81) /* Magic number for MPU Iocts */
+/* IOCTL commands for /dev/mpu */
+
+/*--------------------------------------------------------------------------
+ * Deprecated, debugging only
+ */
+#define MPU_SET_MPU_PLATFORM_DATA	\
+	_IOWR(MPU_IOCTL, 0x01, struct mpu_platform_data)
+#define MPU_SET_EXT_SLAVE_PLATFORM_DATA	\
+	_IOWR(MPU_IOCTL, 0x01, struct ext_slave_platform_data)
+/*--------------------------------------------------------------------------*/
+#define MPU_GET_EXT_SLAVE_PLATFORM_DATA	\
+	_IOWR(MPU_IOCTL, 0x02, struct ext_slave_platform_data)
+#define MPU_GET_MPU_PLATFORM_DATA	\
+	_IOWR(MPU_IOCTL, 0x02, struct mpu_platform_data)
+#define MPU_GET_EXT_SLAVE_DESCR	\
+	_IOWR(MPU_IOCTL, 0x02, struct ext_slave_descr)
+
+#define MPU_READ		_IOWR(MPU_IOCTL, 0x10, struct mpu_read_write)
+#define MPU_WRITE		_IOW(MPU_IOCTL,  0x10, struct mpu_read_write)
+#define MPU_READ_MEM		_IOWR(MPU_IOCTL, 0x11, struct mpu_read_write)
+#define MPU_WRITE_MEM		_IOW(MPU_IOCTL,  0x11, struct mpu_read_write)
+#define MPU_READ_FIFO		_IOWR(MPU_IOCTL, 0x12, struct mpu_read_write)
+#define MPU_WRITE_FIFO		_IOW(MPU_IOCTL,  0x12, struct mpu_read_write)
+
+#define MPU_READ_COMPASS	_IOR(MPU_IOCTL, 0x12, __u8)
+#define MPU_READ_ACCEL		_IOR(MPU_IOCTL, 0x13, __u8)
+#define MPU_READ_PRESSURE	_IOR(MPU_IOCTL, 0x14, __u8)
+
+#define MPU_CONFIG_GYRO		_IOW(MPU_IOCTL, 0x20, struct ext_slave_config)
+#define MPU_CONFIG_ACCEL	_IOW(MPU_IOCTL, 0x21, struct ext_slave_config)
+#define MPU_CONFIG_COMPASS	_IOW(MPU_IOCTL, 0x22, struct ext_slave_config)
+#define MPU_CONFIG_PRESSURE	_IOW(MPU_IOCTL, 0x23, struct ext_slave_config)
+
+#define MPU_GET_CONFIG_GYRO	_IOWR(MPU_IOCTL, 0x20, struct ext_slave_config)
+#define MPU_GET_CONFIG_ACCEL	_IOWR(MPU_IOCTL, 0x21, struct ext_slave_config)
+#define MPU_GET_CONFIG_COMPASS	_IOWR(MPU_IOCTL, 0x22, struct ext_slave_config)
+#define MPU_GET_CONFIG_PRESSURE	_IOWR(MPU_IOCTL, 0x23, struct ext_slave_config)
+
+#define MPU_SUSPEND		_IOW(MPU_IOCTL, 0x30, __u32)
+#define MPU_RESUME		_IOW(MPU_IOCTL, 0x31, __u32)
+/* Userspace PM Event response */
+#define MPU_PM_EVENT_HANDLED	_IO(MPU_IOCTL, 0x32)
+
+#define MPU_GET_REQUESTED_SENSORS	_IOR(MPU_IOCTL, 0x40, __u8)
+#define MPU_SET_REQUESTED_SENSORS	_IOW(MPU_IOCTL, 0x40, __u8)
+#define MPU_GET_IGNORE_SYSTEM_SUSPEND	_IOR(MPU_IOCTL, 0x41, __u8)
+#define MPU_SET_IGNORE_SYSTEM_SUSPEND	_IOW(MPU_IOCTL, 0x41, __u8)
+#define MPU_GET_MLDL_STATUS		_IOR(MPU_IOCTL, 0x42, __u8)
+#define MPU_GET_I2C_SLAVES_ENABLED	_IOR(MPU_IOCTL, 0x43, __u8)
+
+
+#endif				/* __MPU_H_ */