From d7c2157902bda8ff2373f6bff21da567369bed7b Mon Sep 17 00:00:00 2001 From: Xiaohui Tao Date: Wed, 5 Jun 2013 16:03:10 -0700 Subject: input: misc: sensor drivers Sensor drivers for MPU, compass, and pressure. New features include: - Improved power management - Completely powers off when not in use. - Individual axis power control. - Auto low power accelerometer. - HW motion detection that gets an IRQ only when orientation changes. - Improved performance - Auto detect POR readiness. - Auto detect reset/error completion. - HW access only when needed. - Streamlined execution path. - Separate reset control. - Runtime changes only affect the device being changed (removed carpet bombing global resets and disable/enables). - Separate sample rate for each device. A device not enabled doesn't inhibit a faster rate for an enabled device. - Multiple MPU slave devices. - Auto detection of MPU slave devices and allowing an external driver for a slave device to use or not use the MPU. - External bypass mode. Any external driver can control and lock the MPU I2C master bypass mode. - Improved FIFO control. Support for all devices to use the FIFO. - Separate reporting rate for each device. - Improved timestamping by taking a timestamp before and after the sample and using the average. - Allows generic class driver for slave devices. All drivers conform to a standard API. - Automatically handle configuration steps to enable a device and make run-time changes. - Improved debug support and added a debug API. - Add BMP180 pressure driver. - Added compass high speed feature where compass doesn't prevent the MPU devices from going faster than 100Hz. Needed for camera. - Added support for 8kHz Gyro and 1kHz accelerometer. Needed for camera. - Added support to populate Android sensor_t structure from kernel data. Bug 1212893 Bug 1161345 Bug 930909 Bug 1224709 Bug 1058689 Bug 1030747 Bug 980723 Change-Id: Ic0a38f015691cfaca1bc3e72422d5980eddc1265 Signed-off-by: Erik Lilliebjerg Signed-off-by: Xiaohui Tao Reviewed-on: http://git-master/r/210592 (cherry picked from commit 90e7c6b815a591eb0bac120c8b595766f2196ecb) Reviewed-on: http://git-master/r/216709 Reviewed-by: Mandar Padmawar Tested-by: Mandar Padmawar --- include/linux/mpu.h | 298 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 296 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/mpu.h b/include/linux/mpu.h index 1f78833c30f5..3f303da8266a 100644 --- a/include/linux/mpu.h +++ b/include/linux/mpu.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2012 Invensense, Inc. +* Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -47,8 +48,19 @@ * data defined by dbg_dat * - A read to dbg_dat initiates an I2C read transaction * to the device register defined by dbg_reg. +* dbg_i2c_addr = I2C device address +* - if set to 0 (default) the MPU I2C address is used. +* - other devices can be accessed by setting this to the +* that device I2C address. When used after enabling +* bypass mode, devices behind the MPU can be accessed. +* aux_dbg = write 1 to spew auxiliary port register dumps after +* after each external driver call. +* Write 0 to disable the spew. +* Writing anything takes a snapshot of the registers. +* Therefore, a write of 0 can take snapshots whenever +* without the external driver call spew. **********************************************************************/ -#define DEBUG_SYSFS_INTERFACE 0 +#define DEBUG_SYSFS_INTERFACE 1 /* Mount maxtices for mount orientation. * MTMAT_XXX_CCW_YYY @@ -251,7 +263,6 @@ enum ext_slave_bus { EXT_SLAVE_BUS_SECONDARY = 1 }; - /** * struct ext_slave_platform_data - Platform data for mpu3050 and mpu6050 * slave devices @@ -358,6 +369,12 @@ struct ext_slave_descr { struct ext_slave_read_trigger *trigger; }; + +#define NVI_CONFIG_BOOT_AUTO (0) /* auto detect connection to MPU */ +#define NVI_CONFIG_BOOT_MPU (1) /* connected to MPU */ +#define NVI_CONFIG_BOOT_EXTERNAL (2) /* connected to host */ +#define NVI_CONFIG_BOOT_MASK (0x03) + /** * struct mpu_platform_data - Platform data for the mpu driver * @int_config: Bits [7:3] of the int config register. @@ -367,6 +384,8 @@ struct ext_slave_descr { * @sec_slave_id: id of the secondary slave device * @secondary_i2c_address: secondary device's i2c address * @secondary_orientation: secondary device's orientation matrix + * @config: the selection determines the device behavior. + * Select from the NVI_CONFIG_BOOT_ defines. * * Contains platform specific information on how to configure the MPU3050 to * work on this platform. The orientation matricies are 3x3 rotation matricies @@ -384,6 +403,281 @@ struct mpu_platform_data { __u8 secondary_read_reg; __s8 secondary_orientation[9]; __u8 key[16]; + __u8 config; +}; + +/** + * struct nvi_mpu_port: Allows an external driver to use the MPU + * auxiliary I2C master by providing the details for the I2C + * polling of a device connected to the MPU. + * - addr: The 6:0 I2C address of the device connected to + * the MPU. + * 7:7 = 0 if the port is to do write transactions. + * = 1 if the port is to do read transactions. + * - reg: The device register the I2C transaction will + * use. + * - ctrl: The number of consecutive registers to read in + * 3:0. If the port is to do write transactions then this + * value must be 1. See MPU documentation for the other + * bits in I2C_SLVx_CTRL that can be applied by this byte. + * - data_out: The data byte written if the port is configured + * to do writes (addr 7:7 = 0). + * - delay_ms: The polling delay time between I2C transactions + * in ms. Note that the MPU HW only supports one delay + * time so the longest delay of all the MPU ports enabled + * is used. + * - delay_us: The delay at which the read data is reported. + * - shutdown_bypass: set if a connection to the host is needed + * when the system is shutdown. The MPU API will be + * disabled as part of its shutdown but it will enable the + * bypass if this is true. + * - *handler: The pointer to the function called when the data + * is available. This can be NULL if the port is + * configured for write transactions. + * The function is called with the following parameters: + * - *data: The pointer to the data to read. + * - length: The number of bytes to be read (same value as + * length above). + * - timestamp: The timestamp of when the data was polled. + * - *pointer: A generic pointer defined next below. Note + * that this can be NULL if this will be a write I2C + * transaction. + * - *ext_driver: A generic pointer that can be used by the + * external driver. Note that this is specifically for the + * external driver and not used by the MPU. + */ +struct nvi_mpu_port { + u8 addr; + u8 reg; + u8 ctrl; + u8 data_out; + unsigned int delay_ms; + unsigned long delay_us; + bool shutdown_bypass; + void (*handler)(u8 *data, unsigned int len, + long long timestamp, void *ext_driver); + void *ext_driver; }; +/** + * Expected use of the nvi_mpu_ routines are as follows: + * - nvi_mpu_dev_valid: Use to validate whether a device is + * connected to the MPU. + * - nvi_mpu_port_alloc: Request a connection to the device. If + * successful, a port number will be returned to identify + * the connection. The port number is then used for all + * further communication with the connection. + * - nvi_mpu_port_free: Use to close the port connection. + * - nvi_mpu_enable: Use to enable/disable a port. + * The enable and FIFO enable is disabled by default so + * this will be required after a port is assigned. + * - nvi_mpu_delay_us: Use to set the sampling rate in + * microseconds. The fastest rate of all the enabled MPU + * devices will be used that does not exceed the + * nvi_mpu_delay_ms setting of an enabled device. + * - nvi_mpu_delay_ms: Use to change the port polling delay at + * runtime. There is only one HW delay so the delay used + * will be the longest delay of all the enabled ports. + * This is separate from the sampling rate + * (nvi_mpu_delay_us). See function notes below. + * - nvi_mpu_data_out: Use to change the data written at runtime + * for ports that are configured as I2C write transactions. + * - nvi_mpu_bypass request/release: Use to connect/disconnect + * the MPU host from the device. When bypass is enabled, + * the connection from the device to the MPU will then be + * connected to the host (that the MPU is connected to). + * This is a global connection switch affecting all ports + * so a mechanism is in place of whether the request is + * honored or not. See the funtion notes for + * nvi_mpu_bypass_request. + */ + +/** + * Use to validate a device connected to the MPU I2C master. + * The function works by doing a single byte read or write to + * the device and detecting a NACK. Typically, the call would + * be set up to read a byte ID of the device. + * @param struct nvi_mpu_port *nmp + * Only the following is needed in nmp: + * - addr + * - reg + * - ctrl + * - data_out if a write transaction + * @param *val: pointer for read data. Can be NULL if write. + * @return int error + * Possible return value or errors are: + * - 0: device is connected to MPU. + * - -EAGAIN: MPU is not initialized yet. + * - -EPERM: MPU is shutdown. MPU API won't be + * available until a system restart. + * - -EBUSY: MPU is busy with another request. + * - -ENODEV: The device is not connected to the MPU. + * - -EINVAL: Problem with input parameters. + * - -EIO: The device is connected but responded with + * a NACK. + */ +int nvi_mpu_dev_valid(struct nvi_mpu_port *nmp, u8 *data); + +/** + * Request a port. + * @param struct nvi_mpu_port *nmp + * - addr: device I2C address 6:0. + * 7:7 = 0 if the port is to do writes. + * 7:7 = 1 if the port is to do reads. + * - reg: the starting register to write or read. + * - ctrl: number of bytes to read. Use 1 if port + * is configured to do writes. + * - data_out: only valid if port is configured to do + * writes. + * - delay: polling delay + * - handler: function to call when data is read. This + * should be NULL if the port is configured to do + * writes. + * - ext_driver: this pointer is passed in handler for + * use by external driver. This should be NULL + * if the port is configured for writes. + * @return int error/port id + * if return >= 0 then this is the port ID. The ID + * will have a value of 0 to 3 (HW has 4 ports). + * Possible errors are: + * - -EAGAIN: MPU is not initialized yet. + * - -EPERM: MPU is shutdown. MPU API won't be + * available until a system restart. + * - -EBUSY: MPU is busy with another request. + * - -ENODEV: A port is not available. The only way + * to resolve this error is for a port to be + * freed. + * - -EINVAL: Problem with input parameters. + */ +int nvi_mpu_port_alloc(struct nvi_mpu_port *nmp); + +/** + * Remove a port. + * @param port + * @return int error + * Possible errors are: + * - -EAGAIN: MPU is not initialized yet. + * - -EPERM: MPU is shutdown. MPU API won't be + * available until a system restart. + * - -EBUSY: MPU is busy with another request. + * - -EINVAL: Problem with input parameters. + */ +int nvi_mpu_port_free(int port); + +/** + * Enable/disable a port. + * @param port + * @param enable + * @return int error + * Possible errors are: + * - -EAGAIN: MPU is not initialized yet. + * - -EPERM: MPU is shutdown. MPU API won't be + * available until a system restart. + * - -EBUSY: MPU is busy with another request. + * - -EINVAL: Problem with input parameters. + */ +int nvi_mpu_enable(int port, bool enable, bool fifo_enable); + +/** + * Use to change the ports sampling delay in microseconds. The + * hardware only supports one sampling rate so the shortest time + * is used among all enabled ports, accelerometer, and gyro. If + * the requested rate is longer than the actual rate and the + * port is configured for reads, the data will be reported at + * the requested rate skipping the data polled at the faster + * rate. Setting this to zero causes other enabled devices to + * determine the sampling rate. If there are no other enabled + * devices, then the MPU default rate is used. + * @param port + * @param delay_us + * @return int error + * Possible errors are: + * - -EAGAIN: MPU is not initialized yet. + * - -EPERM: MPU is shutdown. MPU API won't be + * available until a system restart. + * - -EBUSY: MPU is busy with another request. + * - -EINVAL: Problem with input parameters. + */ +int nvi_mpu_delay_us(int port, unsigned long delay_us); + +/** + * Use to change the ports polling delay in milliseconds. + * A delay value of 0 disables the delay for that port. The + * hardware only supports one delay value so the largest request + * of all the enabled ports is used. The polling delay is in + * addition to the sampling delay (nvi_mpu_delay_us). This is + * typically used to guarantee a delay after an I2C write to a + * device to allow the device to process the request and be read + * by another port before another write at the sampling delay. + * + * @param port + * @param delay_ms + * @return int error/delay used or 0 if request is to disable + * and is successful. + * Possible errors are: + * - -EAGAIN: MPU is not initialized yet. + * - -EPERM: MPU is shutdown. MPU API won't be + * available until a system restart. + * - -EBUSY: MPU is busy with another request. + * - -EINVAL: Problem with input parameters. + */ +int nvi_mpu_delay_ms(int port, u8 delay_ms); + +/** + * Use to change the data written to the sensor. + * @param port + * @param data_out is the new data to be written + * @return int error + * Possible errors are: + * - -EAGAIN: MPU is not initialized yet. + * - -EPERM: MPU is shutdown. MPU API won't be + * available until a system restart. + * - -EBUSY: MPU is busy with another request. + * - -EINVAL: Problem with input parameters. + */ +int nvi_mpu_data_out(int port, u8 data_out); + +/** + * Enable/disable the MPU bypass mode. When enabled, the MPU + * will connect its auxiliary I2C ports to the host. This is + * typically used to initialize a device that requires more I2C + * transactions than the automated port polling can offer. + * EVERY nvi_mpu_bypass_request call must be balanced with a + * nvi_mpu_bypass_release call! + * A bypass request does not need a following ~enable call. The + * release call will automatically handle the correct bypass + * enable setting. The request locks the bypass setting if + * successful. The release unlocks and restores the setting if + * need be. Although odd, the purpose of the request call with + * the enable cleared to false is to allow an external driver to + * access its device that would normally conflict with a device + * behind the MPU. Note that this call must not be a permanent + * solution, i.e. delayed or no release call. + * When the MPU is in a shutdown state the return error will be + * -EPERM and bypass will be enabled to allow access from the + * host to the devices connected to the MPU for their own + * shutdown needs. + * @param enable + * @return int error: calls that return with an error must not + * be balanced with a release call. + * Possible errors are: + * - -EAGAIN: MPU is not initialized yet. + * - -EPERM: MPU is shutdown. MPU API won't be + * available until a system restart. + * - -EBUSY: MPU is busy with another request. + */ +int nvi_mpu_bypass_request(bool enable); + +/** + * See the nvi_mpu_bypass_request notes. + * @return int error: calls that return with an error must be + * tried again. + * Possible errors are: + * - -EAGAIN: MPU is not initialized yet. + * - -EPERM: MPU is shutdown. MPU API won't be + * available until a system restart. + * - -EBUSY: MPU is busy with another request. + */ +int nvi_mpu_bypass_release(void); + #endif /* __MPU_H_ */ -- cgit v1.2.3