Message ID | 1309486707-1658-1-git-send-email-nroyer@invensense.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
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
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
> 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
> 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
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
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
> 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
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
> > 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
> > # 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.
> > > 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
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
> 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
> 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
> > 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
> 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
> 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 --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_ */
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