summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Collins <rcollins@nvidia.com>2011-04-20 13:23:12 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:46:34 -0800
commite5512fc51e5ff029b68b1749a7434c9536430a33 (patch)
treeea59755ce8d4716fcd57cb3623fc2dbfe9d6b89c
parent7c794b5c6d257ac62694e02860abb80613f66d1a (diff)
mpu3050: Motion Libraries: Update MPU kernel to v3.3.4.
Update 1 of 3: MPU kernel files. Depends on board file and defconfig file. BUG 808052 Original-Change-Id: I42b08570d3a8dac090860276e04f6d2ab7545461 Reviewed-on: http://git-master/r/29724 Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com> Reviewed-by: Robert R Collins <rcollins@nvidia.com> Tested-by: Robert R Collins <rcollins@nvidia.com> Rebase-Id: R13b53bb717968041f18f76031f32377fabdf8c43
-rw-r--r--drivers/misc/mpu3050/Makefile12
-rw-r--r--drivers/misc/mpu3050/compass/ak8975.c74
-rw-r--r--drivers/misc/mpu3050/log.h116
-rw-r--r--drivers/misc/mpu3050/mldl_cfg.c41
-rw-r--r--drivers/misc/mpu3050/mldl_cfg.h1
-rw-r--r--drivers/misc/mpu3050/mlsl-kernel.c10
-rw-r--r--drivers/misc/mpu3050/mltypes.h4
-rw-r--r--drivers/misc/mpu3050/mpu-dev.c626
-rw-r--r--drivers/misc/mpu3050/mpuirq.c7
-rw-r--r--drivers/misc/mpu3050/mpuirq.h14
-rw-r--r--drivers/misc/mpu3050/slaveirq.c11
-rw-r--r--drivers/misc/mpu3050/slaveirq.h9
-rw-r--r--drivers/misc/mpu3050/timerirq.c14
-rw-r--r--drivers/misc/mpu3050/timerirq.h10
-rw-r--r--include/linux/mpu.h131
15 files changed, 610 insertions, 470 deletions
diff --git a/drivers/misc/mpu3050/Makefile b/drivers/misc/mpu3050/Makefile
index c7e1b863e588..89ac46fdac5b 100644
--- a/drivers/misc/mpu3050/Makefile
+++ b/drivers/misc/mpu3050/Makefile
@@ -67,6 +67,10 @@ ifdef CONFIG_MPU_SENSORS_AMI30X
mpu3050-objs += $(MLLITE_DIR)compass/ami30x.o
endif
+ifdef CONFIG_MPU_SENSORS_AMI306
+mpu3050-objs += $(MLLITE_DIR)compass/ami306.o
+endif
+
ifdef CONFIG_MPU_SENSORS_HMC5883
mpu3050-objs += $(MLLITE_DIR)compass/hmc5883.o
endif
@@ -83,6 +87,10 @@ ifdef CONFIG_MPU_SENSORS_YAS529
mpu3050-objs += $(MLLITE_DIR)compass/yas529-kernel.o
endif
+ifdef CONFIG_MPU_SENSORS_YAS530
+mpu3050-objs += $(MLLITE_DIR)compass/yas530.o
+endif
+
ifdef CONFIG_MPU_SENSORS_HSCDTD002B
mpu3050-objs += $(MLLITE_DIR)compass/hscdtd002b.o
endif
@@ -122,7 +130,3 @@ endif
obj-$(CONFIG_MPU_SENSORS_TIMERIRQ)+= timerirq.o
-ifdef CONFIG_MPU_SENSORS_DEBUG
-EXTRA_CFLAGS += -DDEBUG
-endif
-
diff --git a/drivers/misc/mpu3050/compass/ak8975.c b/drivers/misc/mpu3050/compass/ak8975.c
index 991de77dbd01..b8aed30ba39b 100644
--- a/drivers/misc/mpu3050/compass/ak8975.c
+++ b/drivers/misc/mpu3050/compass/ak8975.c
@@ -160,14 +160,84 @@ int ak8975_read(void *mlsl_handle,
return status;
}
+static int ak8975_config(void *mlsl_handle,
+ struct ext_slave_descr *slave,
+ struct ext_slave_platform_data *pdata,
+ struct ext_slave_config *data)
+{
+ int result;
+ if (!data->data)
+ return ML_ERROR_INVALID_PARAMETER;
+
+ switch (data->key) {
+ case MPU_SLAVE_WRITE_REGISTERS:
+ result = MLSLSerialWrite(mlsl_handle, pdata->address,
+ data->len,
+ (unsigned char *)data->data);
+ ERROR_CHECK(result);
+ break;
+ case MPU_SLAVE_CONFIG_ODR_SUSPEND:
+ case MPU_SLAVE_CONFIG_ODR_RESUME:
+ case MPU_SLAVE_CONFIG_FSR_SUSPEND:
+ case MPU_SLAVE_CONFIG_FSR_RESUME:
+ case MPU_SLAVE_CONFIG_MOT_THS:
+ case MPU_SLAVE_CONFIG_NMOT_THS:
+ case MPU_SLAVE_CONFIG_MOT_DUR:
+ case MPU_SLAVE_CONFIG_NMOT_DUR:
+ case MPU_SLAVE_CONFIG_IRQ_SUSPEND:
+ case MPU_SLAVE_CONFIG_IRQ_RESUME:
+ default:
+ return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
+ };
+
+ return ML_SUCCESS;
+}
+
+static int ak8975_get_config(void *mlsl_handle,
+ struct ext_slave_descr *slave,
+ struct ext_slave_platform_data *pdata,
+ struct ext_slave_config *data)
+{
+ int result;
+ if (!data->data)
+ return ML_ERROR_INVALID_PARAMETER;
+
+ switch (data->key) {
+ case MPU_SLAVE_READ_REGISTERS:
+ {
+ unsigned char *serial_data = (unsigned char *)data->data;
+ result = MLSLSerialRead(mlsl_handle, pdata->address,
+ serial_data[0],
+ data->len - 1,
+ &serial_data[1]);
+ ERROR_CHECK(result);
+ break;
+ }
+ case MPU_SLAVE_CONFIG_ODR_SUSPEND:
+ case MPU_SLAVE_CONFIG_ODR_RESUME:
+ case MPU_SLAVE_CONFIG_FSR_SUSPEND:
+ case MPU_SLAVE_CONFIG_FSR_RESUME:
+ case MPU_SLAVE_CONFIG_MOT_THS:
+ case MPU_SLAVE_CONFIG_NMOT_THS:
+ case MPU_SLAVE_CONFIG_MOT_DUR:
+ case MPU_SLAVE_CONFIG_NMOT_DUR:
+ case MPU_SLAVE_CONFIG_IRQ_SUSPEND:
+ case MPU_SLAVE_CONFIG_IRQ_RESUME:
+ default:
+ return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
+ };
+
+ return ML_SUCCESS;
+}
+
struct ext_slave_descr ak8975_descr = {
/*.init = */ NULL,
/*.exit = */ NULL,
/*.suspend = */ ak8975_suspend,
/*.resume = */ ak8975_resume,
/*.read = */ ak8975_read,
- /*.config = */ NULL,
- /*.get_config = */ NULL,
+ /*.config = */ ak8975_config,
+ /*.get_config = */ ak8975_get_config,
/*.name = */ "ak8975",
/*.type = */ EXT_SLAVE_TYPE_COMPASS,
/*.id = */ COMPASS_ID_AKM,
diff --git a/drivers/misc/mpu3050/log.h b/drivers/misc/mpu3050/log.h
index ceee28526265..f2f9ea7ece8e 100644
--- a/drivers/misc/mpu3050/log.h
+++ b/drivers/misc/mpu3050/log.h
@@ -70,14 +70,14 @@ extern "C" {
#else
/* Based off the log priorities in android
/system/core/include/android/log.h */
-#define MPL_LOG_UNKNOWN (0)
-#define MPL_LOG_DEFAULT (1)
-#define MPL_LOG_VERBOSE (2)
-#define MPL_LOG_DEBUG (3)
-#define MPL_LOG_INFO (4)
-#define MPL_LOG_WARN (5)
-#define MPL_LOG_ERROR (6)
-#define MPL_LOG_SILENT (8)
+#define MPL_LOG_UNKNOWN (0)
+#define MPL_LOG_DEFAULT (1)
+#define MPL_LOG_VERBOSE (2)
+#define MPL_LOG_DEBUG (3)
+#define MPL_LOG_INFO (4)
+#define MPL_LOG_WARN (5)
+#define MPL_LOG_ERROR (6)
+#define MPL_LOG_SILENT (8)
#endif
@@ -101,9 +101,13 @@ extern "C" {
*/
#ifndef MPL_LOGV
#if MPL_LOG_NDEBUG
-#define MPL_LOGV(...) ((void)0)
+#define MPL_LOGV(fmt, ...) \
+ do { \
+ if (0) \
+ MPL_LOG(LOG_VERBOSE, MPL_LOG_TAG, fmt, ##__VA_ARGS__);\
+ } while (0)
#else
-#define MPL_LOGV(...) ((void)MPL_LOG(LOG_VERBOSE, MPL_LOG_TAG, __VA_ARGS__))
+#define MPL_LOGV(fmt, ...) MPL_LOG(LOG_VERBOSE, MPL_LOG_TAG, fmt, ##__VA_ARGS__)
#endif
#endif
@@ -113,11 +117,12 @@ extern "C" {
#ifndef MPL_LOGV_IF
#if MPL_LOG_NDEBUG
-#define MPL_LOGV_IF(cond, ...) ((void)0)
+#define MPL_LOGV_IF(cond, fmt, ...) \
+ do { if (0) MPL_LOG(fmt, ##__VA_ARGS__); } while (0)
#else
-#define MPL_LOGV_IF(cond, ...) \
+#define MPL_LOGV_IF(cond, fmt, ...) \
((CONDITION(cond)) \
- ? ((void)MPL_LOG(LOG_VERBOSE, MPL_LOG_TAG, __VA_ARGS__)) \
+ ? MPL_LOG(LOG_VERBOSE, MPL_LOG_TAG, fmt, ##__VA_ARGS__) \
: (void)0)
#endif
#endif
@@ -126,13 +131,13 @@ extern "C" {
* Simplified macro to send a debug log message using the current MPL_LOG_TAG.
*/
#ifndef MPL_LOGD
-#define MPL_LOGD(...) ((void)MPL_LOG(LOG_DEBUG, MPL_LOG_TAG, __VA_ARGS__))
+#define MPL_LOGD(fmt, ...) MPL_LOG(LOG_DEBUG, MPL_LOG_TAG, fmt, ##__VA_ARGS__)
#endif
#ifndef MPL_LOGD_IF
-#define MPL_LOGD_IF(cond, ...) \
+#define MPL_LOGD_IF(cond, fmt, ...) \
((CONDITION(cond)) \
- ? ((void)MPL_LOG(LOG_DEBUG, MPL_LOG_TAG, __VA_ARGS__)) \
+ ? MPL_LOG(LOG_DEBUG, MPL_LOG_TAG, fmt, ##__VA_ARGS__) \
: (void)0)
#endif
@@ -140,13 +145,13 @@ extern "C" {
* Simplified macro to send an info log message using the current MPL_LOG_TAG.
*/
#ifndef MPL_LOGI
-#define MPL_LOGI(...) ((void)MPL_LOG(LOG_INFO, MPL_LOG_TAG, __VA_ARGS__))
+#define MPL_LOGI(fmt, ...) MPL_LOG(LOG_INFO, MPL_LOG_TAG, fmt, ##__VA_ARGS__)
#endif
#ifndef MPL_LOGI_IF
-#define MPL_LOGI_IF(cond, ...) \
+#define MPL_LOGI_IF(cond, fmt, ...) \
((CONDITION(cond)) \
- ? ((void)MPL_LOG(LOG_INFO, MPL_LOG_TAG, __VA_ARGS__)) \
+ ? MPL_LOG(LOG_INFO, MPL_LOG_TAG, fmt, ##__VA_ARGS__) \
: (void)0)
#endif
@@ -154,13 +159,17 @@ extern "C" {
* Simplified macro to send a warning log message using the current MPL_LOG_TAG.
*/
#ifndef MPL_LOGW
-#define MPL_LOGW(...) ((void)MPL_LOG(LOG_WARN, MPL_LOG_TAG, __VA_ARGS__))
+#ifdef __KERNEL__
+#define MPL_LOGW(fmt, ...) printk(KERN_WARNING MPL_LOG_TAG fmt, ##__VA_ARGS__)
+#else
+#define MPL_LOGW(fmt, ...) MPL_LOG(LOG_WARN, MPL_LOG_TAG, fmt, ##__VA_ARGS__)
+#endif
#endif
#ifndef MPL_LOGW_IF
-#define MPL_LOGW_IF(cond, ...) \
+#define MPL_LOGW_IF(cond, fmt, ...) \
((CONDITION(cond)) \
- ? ((void)MPL_LOG(LOG_WARN, MPL_LOG_TAG, __VA_ARGS__)) \
+ ? MPL_LOG(LOG_WARN, MPL_LOG_TAG, fmt, ##__VA_ARGS__) \
: (void)0)
#endif
@@ -168,13 +177,17 @@ extern "C" {
* Simplified macro to send an error log message using the current MPL_LOG_TAG.
*/
#ifndef MPL_LOGE
-#define MPL_LOGE(...) ((void)MPL_LOG(LOG_ERROR, MPL_LOG_TAG, __VA_ARGS__))
+#ifdef __KERNEL__
+#define MPL_LOGE(fmt, ...) printk(KERN_ERR MPL_LOG_TAG fmt, ##__VA_ARGS__)
+#else
+#define MPL_LOGE(fmt, ...) MPL_LOG(LOG_ERROR, MPL_LOG_TAG, fmt, ##__VA_ARGS__)
+#endif
#endif
#ifndef MPL_LOGE_IF
-#define MPL_LOGE_IF(cond, ...) \
+#define MPL_LOGE_IF(cond, fmt, ...) \
((CONDITION(cond)) \
- ? ((void)MPL_LOG(LOG_ERROR, MPL_LOG_TAG, __VA_ARGS__)) \
+ ? MPL_LOG(LOG_ERROR, MPL_LOG_TAG, fmt, ##__VA_ARGS__) \
: (void)0)
#endif
@@ -186,35 +199,43 @@ extern "C" {
* It is NOT stripped from release builds. Note that the condition test
* is -inverted- from the normal assert() semantics.
*/
-#define MPL_LOG_ALWAYS_FATAL_IF(cond, ...) \
+#define MPL_LOG_ALWAYS_FATAL_IF(cond, fmt, ...) \
((CONDITION(cond)) \
- ? ((void)android_printAssert(#cond, MPL_LOG_TAG, __VA_ARGS__)) \
+ ? ((void)android_printAssert(#cond, MPL_LOG_TAG, \
+ fmt, ##__VA_ARGS__)) \
: (void)0)
-#define MPL_LOG_ALWAYS_FATAL(...) \
- (((void)android_printAssert(NULL, MPL_LOG_TAG, __VA_ARGS__)))
+#define MPL_LOG_ALWAYS_FATAL(fmt, ...) \
+ (((void)android_printAssert(NULL, MPL_LOG_TAG, fmt, ##__VA_ARGS__)))
/*
* Versions of MPL_LOG_ALWAYS_FATAL_IF and MPL_LOG_ALWAYS_FATAL that
* are stripped out of release builds.
*/
#if MPL_LOG_NDEBUG
-
-#define MPL_LOG_FATAL_IF(cond, ...) ((void)0)
-#define MPL_LOG_FATAL(...) ((void)0)
-
+#define MPL_LOG_FATAL_IF(cond, fmt, ...) \
+ do { \
+ if (0) \
+ MPL_LOG_ALWAYS_FATAL_IF(cond, fmt, ##__VA_ARGS__); \
+ } while (0)
+#define MPL_LOG_FATAL(fmt, ...) \
+ do { \
+ if (0) \
+ MPL_LOG_ALWAYS_FATAL(fmt, ##__VA_ARGS__) \
+ } while (0)
#else
-
-#define MPL_LOG_FATAL_IF(cond, ...) MPL_LOG_ALWAYS_FATAL_IF(cond, __VA_ARGS__)
-#define MPL_LOG_FATAL(...) MPL_LOG_ALWAYS_FATAL(__VA_ARGS__)
-
+#define MPL_LOG_FATAL_IF(cond, fmt, ...) \
+ MPL_LOG_ALWAYS_FATAL_IF(cond, fmt, ##__VA_ARGS__)
+#define MPL_LOG_FATAL(fmt, ...) \
+ MPL_LOG_ALWAYS_FATAL(fmt, ##__VA_ARGS__)
#endif
/*
* Assertion that generates a log message when the assertion fails.
* Stripped out of release builds. Uses the current MPL_LOG_TAG.
*/
-#define MPL_LOG_ASSERT(cond, ...) MPL_LOG_FATAL_IF(!(cond), __VA_ARGS__)
+#define MPL_LOG_ASSERT(cond, fmt, ...) \
+ MPL_LOG_FATAL_IF(!(cond), fmt, ##__VA_ARGS__)
/* --------------------------------------------------------------------- */
@@ -227,8 +248,8 @@ extern "C" {
* The second argument may be NULL or "" to indicate the "global" tag.
*/
#ifndef MPL_LOG
-#define MPL_LOG(priority, tag, ...) \
- MPL_LOG_PRI(priority, tag, __VA_ARGS__)
+#define MPL_LOG(priority, tag, fmt, ...) \
+ MPL_LOG_PRI(priority, tag, fmt, ##__VA_ARGS__)
#endif
/*
@@ -236,14 +257,14 @@ extern "C" {
*/
#ifndef MPL_LOG_PRI
#ifdef ANDROID
-#define MPL_LOG_PRI(priority, tag, ...) \
- LOG(priority, tag, __VA_ARGS__)
+#define MPL_LOG_PRI(priority, tag, fmt, ...) \
+ LOG(priority, tag, fmt, ##__VA_ARGS__)
#elif defined __KERNEL__
-#define MPL_LOG_PRI(priority, tag, ...) \
- printk(MPL_##priority tag __VA_ARGS__)
+#define MPL_LOG_PRI(priority, tag, fmt, ...) \
+ pr_debug(MPL_##priority tag fmt, ##__VA_ARGS__)
#else
-#define MPL_LOG_PRI(priority, tag, ...) \
- _MLPrintLog(MPL_##priority, tag, __VA_ARGS__)
+#define MPL_LOG_PRI(priority, tag, fmt, ...) \
+ _MLPrintLog(MPL_##priority, tag, fmt, ##__VA_ARGS__)
#endif
#endif
@@ -255,8 +276,7 @@ extern "C" {
#define MPL_LOG_PRI_VA(priority, tag, fmt, args) \
android_vprintLog(priority, NULL, tag, fmt, args)
#elif defined __KERNEL__
-#define MPL_LOG_PRI_VA(priority, tag, fmt, args) \
- vprintk(MPL_##priority tag fmt, args)
+/* not allowed in the Kernel because there is no dev_dbg that takes a va_list */
#else
#define MPL_LOG_PRI_VA(priority, tag, fmt, args) \
_MLPrintVaLog(priority, NULL, tag, fmt, args)
diff --git a/drivers/misc/mpu3050/mldl_cfg.c b/drivers/misc/mpu3050/mldl_cfg.c
index 66f447e7ba85..9cc4cf690386 100644
--- a/drivers/misc/mpu3050/mldl_cfg.c
+++ b/drivers/misc/mpu3050/mldl_cfg.c
@@ -297,7 +297,7 @@ static int MLDLGetSiliconRev(struct mldl_cfg *pdata,
result = MLSLSerialReadMem(mlsl_handle, pdata->addr,
memAddr, 1, &index);
- ERROR_CHECK(result)
+ ERROR_CHECK(result);
if (result)
return result;
index >>= 2;
@@ -306,7 +306,7 @@ static int MLDLGetSiliconRev(struct mldl_cfg *pdata,
result =
MLSLSerialWriteSingle(mlsl_handle, pdata->addr,
MPUREG_BANK_SEL, 0);
- ERROR_CHECK(result)
+ ERROR_CHECK(result);
if (result)
return result;
@@ -330,20 +330,28 @@ static int MLDLGetSiliconRev(struct mldl_cfg *pdata,
}
/**
- * @brief Enable/Disable the use MPU's VDDIO level shifters.
- * When enabled the voltage interface with AUX or other external
- * accelerometer is using Vlogic instead of VDD (supply).
+ * @brief Enable / Disable the use MPU's secondary I2C interface level
+ * shifters.
+ * When enabled the secondary I2C interface to which the external
+ * device is connected runs at VDD voltage (main supply).
+ * When disabled the 2nd interface runs at VDDIO voltage.
+ * See the device specification for more details.
*
- * @note Must be called after MLSerialOpen().
- * @note Typically be called before MLDmpOpen().
- * If called after MLDmpOpen(), must be followed by a call to
- * MLDLApplyLevelShifterBit() to write the setting on the hw.
+ * @note using this API may produce unpredictable results, depending on how
+ * the MPU and slave device are setup on the target platform.
+ * Use of this API should entirely be restricted to system
+ * integrators. Once the correct value is found, there should be no
+ * need to change the level shifter at runtime.
*
- * @param[in] enable
- * 1 to enable, 0 to disable
+ * @pre Must be called after MLSerialOpen().
+ * @note Typically called before MLDmpOpen().
*
- * @return ML_SUCCESS if successfull, a non-zero error code otherwise.
-**/
+ * @param[in] enable:
+ * 0 to run at VDDIO (default),
+ * 1 to run at VDD.
+ *
+ * @return ML_SUCCESS if successfull, a non-zero error code otherwise.
+ */
static int MLDLSetLevelShifterBit(struct mldl_cfg *pdata,
void *mlsl_handle,
unsigned char enable)
@@ -358,9 +366,9 @@ static int MLDLSetLevelShifterBit(struct mldl_cfg *pdata,
return ML_ERROR_INVALID_PARAMETER;
/*-- on parts before B6 the VDDIO bit is bit 7 of ACCEL_BURST_ADDR --
- NOTE: this is incompatible with ST accelerometers where the VDDIO
- bit MUST be set to enable ST's internal logic to autoincrement
- the register address on burst reads --*/
+ NOTE: this is incompatible with ST accelerometers where the VDDIO
+ bit MUST be set to enable ST's internal logic to autoincrement
+ the register address on burst reads --*/
if ((pdata->silicon_revision & 0xf) < MPU_SILICON_REV_B6) {
reg = MPUREG_ACCEL_BURST_ADDR;
mask = 0x80;
@@ -1123,6 +1131,7 @@ int mpu3050_open(struct mldl_cfg *mldl_cfg,
{
int result;
/* Default is Logic HIGH, pushpull, latch disabled, anyread to clear */
+ mldl_cfg->ignore_system_suspend = FALSE;
mldl_cfg->int_config = BIT_INT_ANYRD_2CLEAR | BIT_DMP_INT_EN;
mldl_cfg->clk_src = MPU_CLK_SEL_PLLGYROZ;
mldl_cfg->lpf = MPU_FILTER_42HZ;
diff --git a/drivers/misc/mpu3050/mldl_cfg.h b/drivers/misc/mpu3050/mldl_cfg.h
index ee3a1e3dd05f..ad6a211c5d86 100644
--- a/drivers/misc/mpu3050/mldl_cfg.h
+++ b/drivers/misc/mpu3050/mldl_cfg.h
@@ -93,6 +93,7 @@
struct mldl_cfg {
/* MPU related configuration */
unsigned long requested_sensors;
+ unsigned char ignore_system_suspend;
unsigned char addr;
unsigned char int_config;
unsigned char ext_sync;
diff --git a/drivers/misc/mpu3050/mlsl-kernel.c b/drivers/misc/mpu3050/mlsl-kernel.c
index 908b16f16b24..cb1605131cbf 100644
--- a/drivers/misc/mpu3050/mlsl-kernel.c
+++ b/drivers/misc/mpu3050/mlsl-kernel.c
@@ -96,7 +96,8 @@ tMLError MLSLSerialWriteSingle(void *sl_handle,
*/
tMLError MLSLSerialWrite(void *sl_handle,
unsigned char slaveAddr,
- unsigned short length, unsigned char const *data)
+ unsigned short length,
+ unsigned char const *data)
{
tMLError result;
const unsigned short dataLength = length - 1;
@@ -187,10 +188,9 @@ tMLError MLSLSerialWriteMem(void *sl_handle,
unsigned short bytesWritten = 0;
if ((memAddr & 0xFF) + length > MPU_MEM_BANK_SIZE) {
- printk
- ("memory read length (%d B) extends beyond its limits (%d) "
- "if started at location %d\n", length,
- MPU_MEM_BANK_SIZE, memAddr & 0xFF);
+ pr_err("memory read length (%d B) extends beyond its"
+ " limits (%d) if started at location %d\n", length,
+ MPU_MEM_BANK_SIZE, memAddr & 0xFF);
return ML_ERROR_INVALID_PARAMETER;
}
while (bytesWritten < length) {
diff --git a/drivers/misc/mpu3050/mltypes.h b/drivers/misc/mpu3050/mltypes.h
index 5c1b684e5b50..d0b27fa89e78 100644
--- a/drivers/misc/mpu3050/mltypes.h
+++ b/drivers/misc/mpu3050/mltypes.h
@@ -136,13 +136,13 @@ typedef int_fast8_t bool;
/* - ML Errors. - */
#define ERROR_NAME(x) (#x)
#define ERROR_CHECK(x) \
- { \
+ do { \
if (ML_SUCCESS != x) { \
MPL_LOGE("%s|%s|%d returning %d\n", \
__FILE__, __func__, __LINE__, x); \
return x; \
} \
- }
+ } while (0)
#define ERROR_CHECK_FIRST(first, x) \
{ if (ML_SUCCESS == first) first = x; }
diff --git a/drivers/misc/mpu3050/mpu-dev.c b/drivers/misc/mpu3050/mpu-dev.c
index 115639f84704..e7ddd1cb45ac 100644
--- a/drivers/misc/mpu3050/mpu-dev.c
+++ b/drivers/misc/mpu3050/mpu-dev.c
@@ -1,9 +1,10 @@
/*
- mpu-dev.c - mpu3050 char device interface
+ mpu-dev.c - mpu3050 char device interface 2 $License:
Copyright (C) 1995-97 Simon G. Vogl
Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
+
Copyright (C) 2010 InvenSense Corporation, All Rights Reserved.
This program is free software; you can redistribute it and/or modify
@@ -18,8 +19,6 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/* Code inside mpudev_ioctl_rdrw is copied from i2c-dev.c
*/
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
@@ -36,7 +35,9 @@
#include <linux/slab.h>
#include <linux/version.h>
#include <linux/pm.h>
-
+#include <linux/mutex.h>
+#include <linux/suspend.h>
+#include <linux/poll.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
@@ -65,28 +66,97 @@ struct mpu_private_data {
#ifdef CONFIG_HAS_EARLYSUSPEND
struct early_suspend early_suspend;
#endif
+ struct mutex mutex;
+ wait_queue_head_t mpu_event_wait;
+ struct completion completion;
+ struct timer_list timeout;
+ struct notifier_block nb;
+ struct mpuirq_data mpu_pm_event;
+ int response_timeout; /* In seconds */
+ unsigned long event;
+ int pid;
};
-static int pid;
-
static struct i2c_client *this_client;
+
+static void
+mpu_pm_timeout(u_long data)
+{
+ struct mpu_private_data *mpu = (struct mpu_private_data *) data;
+ dev_dbg(&this_client->adapter->dev, "%s\n", __func__);
+ complete(&mpu->completion);
+}
+
+static int mpu_pm_notifier_callback(struct notifier_block *nb,
+ unsigned long event,
+ void *unused)
+{
+ struct mpu_private_data *mpu =
+ container_of(nb, struct mpu_private_data, nb);
+ struct timeval event_time;
+ dev_dbg(&this_client->adapter->dev, "%s: %ld\n", __func__, event);
+
+ /* Prevent the file handle from being closed before we initialize
+ the completion event */
+ mutex_lock(&mpu->mutex);
+ if (!(mpu->pid) ||
+ (event != PM_SUSPEND_PREPARE && event != PM_POST_SUSPEND)) {
+ mutex_unlock(&mpu->mutex);
+ return NOTIFY_OK;
+ }
+
+ do_gettimeofday(&event_time);
+ mpu->mpu_pm_event.interruptcount++;
+ mpu->mpu_pm_event.irqtime =
+ (((long long) event_time.tv_sec) << 32) +
+ event_time.tv_usec;
+ mpu->mpu_pm_event.data_type = MPUIRQ_DATA_TYPE_PM_EVENT;
+ mpu->mpu_pm_event.data_size = sizeof(unsigned long);
+ mpu->mpu_pm_event.data = &mpu->event;
+
+ if (event == PM_SUSPEND_PREPARE)
+ mpu->event = MPU_PM_EVENT_SUSPEND_PREPARE;
+ if (event == PM_POST_SUSPEND)
+ mpu->event = MPU_PM_EVENT_POST_SUSPEND;
+
+ if (mpu->response_timeout > 0) {
+ mpu->timeout.expires = jiffies + mpu->response_timeout * HZ;
+ add_timer(&mpu->timeout);
+ }
+ INIT_COMPLETION(mpu->completion);
+ mutex_unlock(&mpu->mutex);
+
+ wake_up_interruptible(&mpu->mpu_event_wait);
+ wait_for_completion(&mpu->completion);
+ del_timer_sync(&mpu->timeout);
+ dev_dbg(&this_client->adapter->dev, "%s: %ld DONE\n", __func__, event);
+ return NOTIFY_OK;
+}
+
static int mpu_open(struct inode *inode, struct file *file)
{
struct mpu_private_data *mpu =
(struct mpu_private_data *) i2c_get_clientdata(this_client);
struct mldl_cfg *mldl_cfg = &mpu->mldl_cfg;
-
+ int result;
dev_dbg(&this_client->adapter->dev, "mpu_open\n");
dev_dbg(&this_client->adapter->dev, "current->pid %d\n",
current->pid);
- pid = current->pid;
+ mpu->pid = current->pid;
file->private_data = this_client;
/* we could do some checking on the flags supplied by "open" */
/* i.e. O_NONBLOCK */
/* -> set some flag to disable interruptible_sleep_on in mpu_read */
/* Reset the sensors to the default */
+ result = mutex_lock_interruptible(&mpu->mutex);
+ if (result) {
+ dev_err(&this_client->adapter->dev,
+ "%s: mutex_lock_interruptible returned %d\n",
+ __func__, result);
+ return result;
+ }
mldl_cfg->requested_sensors = ML_THREE_AXIS_GYRO;
if (mldl_cfg->accel && mldl_cfg->accel->resume)
mldl_cfg->requested_sensors |= ML_THREE_AXIS_ACCEL;
@@ -96,7 +166,7 @@ static int mpu_open(struct inode *inode, struct file *file)
if (mldl_cfg->pressure && mldl_cfg->pressure->resume)
mldl_cfg->requested_sensors |= ML_THREE_AXIS_PRESSURE;
-
+ mutex_unlock(&mpu->mutex);
return 0;
}
@@ -113,130 +183,80 @@ static int mpu_release(struct inode *inode, struct file *file)
struct i2c_adapter *pressure_adapter;
int result = 0;
- pid = 0;
-
accel_adapter = i2c_get_adapter(mldl_cfg->pdata->accel.adapt_num);
compass_adapter = i2c_get_adapter(mldl_cfg->pdata->compass.adapt_num);
pressure_adapter = i2c_get_adapter(mldl_cfg->pdata->pressure.adapt_num);
+
+ mutex_lock(&mpu->mutex);
result = mpu3050_suspend(mldl_cfg, client->adapter,
accel_adapter, compass_adapter,
pressure_adapter,
TRUE, TRUE, TRUE, TRUE);
-
+ mpu->pid = 0;
+ mutex_unlock(&mpu->mutex);
+ complete(&mpu->completion);
dev_dbg(&this_client->adapter->dev, "mpu_release\n");
return result;
}
-static noinline int mpudev_ioctl_rdrw(struct i2c_client *client,
- unsigned long arg)
+/* read function called when from /dev/mpu is read. Read from the FIFO */
+static ssize_t mpu_read(struct file *file,
+ char __user *buf, size_t count, loff_t *offset)
{
- struct i2c_rdwr_ioctl_data rdwr_arg;
- struct i2c_msg *rdwr_pa;
- u8 __user **data_ptrs;
- int i, res;
-
- if (copy_from_user(&rdwr_arg,
- (struct i2c_rdwr_ioctl_data __user *) arg,
- sizeof(rdwr_arg)))
- return -EFAULT;
+ struct mpuirq_data local_mpu_pm_event;
+ struct i2c_client *client =
+ (struct i2c_client *) file->private_data;
+ struct mpu_private_data *mpu =
+ (struct mpu_private_data *) i2c_get_clientdata(client);
+ size_t len = sizeof(mpu->mpu_pm_event) + sizeof(unsigned long);
+ int err;
- /* Put an arbitrary limit on the number of messages that can
- * be sent at once */
- if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS)
- return -EINVAL;
+ if (!mpu->event && (!(file->f_flags & O_NONBLOCK)))
+ wait_event_interruptible(mpu->mpu_event_wait, mpu->event);
- rdwr_pa = (struct i2c_msg *)
- kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg), GFP_KERNEL);
- if (!rdwr_pa)
- return -ENOMEM;
+ if (!mpu->event || NULL == buf
+ || count < sizeof(mpu->mpu_pm_event) + sizeof(unsigned long))
+ return 0;
- if (copy_from_user(rdwr_pa, rdwr_arg.msgs,
- rdwr_arg.nmsgs * sizeof(struct i2c_msg))) {
- kfree(rdwr_pa);
+ err = copy_from_user(&local_mpu_pm_event, buf,
+ sizeof(mpu->mpu_pm_event));
+ if (err != 0) {
+ dev_err(&this_client->adapter->dev,
+ "Copy from user returned %d\n", err);
return -EFAULT;
}
- data_ptrs =
- kmalloc(rdwr_arg.nmsgs * sizeof(u8 __user *), GFP_KERNEL);
- if (data_ptrs == NULL) {
- kfree(rdwr_pa);
- return -ENOMEM;
- }
-
- res = 0;
- for (i = 0; i < rdwr_arg.nmsgs; i++) {
- /* Limit the size of the message to a sane amount;
- * and don't let length change either. */
- if ((rdwr_pa[i].len > 8192) ||
- (rdwr_pa[i].flags & I2C_M_RECV_LEN)) {
- res = -EINVAL;
- break;
- }
- data_ptrs[i] = (u8 __user *) rdwr_pa[i].buf;
- rdwr_pa[i].buf = kmalloc(rdwr_pa[i].len, GFP_KERNEL);
- if (rdwr_pa[i].buf == NULL) {
- res = -ENOMEM;
- break;
- }
- if (copy_from_user(rdwr_pa[i].buf, data_ptrs[i],
- rdwr_pa[i].len)) {
- ++i; /* Needs to be kfreed too */
- res = -EFAULT;
- break;
- }
- }
- if (res < 0) {
- int j;
- for (j = 0; j < i; ++j)
- kfree(rdwr_pa[j].buf);
- kfree(data_ptrs);
- kfree(rdwr_pa);
- return res;
+ mpu->mpu_pm_event.data = local_mpu_pm_event.data;
+ err = copy_to_user((unsigned long __user *)local_mpu_pm_event.data,
+ &mpu->event,
+ sizeof(mpu->event));
+ if (err != 0) {
+ dev_err(&this_client->adapter->dev,
+ "Copy to user returned %d\n", err);
+ return -EFAULT;
}
-
- res = i2c_transfer(client->adapter, rdwr_pa, rdwr_arg.nmsgs);
- while (i-- > 0) {
- if (res >= 0 && (rdwr_pa[i].flags & I2C_M_RD)) {
- if (copy_to_user(data_ptrs[i], rdwr_pa[i].buf,
- rdwr_pa[i].len))
- res = -EFAULT;
- }
- kfree(rdwr_pa[i].buf);
+ err = copy_to_user(buf, &mpu->mpu_pm_event, sizeof(mpu->mpu_pm_event));
+ if (err != 0) {
+ dev_err(&this_client->adapter->dev,
+ "Copy to user returned %d\n", err);
+ return -EFAULT;
}
- kfree(data_ptrs);
- kfree(rdwr_pa);
- return res;
+ mpu->event = 0;
+ return len;
}
-/* read function called when from /dev/mpu is read. Read from the FIFO */
-static ssize_t mpu_read(struct file *file,
- char __user *buf, size_t count, loff_t *offset)
+static unsigned int mpu_poll(struct file *file, struct poll_table_struct *poll)
{
- char *tmp;
- int ret;
-
struct i2c_client *client =
(struct i2c_client *) file->private_data;
+ struct mpu_private_data *mpu =
+ (struct mpu_private_data *) i2c_get_clientdata(client);
+ int mask = 0;
- if (count > 8192)
- count = 8192;
-
- tmp = kmalloc(count, GFP_KERNEL);
- if (tmp == NULL)
- return -ENOMEM;
-
- pr_debug("i2c-dev: i2c-%d reading %zu bytes.\n",
- iminor(file->f_path.dentry->d_inode), count);
-
-/* @todo fix this to do a i2c trasnfer from the FIFO */
- ret = i2c_master_recv(client, tmp, count);
- if (ret >= 0) {
- ret = copy_to_user(buf, tmp, count) ? -EFAULT : ret;
- if (ret)
- ret = -EFAULT;
- }
- kfree(tmp);
- return ret;
+ poll_wait(file, &mpu->mpu_event_wait, poll);
+ if (mpu->event)
+ mask |= POLLIN | POLLRDNORM;
+ return mask;
}
static int
@@ -466,40 +486,36 @@ out:
static int slave_config(void *adapter,
struct mldl_cfg *mldl_cfg,
struct ext_slave_descr *slave,
+ struct ext_slave_platform_data *pdata,
struct ext_slave_config __user *usr_config)
{
int retval = ML_SUCCESS;
- if ((slave) && (slave->config)) {
- struct ext_slave_config config;
- retval = copy_from_user(
- &config,
- usr_config,
- sizeof(config));
- if (retval)
- return -EFAULT;
-
- if (config.len && config.data) {
- int *data;
- data = kzalloc(config.len, GFP_KERNEL);
- if (!data)
- return ML_ERROR_MEMORY_EXAUSTED;
-
- retval = copy_from_user(data,
- (void __user *)config.data,
- config.len);
- if (retval) {
- retval = -EFAULT;
- kfree(data);
- return retval;
- }
- config.data = data;
+ struct ext_slave_config config;
+ if ((!slave) || (!slave->config))
+ return retval;
+
+ retval = copy_from_user(&config, usr_config, sizeof(config));
+ if (retval)
+ return -EFAULT;
+
+ if (config.len && config.data) {
+ int *data;
+ data = kzalloc(config.len, GFP_KERNEL);
+ if (!data)
+ return ML_ERROR_MEMORY_EXAUSTED;
+
+ retval = copy_from_user(data,
+ (void __user *)config.data,
+ config.len);
+ if (retval) {
+ retval = -EFAULT;
+ kfree(data);
+ return retval;
}
- retval = slave->config(adapter,
- slave,
- &mldl_cfg->pdata->accel,
- &config);
- kfree(config.data);
+ config.data = data;
}
+ retval = slave->config(adapter, slave, pdata, &config);
+ kfree(config.data);
return retval;
}
@@ -516,49 +532,111 @@ static int slave_config(void *adapter,
static int slave_get_config(void *adapter,
struct mldl_cfg *mldl_cfg,
struct ext_slave_descr *slave,
+ struct ext_slave_platform_data *pdata,
struct ext_slave_config __user *usr_config)
{
int retval = ML_SUCCESS;
- if ((slave) && (slave->get_config)) {
- struct ext_slave_config config;
- void *user_data;
- retval = copy_from_user(
- &config,
- usr_config,
- sizeof(config));
- if (retval)
- return -EFAULT;
-
- user_data = config.data;
- if (config.len && config.data) {
- int *data;
- data = kzalloc(config.len, GFP_KERNEL);
- if (!data)
- return ML_ERROR_MEMORY_EXAUSTED;
-
- retval = copy_from_user(data,
- (void __user *)config.data,
- config.len);
- if (retval) {
- retval = -EFAULT;
- kfree(data);
- return retval;
- }
- config.data = data;
- }
- retval = slave->get_config(adapter,
- slave,
- &mldl_cfg->pdata->accel,
- &config);
+ struct ext_slave_config config;
+ void *user_data;
+ if (!(slave) || !(slave->get_config))
+ return ML_SUCCESS;
+
+ retval = copy_from_user(&config, usr_config, sizeof(config));
+ if (retval)
+ return -EFAULT;
+
+ user_data = config.data;
+ if (config.len && config.data) {
+ int *data;
+ data = kzalloc(config.len, GFP_KERNEL);
+ if (!data)
+ return ML_ERROR_MEMORY_EXAUSTED;
+
+ retval = copy_from_user(data,
+ (void __user *)config.data,
+ config.len);
if (retval) {
- kfree(config.data);
+ retval = -EFAULT;
+ kfree(data);
return retval;
}
- retval = copy_to_user((unsigned char __user *) user_data,
- config.data,
- config.len);
+ config.data = data;
+ }
+ retval = slave->get_config(adapter, slave, pdata, &config);
+ if (retval) {
kfree(config.data);
+ return retval;
}
+ retval = copy_to_user((unsigned char __user *) user_data,
+ config.data,
+ config.len);
+ kfree(config.data);
+ return retval;
+}
+
+static int mpu_handle_mlsl(void *sl_handle,
+ unsigned char addr,
+ unsigned int cmd,
+ struct mpu_read_write __user *usr_msg)
+{
+ int retval = ML_SUCCESS;
+ struct mpu_read_write msg;
+ unsigned char *user_data;
+ retval = copy_from_user(&msg, usr_msg, sizeof(msg));
+ if (retval)
+ return -EFAULT;
+
+ user_data = msg.data;
+ if (msg.length && msg.data) {
+ unsigned char *data;
+ data = kzalloc(msg.length, GFP_KERNEL);
+ if (!data)
+ return ML_ERROR_MEMORY_EXAUSTED;
+
+ retval = copy_from_user(data,
+ (void __user *)msg.data,
+ msg.length);
+ if (retval) {
+ retval = -EFAULT;
+ kfree(data);
+ return retval;
+ }
+ msg.data = data;
+ } else {
+ return ML_ERROR_INVALID_PARAMETER;
+ }
+
+ switch (cmd) {
+ case MPU_READ:
+ retval = MLSLSerialRead(sl_handle, addr,
+ msg.address, msg.length, msg.data);
+ break;
+ case MPU_WRITE:
+ retval = MLSLSerialWrite(sl_handle, addr,
+ msg.length, msg.data);
+ break;
+ case MPU_READ_MEM:
+ retval = MLSLSerialReadMem(sl_handle, addr,
+ msg.address, msg.length, msg.data);
+ break;
+ case MPU_WRITE_MEM:
+ retval = MLSLSerialWriteMem(sl_handle, addr,
+ msg.address, msg.length, msg.data);
+ break;
+ case MPU_READ_FIFO:
+ retval = MLSLSerialReadFifo(sl_handle, addr,
+ msg.length, msg.data);
+ break;
+ case MPU_WRITE_FIFO:
+ retval = MLSLSerialWriteFifo(sl_handle, addr,
+ msg.length, msg.data);
+ break;
+
+ };
+ retval = copy_to_user((unsigned char __user *) user_data,
+ msg.data,
+ msg.length);
+ kfree(msg.data);
return retval;
}
@@ -582,160 +660,67 @@ static long mpu_ioctl(struct file *file,
pressure_adapter =
i2c_get_adapter(mldl_cfg->pdata->pressure.adapt_num);
+ retval = mutex_lock_interruptible(&mpu->mutex);
+ if (retval) {
+ dev_err(&this_client->adapter->dev,
+ "%s: mutex_lock_interruptible returned %d\n",
+ __func__, retval);
+ return retval;
+ }
+
switch (cmd) {
- case I2C_RDWR:
- mpudev_ioctl_rdrw(client, arg);
- break;
- case I2C_SLAVE:
- if ((arg & 0x7E) != (client->addr & 0x7E)) {
- dev_err(&this_client->adapter->dev,
- "%s: Invalid I2C_SLAVE arg %lu\n",
- __func__, arg);
- }
- break;
case MPU_SET_MPU_CONFIG:
retval = mpu_ioctl_set_mpu_config(client, arg);
break;
- case MPU_SET_INT_CONFIG:
- mldl_cfg->int_config = (unsigned char) arg;
- break;
- case MPU_SET_EXT_SYNC:
- mldl_cfg->ext_sync = (enum mpu_ext_sync) arg;
- break;
- case MPU_SET_FULL_SCALE:
- mldl_cfg->full_scale = (enum mpu_fullscale) arg;
- break;
- case MPU_SET_LPF:
- mldl_cfg->lpf = (enum mpu_filter) arg;
- break;
- case MPU_SET_CLK_SRC:
- mldl_cfg->clk_src = (enum mpu_clock_sel) arg;
- break;
- case MPU_SET_DIVIDER:
- mldl_cfg->divider = (unsigned char) arg;
- break;
- case MPU_SET_LEVEL_SHIFTER:
- mldl_cfg->pdata->level_shifter = (unsigned char) arg;
- break;
- case MPU_SET_DMP_ENABLE:
- mldl_cfg->dmp_enable = (unsigned char) arg;
- break;
- case MPU_SET_FIFO_ENABLE:
- mldl_cfg->fifo_enable = (unsigned char) arg;
- break;
- case MPU_SET_DMP_CFG1:
- mldl_cfg->dmp_cfg1 = (unsigned char) arg;
- break;
- case MPU_SET_DMP_CFG2:
- mldl_cfg->dmp_cfg2 = (unsigned char) arg;
- break;
- case MPU_SET_OFFSET_TC:
- retval = copy_from_user(mldl_cfg->offset_tc,
- (unsigned char __user *) arg,
- sizeof(mldl_cfg->offset_tc));
- if (retval)
- retval = -EFAULT;
-
- break;
- case MPU_SET_RAM:
- retval = copy_from_user(mldl_cfg->ram,
- (unsigned char __user *) arg,
- sizeof(mldl_cfg->ram));
- if (retval)
- retval = -EFAULT;
- break;
case MPU_SET_PLATFORM_DATA:
retval = mpu_ioctl_set_mpu_pdata(client, arg);
break;
case MPU_GET_MPU_CONFIG:
retval = mpu_ioctl_get_mpu_config(client, arg);
break;
- case MPU_GET_INT_CONFIG:
- retval = put_user(mldl_cfg->int_config,
- (unsigned char __user *) arg);
- break;
- case MPU_GET_EXT_SYNC:
- retval = put_user(mldl_cfg->ext_sync,
- (unsigned char __user *) arg);
- break;
- case MPU_GET_FULL_SCALE:
- retval = put_user(mldl_cfg->full_scale,
- (unsigned char __user *) arg);
- break;
- case MPU_GET_LPF:
- retval = put_user(mldl_cfg->lpf,
- (unsigned char __user *) arg);
- break;
- case MPU_GET_CLK_SRC:
- retval = put_user(mldl_cfg->clk_src,
- (unsigned char __user *) arg);
- break;
- case MPU_GET_DIVIDER:
- retval = put_user(mldl_cfg->divider,
- (unsigned char __user *) arg);
- break;
- case MPU_GET_LEVEL_SHIFTER:
- retval = put_user(mldl_cfg->pdata->level_shifter,
- (unsigned char __user *) arg);
- break;
- case MPU_GET_DMP_ENABLE:
- retval = put_user(mldl_cfg->dmp_enable,
- (unsigned char __user *) arg);
- break;
- case MPU_GET_FIFO_ENABLE:
- retval = put_user(mldl_cfg->fifo_enable,
- (unsigned char __user *) arg);
- break;
- case MPU_GET_DMP_CFG1:
- retval = put_user(mldl_cfg->dmp_cfg1,
- (unsigned char __user *) arg);
- break;
- case MPU_GET_DMP_CFG2:
- retval = put_user(mldl_cfg->dmp_cfg2,
- (unsigned char __user *) arg);
- break;
- case MPU_GET_OFFSET_TC:
- retval = copy_to_user((unsigned char __user *) arg,
- mldl_cfg->offset_tc,
- sizeof(mldl_cfg->offset_tc));
- if (retval)
- retval = -EFAULT;
- break;
- case MPU_GET_RAM:
- retval = copy_to_user((unsigned char __user *) arg,
- mldl_cfg->ram,
- sizeof(mldl_cfg->ram));
- if (retval)
- retval = -EFAULT;
+ case MPU_READ:
+ case MPU_WRITE:
+ case MPU_READ_MEM:
+ case MPU_WRITE_MEM:
+ case MPU_READ_FIFO:
+ case MPU_WRITE_FIFO:
+ retval = mpu_handle_mlsl(client->adapter, mldl_cfg->addr, cmd,
+ (struct mpu_read_write __user *) arg);
break;
case MPU_CONFIG_ACCEL:
retval = slave_config(accel_adapter, mldl_cfg,
mldl_cfg->accel,
+ &mldl_cfg->pdata->accel,
(struct ext_slave_config __user *) arg);
break;
case MPU_CONFIG_COMPASS:
retval = slave_config(compass_adapter, mldl_cfg,
mldl_cfg->compass,
+ &mldl_cfg->pdata->compass,
(struct ext_slave_config __user *) arg);
break;
case MPU_CONFIG_PRESSURE:
retval = slave_config(pressure_adapter, mldl_cfg,
mldl_cfg->pressure,
+ &mldl_cfg->pdata->pressure,
(struct ext_slave_config __user *) arg);
break;
case MPU_GET_CONFIG_ACCEL:
retval = slave_get_config(accel_adapter, mldl_cfg,
mldl_cfg->accel,
+ &mldl_cfg->pdata->accel,
(struct ext_slave_config __user *) arg);
break;
case MPU_GET_CONFIG_COMPASS:
retval = slave_get_config(compass_adapter, mldl_cfg,
mldl_cfg->compass,
+ &mldl_cfg->pdata->compass,
(struct ext_slave_config __user *) arg);
break;
case MPU_GET_CONFIG_PRESSURE:
retval = slave_get_config(pressure_adapter, mldl_cfg,
mldl_cfg->pressure,
+ &mldl_cfg->pdata->pressure,
(struct ext_slave_config __user *) arg);
break;
case MPU_SUSPEND:
@@ -772,6 +757,11 @@ static long mpu_ioctl(struct file *file,
sensors & ML_THREE_AXIS_PRESSURE);
}
break;
+ case MPU_PM_EVENT_HANDLED:
+ dev_dbg(&this_client->adapter->dev,
+ "%s: %d\n", __func__, cmd);
+ complete(&mpu->completion);
+ break;
case MPU_READ_ACCEL:
{
unsigned char data[6];
@@ -812,15 +802,14 @@ static long mpu_ioctl(struct file *file,
retval = -EFAULT;
}
break;
- case MPU_READ_MEMORY:
- case MPU_WRITE_MEMORY:
default:
dev_err(&this_client->adapter->dev,
- "%s: Unknown cmd %d, arg %lu\n", __func__, cmd,
+ "%s: Unknown cmd %x, arg %lu\n", __func__, cmd,
arg);
retval = -EINVAL;
}
+ mutex_unlock(&mpu->mutex);
return retval;
}
@@ -844,10 +833,13 @@ void mpu3050_early_suspend(struct early_suspend *h)
dev_dbg(&this_client->adapter->dev, "%s: %d, %d\n", __func__,
h->level, mpu->mldl_cfg.gyro_is_suspended);
- if (MPU3050_EARLY_SUSPEND_IN_DRIVER)
+ if (MPU3050_EARLY_SUSPEND_IN_DRIVER) {
+ mutex_lock(&mpu->mutex);
(void) mpu3050_suspend(mldl_cfg, this_client->adapter,
accel_adapter, compass_adapter,
pressure_adapter, TRUE, TRUE, TRUE, TRUE);
+ mutex_unlock(&mpu->mutex);
+ }
}
void mpu3050_early_resume(struct early_suspend *h)
@@ -868,8 +860,9 @@ void mpu3050_early_resume(struct early_suspend *h)
i2c_get_adapter(mldl_cfg->pdata->pressure.adapt_num);
if (MPU3050_EARLY_SUSPEND_IN_DRIVER) {
- if (pid) {
+ if (mpu->pid) {
unsigned long sensors = mldl_cfg->requested_sensors;
+ mutex_lock(&mpu->mutex);
(void) mpu3050_resume(mldl_cfg,
this_client->adapter,
accel_adapter,
@@ -879,8 +872,9 @@ void mpu3050_early_resume(struct early_suspend *h)
sensors & ML_THREE_AXIS_ACCEL,
sensors & ML_THREE_AXIS_COMPASS,
sensors & ML_THREE_AXIS_PRESSURE);
+ mutex_unlock(&mpu->mutex);
dev_dbg(&this_client->adapter->dev,
- "%s for pid %d\n", __func__, pid);
+ "%s for pid %d\n", __func__, mpu->pid);
}
}
dev_dbg(&this_client->adapter->dev, "%s: %d\n", __func__, h->level);
@@ -902,9 +896,11 @@ void mpu_shutdown(struct i2c_client *client)
pressure_adapter =
i2c_get_adapter(mldl_cfg->pdata->pressure.adapt_num);
+ mutex_lock(&mpu->mutex);
(void) mpu3050_suspend(mldl_cfg, this_client->adapter,
accel_adapter, compass_adapter, pressure_adapter,
TRUE, TRUE, TRUE, TRUE);
+ mutex_unlock(&mpu->mutex);
dev_dbg(&this_client->adapter->dev, "%s\n", __func__);
}
@@ -923,7 +919,8 @@ int mpu_suspend(struct i2c_client *client, pm_message_t mesg)
pressure_adapter =
i2c_get_adapter(mldl_cfg->pdata->pressure.adapt_num);
- if (!mpu->mldl_cfg.gyro_is_suspended) {
+ mutex_lock(&mpu->mutex);
+ if (!mldl_cfg->ignore_system_suspend) {
dev_dbg(&this_client->adapter->dev,
"%s: suspending on event %d\n", __func__,
mesg.event);
@@ -936,6 +933,7 @@ int mpu_suspend(struct i2c_client *client, pm_message_t mesg)
"%s: Already suspended %d\n", __func__,
mesg.event);
}
+ mutex_unlock(&mpu->mutex);
return 0;
}
@@ -954,7 +952,8 @@ int mpu_resume(struct i2c_client *client)
pressure_adapter =
i2c_get_adapter(mldl_cfg->pdata->pressure.adapt_num);
- if (pid) {
+ mutex_lock(&mpu->mutex);
+ if (mpu->pid && !mldl_cfg->ignore_system_suspend) {
unsigned long sensors = mldl_cfg->requested_sensors;
(void) mpu3050_resume(mldl_cfg, this_client->adapter,
accel_adapter,
@@ -965,8 +964,9 @@ int mpu_resume(struct i2c_client *client)
sensors & ML_THREE_AXIS_COMPASS,
sensors & ML_THREE_AXIS_PRESSURE);
dev_dbg(&this_client->adapter->dev,
- "%s for pid %d\n", __func__, pid);
+ "%s for pid %d\n", __func__, mpu->pid);
}
+ mutex_unlock(&mpu->mutex);
return 0;
}
@@ -974,6 +974,8 @@ int mpu_resume(struct i2c_client *client)
static const struct file_operations mpu_fops = {
.owner = THIS_MODULE,
.read = mpu_read,
+ .poll = mpu_poll,
+
#if HAVE_COMPAT_IOCTL
.compat_ioctl = mpu_ioctl,
#endif
@@ -1007,7 +1009,7 @@ int mpu3050_probe(struct i2c_client *client,
struct i2c_adapter *accel_adapter = NULL;
struct i2c_adapter *compass_adapter = NULL;
struct i2c_adapter *pressure_adapter = NULL;
-
+ printk("Ameer's changes...\n");
dev_dbg(&client->adapter->dev, "%s\n", __func__);
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
@@ -1024,10 +1026,25 @@ int mpu3050_probe(struct i2c_client *client,
i2c_set_clientdata(client, mpu);
this_client = client;
mldl_cfg = &mpu->mldl_cfg;
+
+ init_waitqueue_head(&mpu->mpu_event_wait);
+
+ mutex_init(&mpu->mutex);
+ init_completion(&mpu->completion);
+
+ mpu->response_timeout = 60; /* Seconds */
+ mpu->timeout.function = mpu_pm_timeout;
+ mpu->timeout.data = (u_long) mpu;
+ init_timer(&mpu->timeout);
+
+ mpu->nb.notifier_call = mpu_pm_notifier_callback;
+ mpu->nb.priority = 0;
+ register_pm_notifier(&mpu->nb);
+
pdata = (struct mpu3050_platform_data *) client->dev.platform_data;
if (!pdata) {
- dev_warn(&this_client->adapter->dev,
- "Warning no platform data for mpu3050\n");
+ dev_WARN(&this_client->adapter->dev,
+ "Missing platform data for mpu3050\n");
} else {
mldl_cfg->pdata = pdata;
@@ -1056,7 +1073,7 @@ int mpu3050_probe(struct i2c_client *client,
if (res)
goto out_accelirq_failed;
} else {
- dev_warn(&this_client->adapter->dev,
+ dev_WARN(&this_client->adapter->dev,
"WARNING: Accel irq not assigned\n");
}
} else {
@@ -1143,8 +1160,8 @@ int mpu3050_probe(struct i2c_client *client,
if (res)
goto out_mpuirq_failed;
} else {
- dev_warn(&this_client->adapter->dev,
- "WARNING: %s irq not assigned\n", MPU_NAME);
+ dev_WARN(&this_client->adapter->dev,
+ "Missing %s IRQ\n", MPU_NAME);
}
@@ -1264,17 +1281,16 @@ static struct i2c_driver mpu3050_driver = {
static int __init mpu_init(void)
{
int res = i2c_add_driver(&mpu3050_driver);
- pid = 0;
- printk(KERN_DEBUG "%s\n", __func__);
+ pr_debug("%s\n", __func__);
if (res)
- dev_err(&this_client->adapter->dev, "%s failed\n",
+ pr_err("%s failed\n",
__func__);
return res;
}
static void __exit mpu_exit(void)
{
- printk(KERN_DEBUG "%s\n", __func__);
+ pr_debug("%s\n", __func__);
i2c_del_driver(&mpu3050_driver);
}
diff --git a/drivers/misc/mpu3050/mpuirq.c b/drivers/misc/mpu3050/mpuirq.c
index 691e5bc5b052..ce1ad409cbf4 100644
--- a/drivers/misc/mpu3050/mpuirq.c
+++ b/drivers/misc/mpu3050/mpuirq.c
@@ -72,9 +72,6 @@ static int mpuirq_open(struct inode *inode, struct file *file)
"%s current->pid %d\n", __func__, current->pid);
mpuirq_dev_data.pid = current->pid;
file->private_data = &mpuirq_dev_data;
- /* we could do some checking on the flags supplied by "open" */
- /* i.e. O_NONBLOCK */
- /* -> set some flag to disable interruptible_sleep_on in mpuirq_read */
return 0;
}
@@ -92,7 +89,9 @@ static ssize_t mpuirq_read(struct file *file,
int len, err;
struct mpuirq_dev_data *p_mpuirq_dev_data = file->private_data;
- if (!mpuirq_dev_data.data_ready) {
+ if (!mpuirq_dev_data.data_ready &&
+ mpuirq_dev_data.timeout &&
+ (!(file->f_flags & O_NONBLOCK))) {
wait_event_interruptible_timeout(mpuirq_wait,
mpuirq_dev_data.
data_ready,
diff --git a/drivers/misc/mpu3050/mpuirq.h b/drivers/misc/mpu3050/mpuirq.h
index 70a2d35679f0..a71c79c75e8c 100644
--- a/drivers/misc/mpu3050/mpuirq.h
+++ b/drivers/misc/mpu3050/mpuirq.h
@@ -22,15 +22,15 @@
#ifdef __KERNEL__
#include <linux/i2c-dev.h>
+#include <linux/time.h>
+#else
+#include <sys/time.h>
#endif
-#define MPUIRQ_ENABLE_DEBUG (1)
-#define MPUIRQ_GET_INTERRUPT_CNT (2)
-#define MPUIRQ_GET_IRQ_TIME (3)
-#define MPUIRQ_GET_LED_VALUE (4)
-#define MPUIRQ_SET_TIMEOUT (5)
-#define MPUIRQ_SET_ACCEL_INFO (6)
-#define MPUIRQ_SET_FREQUENCY_DIVIDER (7)
+#define MPUIRQ_SET_TIMEOUT _IOW(MPU_IOCTL, 0x40, unsigned long)
+#define MPUIRQ_GET_INTERRUPT_CNT _IOR(MPU_IOCTL, 0x41, unsigned long)
+#define MPUIRQ_GET_IRQ_TIME _IOR(MPU_IOCTL, 0x42, struct timeval)
+#define MPUIRQ_SET_FREQUENCY_DIVIDER _IOW(MPU_IOCTL, 0x43, unsigned long)
#ifdef __KERNEL__
diff --git a/drivers/misc/mpu3050/slaveirq.c b/drivers/misc/mpu3050/slaveirq.c
index 2ee53851e125..a3c7bfec4b4b 100644
--- a/drivers/misc/mpu3050/slaveirq.c
+++ b/drivers/misc/mpu3050/slaveirq.c
@@ -89,7 +89,9 @@ static ssize_t slaveirq_read(struct file *file,
struct slaveirq_dev_data *data =
container_of(file->private_data, struct slaveirq_dev_data, dev);
- if (!data->data_ready) {
+ if (!data->data_ready &&
+ data->timeout &&
+ !(file->f_flags & O_NONBLOCK)) {
wait_event_interruptible_timeout(data->slaveirq_wait,
data->data_ready,
data->timeout);
@@ -112,7 +114,8 @@ static ssize_t slaveirq_read(struct file *file,
return len;
}
-unsigned int slaveirq_poll(struct file *file, struct poll_table_struct *poll)
+static unsigned int slaveirq_poll(struct file *file,
+ struct poll_table_struct *poll)
{
int mask = 0;
struct slaveirq_dev_data *data =
@@ -168,7 +171,6 @@ static irqreturn_t slaveirq_handler(int irq, void *dev_id)
data->data.interruptcount++;
/* wake up (unblock) for reading data from userspace */
- /* and ignore first interrupt generated in module init */
data->data_ready = 1;
do_gettimeofday(&irqtime);
@@ -223,6 +225,8 @@ int slaveirq_init(struct i2c_adapter *slave_adapter,
data->data_ready = 0;
data->timeout = 0;
+ init_waitqueue_head(&data->slaveirq_wait);
+
res = request_irq(data->irq, slaveirq_handler, IRQF_TRIGGER_RISING,
data->dev.name, data);
@@ -241,7 +245,6 @@ int slaveirq_init(struct i2c_adapter *slave_adapter,
goto out_misc_register;
}
- init_waitqueue_head(&data->slaveirq_wait);
return res;
out_misc_register:
diff --git a/drivers/misc/mpu3050/slaveirq.h b/drivers/misc/mpu3050/slaveirq.h
index ca9c7e496dab..b4e1115f1b0a 100644
--- a/drivers/misc/mpu3050/slaveirq.h
+++ b/drivers/misc/mpu3050/slaveirq.h
@@ -27,12 +27,9 @@
#include "mpu.h"
#include "mpuirq.h"
-#define SLAVEIRQ_ENABLE_DEBUG (1)
-#define SLAVEIRQ_GET_INTERRUPT_CNT (2)
-#define SLAVEIRQ_GET_IRQ_TIME (3)
-#define SLAVEIRQ_GET_LED_VALUE (4)
-#define SLAVEIRQ_SET_TIMEOUT (5)
-#define SLAVEIRQ_SET_SLAVE_INFO (6)
+#define SLAVEIRQ_SET_TIMEOUT _IOW(MPU_IOCTL, 0x50, unsigned long)
+#define SLAVEIRQ_GET_INTERRUPT_CNT _IOR(MPU_IOCTL, 0x51, unsigned long)
+#define SLAVEIRQ_GET_IRQ_TIME _IOR(MPU_IOCTL, 0x52, unsigned long)
#ifdef __KERNEL__
diff --git a/drivers/misc/mpu3050/timerirq.c b/drivers/misc/mpu3050/timerirq.c
index 94dd095306a5..41c3ac981016 100644
--- a/drivers/misc/mpu3050/timerirq.c
+++ b/drivers/misc/mpu3050/timerirq.c
@@ -63,9 +63,6 @@ static void timerirq_handler(unsigned long arg)
struct timerirq_data *data = (struct timerirq_data *)arg;
struct timeval irqtime;
- /* dev_info(data->dev->this_device,
- "%s, %ld\n", __func__, (unsigned long)data); */
-
data->data.interruptcount++;
data->data_ready = 1;
@@ -75,6 +72,10 @@ static void timerirq_handler(unsigned long arg)
data->data.irqtime += irqtime.tv_usec;
data->data.data_type |= 1;
+ dev_dbg(data->dev->this_device,
+ "%s, %lld, %ld\n", __func__, data->data.irqtime,
+ (unsigned long)data);
+
wake_up_interruptible(&data->timerirq_wait);
if (data->run)
@@ -159,7 +160,9 @@ static ssize_t timerirq_read(struct file *file,
int len, err;
struct timerirq_data *data = file->private_data;
- if (!data->data_ready) {
+ if (!data->data_ready &&
+ data->timeout &&
+ !(file->f_flags & O_NONBLOCK)) {
wait_event_interruptible_timeout(data->timerirq_wait,
data->data_ready,
data->timeout);
@@ -182,7 +185,8 @@ static ssize_t timerirq_read(struct file *file,
return len;
}
-unsigned int timerirq_poll(struct file *file, struct poll_table_struct *poll)
+static unsigned int timerirq_poll(struct file *file,
+ struct poll_table_struct *poll)
{
int mask = 0;
struct timerirq_data *data = file->private_data;
diff --git a/drivers/misc/mpu3050/timerirq.h b/drivers/misc/mpu3050/timerirq.h
index a38b4907a4d4..ec2c1e29f080 100644
--- a/drivers/misc/mpu3050/timerirq.h
+++ b/drivers/misc/mpu3050/timerirq.h
@@ -20,9 +20,11 @@
#ifndef __TIMERIRQ__
#define __TIMERIRQ__
-#define TIMERIRQ_SET_TIMEOUT (5)
-#define TIMERIRQ_GET_INTERRUPT_CNT (7)
-#define TIMERIRQ_START (8)
-#define TIMERIRQ_STOP (9)
+#include "mpu.h"
+
+#define TIMERIRQ_SET_TIMEOUT _IOW(MPU_IOCTL, 0x60, unsigned long)
+#define TIMERIRQ_GET_INTERRUPT_CNT _IOW(MPU_IOCTL, 0x61, unsigned long)
+#define TIMERIRQ_START _IOW(MPU_IOCTL, 0x62, unsigned long)
+#define TIMERIRQ_STOP _IO(MPU_IOCTL, 0x63)
#endif
diff --git a/include/linux/mpu.h b/include/linux/mpu.h
index 15b5fef07c9a..d66d9e76b9af 100644
--- a/include/linux/mpu.h
+++ b/include/linux/mpu.h
@@ -22,6 +22,9 @@
#ifdef __KERNEL__
#include <linux/types.h>
+#include <linux/ioctl.h>
+#elif defined LINUX
+#include <sys/ioctl.h>
#endif
#ifdef M_HW
@@ -35,72 +38,67 @@
#define ACCEL_NUM_AXES (3)
#define COMPASS_NUM_AXES (3)
+#if defined __KERNEL__ || defined LINUX
+#define MPU_IOCTL (0x81) /* Magic number for MPU Iocts */
/* IOCTL commands for /dev/mpu */
-#define MPU_SET_MPU_CONFIG (0x00)
-#define MPU_SET_INT_CONFIG (0x01)
-#define MPU_SET_EXT_SYNC (0x02)
-#define MPU_SET_FULL_SCALE (0x03)
-#define MPU_SET_LPF (0x04)
-#define MPU_SET_CLK_SRC (0x05)
-#define MPU_SET_DIVIDER (0x06)
-#define MPU_SET_LEVEL_SHIFTER (0x07)
-#define MPU_SET_DMP_ENABLE (0x08)
-#define MPU_SET_FIFO_ENABLE (0x09)
-#define MPU_SET_DMP_CFG1 (0x0a)
-#define MPU_SET_DMP_CFG2 (0x0b)
-#define MPU_SET_OFFSET_TC (0x0c)
-#define MPU_SET_RAM (0x0d)
-
-#define MPU_SET_PLATFORM_DATA (0x0e)
-
-#define MPU_GET_MPU_CONFIG (0x80)
-#define MPU_GET_INT_CONFIG (0x81)
-#define MPU_GET_EXT_SYNC (0x82)
-#define MPU_GET_FULL_SCALE (0x83)
-#define MPU_GET_LPF (0x84)
-#define MPU_GET_CLK_SRC (0x85)
-#define MPU_GET_DIVIDER (0x86)
-#define MPU_GET_LEVEL_SHIFTER (0x87)
-#define MPU_GET_DMP_ENABLE (0x88)
-#define MPU_GET_FIFO_ENABLE (0x89)
-#define MPU_GET_DMP_CFG1 (0x8a)
-#define MPU_GET_DMP_CFG2 (0x8b)
-#define MPU_GET_OFFSET_TC (0x8c)
-#define MPU_GET_RAM (0x8d)
-
-#define MPU_READ_REGISTER (0x40)
-#define MPU_WRITE_REGISTER (0x41)
-#define MPU_READ_MEMORY (0x42)
-#define MPU_WRITE_MEMORY (0x43)
-
-#define MPU_SUSPEND (0x44)
-#define MPU_RESUME (0x45)
-#define MPU_READ_COMPASS (0x46)
-#define MPU_READ_ACCEL (0x47)
-#define MPU_READ_PRESSURE (0x48)
-
-#define MPU_CONFIG_ACCEL (0x20)
-#define MPU_CONFIG_COMPASS (0x21)
-#define MPU_CONFIG_PRESSURE (0x22)
-
-#define MPU_GET_CONFIG_ACCEL (0x28)
-#define MPU_GET_CONFIG_COMPASS (0x29)
-#define MPU_GET_CONFIG_PRESSURE (0x2a)
+#define MPU_SET_MPU_CONFIG _IOW(MPU_IOCTL, 0x00, struct mldl_cfg)
+#define MPU_GET_MPU_CONFIG _IOR(MPU_IOCTL, 0x00, struct mldl_cfg)
+#define MPU_SET_PLATFORM_DATA _IOW(MPU_IOCTL, 0x01, struct mldl_cfg)
+
+#define MPU_READ _IOR(MPU_IOCTL, 0x10, struct mpu_read_write)
+#define MPU_WRITE _IOW(MPU_IOCTL, 0x10, struct mpu_read_write)
+#define MPU_READ_MEM _IOR(MPU_IOCTL, 0x11, struct mpu_read_write)
+#define MPU_WRITE_MEM _IOW(MPU_IOCTL, 0x11, struct mpu_read_write)
+#define MPU_READ_FIFO _IOR(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, unsigned char)
+#define MPU_READ_ACCEL _IOR(MPU_IOCTL, 0x13, unsigned char)
+#define MPU_READ_PRESSURE _IOR(MPU_IOCTL, 0x14, unsigned char)
+
+#define MPU_CONFIG_ACCEL _IOW(MPU_IOCTL, 0x20, struct ext_slave_config)
+#define MPU_CONFIG_COMPASS _IOW(MPU_IOCTL, 0x21, struct ext_slave_config)
+#define MPU_CONFIG_PRESSURE _IOW(MPU_IOCTL, 0x22, struct ext_slave_config)
+
+#define MPU_GET_CONFIG_ACCEL _IOR(MPU_IOCTL, 0x20, struct ext_slave_config)
+#define MPU_GET_CONFIG_COMPASS _IOR(MPU_IOCTL, 0x21, struct ext_slave_config)
+#define MPU_GET_CONFIG_PRESSURE _IOR(MPU_IOCTL, 0x22, struct ext_slave_config)
+
+#define MPU_SUSPEND _IO(MPU_IOCTL, 0x30)
+#define MPU_RESUME _IO(MPU_IOCTL, 0x31)
+/* Userspace PM Event response */
+#define MPU_PM_EVENT_HANDLED _IO(MPU_IOCTL, 0x32)
+
+#endif
/* Structure for the following IOCTL's:
- MPU_SET_RAM
- MPU_GET_RAM
- MPU_READ_REGISTER
- MPU_WRITE_REGISTER
- MPU_READ_MEMORY
- MPU_WRITE_MEMORY
+ MPU_READ
+ MPU_WRITE
+ MPU_READ_MEM
+ MPU_WRITE_MEM
+ MPU_READ_FIFO
+ MPU_WRITE_FIFO
*/
struct mpu_read_write {
+ /* Memory address or register address depending on ioctl */
unsigned short address;
unsigned short length;
unsigned char *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)
+
+#define MAX_MPUIRQ_DATA_SIZE (32)
+
struct mpuirq_data {
int interruptcount;
unsigned long long irqtime;
@@ -108,6 +106,7 @@ struct mpuirq_data {
int data_size;
void *data;
};
+
enum ext_slave_config_key {
MPU_SLAVE_CONFIG_ODR_SUSPEND,
MPU_SLAVE_CONFIG_ODR_RESUME,
@@ -119,6 +118,8 @@ enum ext_slave_config_key {
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_NUM_CONFIG_KEYS,
};
@@ -157,6 +158,7 @@ enum ext_slave_id {
ACCEL_ID_LIS331,
ACCEL_ID_LSM303,
+ ACCEL_ID_LIS3DH,
ACCEL_ID_KXSD9,
ACCEL_ID_KXTF9,
ACCEL_ID_BMA150,
@@ -165,11 +167,12 @@ enum ext_slave_id {
ACCEL_ID_MMA8450,
ACCEL_ID_MMA845X,
ACCEL_ID_MPU6000,
- ACCEL_ID_LIS3DH,
COMPASS_ID_AKM,
COMPASS_ID_AMI30X,
+ COMPASS_ID_AMI306,
COMPASS_ID_YAS529,
+ COMPASS_ID_YAS530,
COMPASS_ID_HMC5883,
COMPASS_ID_LSM303,
COMPASS_ID_MMC314X,
@@ -397,12 +400,18 @@ struct ext_slave_descr *ak8975_get_slave_descr(void);
#define get_compass_slave_descr ak8975_get_slave_descr
#endif
-#ifdef CONFIG_MPU_SENSORS_AMI30X /* AICHI Steel compass */
+#ifdef CONFIG_MPU_SENSORS_AMI30X /* AICHI Steel AMI304/305 compass */
struct ext_slave_descr *ami30x_get_slave_descr(void);
#undef get_compass_slave_descr
#define get_compass_slave_descr ami30x_get_slave_descr
#endif
+#ifdef CONFIG_MPU_SENSORS_AMI306 /* AICHI Steel AMI306 compass */
+struct ext_slave_descr *ami306_get_slave_descr(void);
+#undef get_compass_slave_descr
+#define get_compass_slave_descr ami306_get_slave_descr
+#endif
+
#ifdef CONFIG_MPU_SENSORS_HMC5883 /* Honeywell compass */
struct ext_slave_descr *hmc5883_get_slave_descr(void);
#undef get_compass_slave_descr
@@ -427,6 +436,12 @@ struct ext_slave_descr *yas529_get_slave_descr(void);
#define get_compass_slave_descr yas529_get_slave_descr
#endif
+#ifdef CONFIG_MPU_SENSORS_YAS530 /* Yamaha compass */
+struct ext_slave_descr *yas530_get_slave_descr(void);
+#undef get_compass_slave_descr
+#define get_compass_slave_descr yas530_get_slave_descr
+#endif
+
#ifdef CONFIG_MPU_SENSORS_HSCDTD002B /* Alps HSCDTD002B compass */
struct ext_slave_descr *hscdtd002b_get_slave_descr(void);
#undef get_compass_slave_descr