From: liuji <liuji@rock-chips.com>
Date: Mon, 8 Aug 2011 16:53:25 +0000 (+0800)
Subject: mod/add: add mpu support
X-Git-Tag: firefly_0821_release~9772^2~18^2~23^2~3
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=1495c383330d098039a56fb0aa3f765bd3a21b6e;p=firefly-linux-kernel-4.4.55.git

mod/add: add mpu support
---

diff --git a/arch/arm/mach-rk29/board-rk29-ddr3sdk.c b/arch/arm/mach-rk29/board-rk29-ddr3sdk.c
index 6ffc986a3cdb..f4e883fa9fee 100755
--- a/arch/arm/mach-rk29/board-rk29-ddr3sdk.c
+++ b/arch/arm/mach-rk29/board-rk29-ddr3sdk.c
@@ -497,7 +497,55 @@ static struct mma8452_platform_data mma8452_info = {
 
 };
 #endif
-
+#if defined (CONFIG_MPU_SENSORS_MPU3050)
+/*mpu3050*/
+static struct mpu3050_platform_data mpu3050_data = {
+		.int_config = 0x10,
+		//.orientation = { 1, 0, 0,0, -1, 0,0, 0, 1 },
+		//.orientation = { 0, 1, 0,-1, 0, 0,0, 0, -1 },
+		//.orientation = { -1, 0, 0,0, -1, 0,0, 0, -1 },
+		.orientation = { 0, 1, 0, -1, 0, 0, 0, 0, 1 },
+		.level_shifter = 0,
+#if defined (CONFIG_MPU_SENSORS_KXTF9)
+		.accel = {
+#ifdef CONFIG_MPU_SENSORS_MPU3050_MODULE
+				.get_slave_descr = NULL ,
+#else
+				.get_slave_descr = get_accel_slave_descr ,			
+#endif
+				.adapt_num = 0, // The i2c bus to which the mpu device is
+				// connected
+				//.irq = RK29_PIN0_PA3,
+				.bus = EXT_SLAVE_BUS_SECONDARY,  //The secondary I2C of MPU
+				.address = 0x0f,
+				//.orientation = { 1, 0, 0,0, 1, 0,0, 0, 1 },
+				//.orientation = { 0, -1, 0,-1, 0, 0,0, 0, -1 },
+				//.orientation = { 0, 1, 0,1, 0, 0,0, 0, -1 },
+				.orientation = { 0, 1 ,0, -1 ,0, 0, 0, 0, 1 },
+		},
+#endif
+#if defined (CONFIG_MPU_SENSORS_AK8975)
+		.compass = {
+#ifdef CONFIG_MPU_SENSORS_MPU3050_MODULE
+				.get_slave_descr = NULL,/*ak5883_get_slave_descr,*/
+#else
+				.get_slave_descr = get_compass_slave_descr,
+#endif						
+				.adapt_num = 0, // The i2c bus to which the compass device is. 
+				// It can be difference with mpu
+				// connected
+				//.irq = RK29_PIN0_PA4,
+				.bus = EXT_SLAVE_BUS_PRIMARY,
+				.address = 0x0d,
+				//.orientation = { -1, 0, 0,0, -1, 0,0, 0, 1 },
+				//.orientation = { 0, -1, 0,-1, 0, 0,0, 0, -1 },
+				//.orientation = { 0, 1, 0,1, 0, 0,0, 0, -1 },
+				//.orientation = { 0, -1, 0, 1, 0, 0, 0, 0, 1 },
+				.orientation = { 0, 1, 0, -1, 0, 0, 0, 0, 1 },
+		},
+};
+#endif
+#endif
 #if defined (CONFIG_BATTERY_BQ27510)
 #define	DC_CHECK_PIN	RK29_PIN4_PA1
 #define	LI_LION_BAT_NUM	2
@@ -730,6 +778,15 @@ static struct i2c_board_info __initdata board_i2c0_devices[] = {
 		.irq			= RK29_PIN0_PA4,
 	},
 #endif
+#if defined (CONFIG_MPU_SENSORS_MPU3050) 
+	{
+		.type 			= "mpu3050",
+		.addr			= 0x68,
+		.flags			= 0,
+		.irq			= RK29_PIN5_PA3,
+		.platform_data  = &mpu3050_data,
+	},
+#endif
 };
 #endif
 
diff --git a/arch/arm/mach-rk29/board-rk29sdk.c b/arch/arm/mach-rk29/board-rk29sdk.c
index 9c354ef55c2b..064441f203b5 100755
--- a/arch/arm/mach-rk29/board-rk29sdk.c
+++ b/arch/arm/mach-rk29/board-rk29sdk.c
@@ -502,7 +502,55 @@ static struct mma8452_platform_data mma8452_info = {
 
 };
 #endif
-
+#if defined (CONFIG_MPU_SENSORS_MPU3050)
+/*mpu3050*/
+static struct mpu3050_platform_data mpu3050_data = {
+		.int_config = 0x10,
+		//.orientation = { 1, 0, 0,0, -1, 0,0, 0, 1 },
+		//.orientation = { 0, 1, 0,-1, 0, 0,0, 0, -1 },
+		//.orientation = { -1, 0, 0,0, -1, 0,0, 0, -1 },
+		.orientation = { 0, 1, 0, -1, 0, 0, 0, 0, 1 },
+		.level_shifter = 0,
+#if defined (CONFIG_MPU_SENSORS_KXTF9)
+		.accel = {
+#ifdef CONFIG_MPU_SENSORS_MPU3050_MODULE
+				.get_slave_descr = NULL ,
+#else
+				.get_slave_descr = get_accel_slave_descr ,			
+#endif
+				.adapt_num = 0, // The i2c bus to which the mpu device is
+				// connected
+				//.irq = RK29_PIN0_PA3,
+				.bus = EXT_SLAVE_BUS_SECONDARY,  //The secondary I2C of MPU
+				.address = 0x0f,
+				//.orientation = { 1, 0, 0,0, 1, 0,0, 0, 1 },
+				//.orientation = { 0, -1, 0,-1, 0, 0,0, 0, -1 },
+				//.orientation = { 0, 1, 0,1, 0, 0,0, 0, -1 },
+				.orientation = { 0, 1 ,0, -1 ,0, 0, 0, 0, 1 },
+		},
+#endif
+#if defined (CONFIG_MPU_SENSORS_AK8975)
+		.compass = {
+#ifdef CONFIG_MPU_SENSORS_MPU3050_MODULE
+				.get_slave_descr = NULL,/*ak5883_get_slave_descr,*/
+#else
+				.get_slave_descr = get_compass_slave_descr,
+#endif						
+				.adapt_num = 0, // The i2c bus to which the compass device is. 
+				// It can be difference with mpu
+				// connected
+				//.irq = RK29_PIN0_PA4,
+				.bus = EXT_SLAVE_BUS_PRIMARY,
+				.address = 0x0d,
+				//.orientation = { -1, 0, 0,0, -1, 0,0, 0, 1 },
+				//.orientation = { 0, -1, 0,-1, 0, 0,0, 0, -1 },
+				//.orientation = { 0, 1, 0,1, 0, 0,0, 0, -1 },
+				//.orientation = { 0, -1, 0, 1, 0, 0, 0, 0, 1 },
+				.orientation = { 0, 1, 0, -1, 0, 0, 0, 0, 1 },
+		},
+};
+#endif
+#endif
 #if defined (CONFIG_BATTERY_BQ27510)
 #define	DC_CHECK_PIN	RK29_PIN4_PA1
 #define	LI_LION_BAT_NUM	2
@@ -735,6 +783,16 @@ static struct i2c_board_info __initdata board_i2c0_devices[] = {
 		.irq			= RK29_PIN0_PA4,
 	},
 #endif
+/*mpu3050*/
+#if defined (CONFIG_MPU_SENSORS_MPU3050) 
+	{
+		.type 			= "mpu3050",
+		.addr			= 0x68,
+		.flags			= 0,
+		.irq			= RK29_PIN5_PA3,
+		.platform_data  = &mpu3050_data,
+	},
+#endif
 };
 #endif
 
diff --git a/drivers/misc/mpu3050/Kconfig b/drivers/misc/mpu3050/Kconfig
old mode 100644
new mode 100755
index 69ee20209c38..210953f35095
--- a/drivers/misc/mpu3050/Kconfig
+++ b/drivers/misc/mpu3050/Kconfig
@@ -1,188 +1,213 @@
-
-menu "Motion Sensors Support"
-
-choice
-    tristate "Motion Processing Unit"
-    depends on I2C
-    default MPU_NONE
-
-config MPU_NONE
-    bool "None"
-    help
-      This disables support for motion processing using the MPU family of 
-      motion processing units.
-
-config SENSORS_MPU3050
-    tristate "MPU3050"
-    depends on I2C
-    help
-      If you say yes here you get support for the MPU3050 Gyroscope driver
-      This driver can also be built as a module.  If so, the module
-      will be called mpu3050.
-
-config SENSORS_MPU6000
-    tristate "MPU6000"
-    depends on I2C
-    help
-      If you say yes here you get support for the MPU6000 Gyroscope driver
-      This driver can also be built as a module.  If so, the module
-      will be called mpu6000.
-
-endchoice
-
-choice
-    prompt "Accelerometer Type"
-    depends on SENSORS_MPU3050
-    default SENSORS_BMA150
-
-config SENSORS_ACCELEROMETER_NONE
-    bool "NONE"
-    depends on SENSORS_MPU3050 || SENSORS_MPU6000
-    help
-      This disables accelerometer support for the MPU3050
-
-config SENSORS_ADXL346
-    bool "ADI adxl346"
-    depends on SENSORS_MPU3050
-    help
-      This enables support for the ADI adxl346 accelerometer
-
-config SENSORS_BMA150
-    bool "Bosch BMA150"
-    depends on SENSORS_MPU3050
-    help
-      This enables support for the Bosch BMA150 accelerometer
- 
-config SENSORS_BMA222
-    bool "Bosch BMA222"
-    depends on SENSORS_MPU3050
-    help
-      This enables support for the Bosch BMA222 accelerometer
-      
-config SENSORS_KXSD9
-    bool "Kionix KXSD9"
-    depends on SENSORS_MPU3050
-    help
-      This enables support for the Kionix KXSD9 accelerometer
-
-config SENSORS_KXTF9
-    bool "Kionix KXTF9"
-    depends on SENSORS_MPU3050
-    help
-      This enables support for the Kionix KXFT9 accelerometer
-
-config SENSORS_LIS331DLH
-    bool "ST lis331dlh"
-    depends on SENSORS_MPU3050
-    help
-      This enables support for the ST lis331dlh accelerometer
-
-config SENSORS_LSM303DLHA
-    bool "ST lsm303dlh"
-    depends on SENSORS_MPU3050
-    help
-      This enables support for the ST lsm303dlh accelerometer
-
-config SENSORS_MMA8450
-    bool "Freescale mma8450"
-    depends on SENSORS_MPU3050
-    help
-      This enables support for the Freescale mma8450 accelerometer
-
-config SENSORS_MMA8451
-    bool "Freescale mma8451"
-    depends on SENSORS_MPU3050
-    help
-      This enables support for the Freescale mma8451 accelerometer
-
-endchoice
-
-choice
-    prompt "Compass Type"
-    depends on SENSORS_MPU6000 || SENSORS_MPU3050
-    default SENSORS_AK8975
-
-config SENSORS_COMPASS_NONE
-    bool "NONE"
-    depends on SENSORS_MPU6000 || SENSORS_MPU3050
-    help
-      This disables compass support for the MPU6000
-
-config SENSORS_AK8975
-    bool "AKM ak8975"
-    depends on SENSORS_MPU6000 || SENSORS_MPU3050
-    help
-      This enables support for the AKM ak8975 compass
-
-config SENSORS_MMC314X
-    bool "MEMSIC mmc314x"
-    depends on SENSORS_MPU3050
-    help
-      This enables support for the MEMSIC mmc314x compass
-
-config SENSORS_AMI30X
-    bool "Aichi Steel ami30X"
-    depends on SENSORS_MPU3050
-    help
-      This enables support for the Aichi Steel ami304/ami305 compass
-
-config SENSORS_HMC5883
-    bool "Honeywell hmc5883"
-    depends on SENSORS_MPU3050
-    help
-      This enables support for the Honeywell hmc5883 compass
-
-config SENSORS_LSM303DLHM
-    bool "ST lsm303dlh"
-    depends on SENSORS_MPU3050
-    help
-      This enables support for the ST lsm303dlh compass
-
-config SENSORS_MMC314X
-    bool "MEMSIC mmc314xMS"
-    depends on SENSORS_MPU3050
-    help
-      This enables support for the MEMSIC mmc314xMS compass
-
-config SENSORS_YAS529
-    bool "Yamaha yas529"
-    depends on SENSORS_MPU3050
-    help
-      This enables support for the Yamaha yas529 compass
-
-config SENSORS_HSCDTD00XX
-    bool "Alps hscdtd00XX"
-    depends on SENSORS_MPU3050
-    help
-      This enables support for the Alps hscdtd002b/hscdtd004a compass
-
-endchoice
-
-choice
-    prompt "Pressure Type"
-    depends on SENSORS_MPU6000 || SENSORS_MPU3050
-    default SENSORS_BMA085
-
-config SENSORS_PRESSURE_NONE
-    bool "NONE"
-    depends on SENSORS_MPU6000 || SENSORS_MPU3050
-    help
-      This disables pressure sensor support for the MPU6000
-
-config SENSORS_BMA085
-    bool "Bosch BMA085"
-    depends on SENSORS_MPU6000 || SENSORS_MPU3050
-    help
-      This enables support for the Bosch bma085 pressure sensor
-
-endchoice
-
-config SENSORS_MPU_DEBUG
-    bool "MPU debug"
-    depends on SENSORS_MPU3050 || SENSORS_MPU6000
-    help
-      If you say yes here you get extra debug messages from the MPU3050
-      and other slave sensors.
-
-endmenu
-
+
+menu "Motion Sensors Support"
+
+choice
+    tristate "Motion Processing Unit"
+    depends on I2C
+    default MPU_NONE
+
+config MPU_NONE
+    bool "None"
+    help
+      This disables support for motion processing using the MPU family of 
+      motion processing units.
+
+config MPU_SENSORS_MPU3050
+    tristate "MPU3050"
+    depends on I2C
+    help
+      If you say yes here you get support for the MPU3050 Gyroscope driver
+      This driver can also be built as a module.  If so, the module
+      will be called mpu3050.
+
+config MPU_SENSORS_MPU6000
+    tristate "MPU6000"
+    depends on I2C
+    help
+      If you say yes here you get support for the MPU6000 Gyroscope driver
+      This driver can also be built as a module.  If so, the module
+      will be called mpu6000.
+
+endchoice
+
+choice
+    prompt "Accelerometer Type"
+    depends on MPU_SENSORS_MPU3050
+    default MPU_SENSORS_BMA150
+
+config MPU_SENSORS_ACCELEROMETER_NONE
+    bool "NONE"
+    depends on MPU_SENSORS_MPU3050 || MPU_SENSORS_MPU6000
+    help
+      This disables accelerometer support for the MPU3050
+
+config MPU_SENSORS_ADXL346
+    bool "ADI adxl346"
+    depends on MPU_SENSORS_MPU3050
+    help
+      This enables support for the ADI adxl346 accelerometer
+
+config MPU_SENSORS_BMA150
+    bool "Bosch BMA150"
+    depends on MPU_SENSORS_MPU3050
+    help
+      This enables support for the Bosch BMA150 accelerometer
+ 
+config MPU_SENSORS_BMA222
+    bool "Bosch BMA222"
+    depends on MPU_SENSORS_MPU3050
+    help
+      This enables support for the Bosch BMA222 accelerometer
+      
+config MPU_SENSORS_KXSD9
+    bool "Kionix KXSD9"
+    depends on MPU_SENSORS_MPU3050
+    help
+      This enables support for the Kionix KXSD9 accelerometer
+
+config MPU_SENSORS_KXTF9
+    bool "Kionix KXTF9"
+    depends on MPU_SENSORS_MPU3050
+    help
+      This enables support for the Kionix KXFT9 accelerometer
+
+config MPU_SENSORS_LIS331DLH
+    bool "ST lis331dlh"
+    depends on MPU_SENSORS_MPU3050
+    help
+      This enables support for the ST lis331dlh accelerometer
+
+config MPU_SENSORS_LIS3DH
+    bool "ST lis3dh"
+    depends on MPU_SENSORS_MPU3050
+    help
+      This enables support for the ST lis3dh accelerometer
+
+config MPU_SENSORS_LSM303DLHA
+    bool "ST lsm303dlh"
+    depends on MPU_SENSORS_MPU3050
+    help
+      This enables support for the ST lsm303dlh accelerometer
+
+config MPU_SENSORS_MMA8450
+    bool "Freescale mma8450"
+    depends on MPU_SENSORS_MPU3050
+    help
+      This enables support for the Freescale mma8450 accelerometer
+
+config MPU_SENSORS_MMA845X
+    bool "Freescale mma8451/8452/8453"
+    depends on MPU_SENSORS_MPU3050
+    help
+      This enables support for the Freescale mma8451/8452/8453 accelerometer
+
+endchoice
+
+choice
+    prompt "Compass Type"
+    depends on MPU_SENSORS_MPU6000 || MPU_SENSORS_MPU3050
+    default MPU_SENSORS_AK8975
+
+config MPU_SENSORS_COMPASS_NONE
+    bool "NONE"
+    depends on MPU_SENSORS_MPU6000 || MPU_SENSORS_MPU3050
+    help
+      This disables compass support for the MPU6000
+
+config MPU_SENSORS_AK8975
+    bool "AKM ak8975"
+    depends on MPU_SENSORS_MPU6000 || MPU_SENSORS_MPU3050
+    help
+      This enables support for the AKM ak8975 compass
+
+config MPU_SENSORS_MMC314X
+    bool "MEMSIC mmc314x"
+    depends on MPU_SENSORS_MPU3050
+    help
+      This enables support for the MEMSIC mmc314x compass
+
+config MPU_SENSORS_AMI30X
+    bool "Aichi Steel ami30X"
+    depends on MPU_SENSORS_MPU3050
+    help
+      This enables support for the Aichi Steel ami304/ami305 compass
+
+config MPU_SENSORS_AMI306
+    bool "Aichi Steel ami306"
+    depends on MPU_SENSORS_MPU3050
+    help
+      This enables support for the Aichi Steel ami306 compass
+
+config MPU_SENSORS_HMC5883
+    bool "Honeywell hmc5883"
+    depends on MPU_SENSORS_MPU3050
+    help
+      This enables support for the Honeywell hmc5883 compass
+
+config MPU_SENSORS_LSM303DLHM
+    bool "ST lsm303dlh"
+    depends on MPU_SENSORS_MPU3050
+    help
+      This enables support for the ST lsm303dlh compass
+
+config MPU_SENSORS_MMC314X
+    bool "MEMSIC mmc314xMS"
+    depends on MPU_SENSORS_MPU3050
+    help
+      This enables support for the MEMSIC mmc314xMS compass
+
+config MPU_SENSORS_YAS529
+    bool "Yamaha yas529"
+    depends on MPU_SENSORS_MPU3050
+    help
+      This enables support for the Yamaha yas529 compass
+
+config MPU_SENSORS_YAS530
+    bool "Yamaha yas530"
+    depends on MPU_SENSORS_MPU3050
+    help
+      This enables support for the Yamaha yas530 compass
+
+config MPU_SENSORS_HSCDTD002B
+    bool "Alps hscdtd002b"
+    depends on MPU_SENSORS_MPU3050
+    help
+      This enables support for the Alps hscdtd002b compass
+
+config MPU_SENSORS_HSCDTD004A
+    bool "Alps hscdtd004a"
+    depends on MPU_SENSORS_MPU3050
+    help
+      This enables support for the Alps hscdtd004a compass
+
+endchoice
+
+choice
+    prompt "Pressure Type"
+    depends on MPU_SENSORS_MPU6000 || MPU_SENSORS_MPU3050
+    default MPU_SENSORS_BMA085
+
+config MPU_SENSORS_PRESSURE_NONE
+    bool "NONE"
+    depends on MPU_SENSORS_MPU6000 || MPU_SENSORS_MPU3050
+    help
+      This disables pressure sensor support for the MPU6000
+
+config MPU_SENSORS_BMA085
+    bool "Bosch BMA085"
+    depends on MPU_SENSORS_MPU6000 || MPU_SENSORS_MPU3050
+    help
+      This enables support for the Bosch bma085 pressure sensor
+
+endchoice
+
+config MPU_SENSORS_TIMERIRQ
+    tristate "Timer IRQ"
+    help
+      If you say yes here you get access to the timerirq device handle which
+      can be used to select on.  This can be used instead of IRQ's, sleeping,
+      or timer threads.  Reading from this device returns the same type of
+      information as reading from the MPU and slave IRQ's.
+
+endmenu
+
diff --git a/drivers/misc/mpu3050/Makefile b/drivers/misc/mpu3050/Makefile
old mode 100644
new mode 100755
index 5114e43db83c..935915ad01dc
--- a/drivers/misc/mpu3050/Makefile
+++ b/drivers/misc/mpu3050/Makefile
@@ -1,117 +1,132 @@
-
-# Kernel makefile for motions sensors
-#
-# 
-
-# MPU
-obj-$(CONFIG_SENSORS_MPU3050)	+= mpu3050.o
-mpu3050-objs += mpuirq.o \
-	slaveirq.o \
-	mpu-dev.o \
-	mpu-i2c.o \
-	mlsl-kernel.o \
-	mlos-kernel.o \
-	$(MLLITE_DIR)mldl_cfg.o
-
-#
-# Accel options
-#
-ifdef CONFIG_SENSORS_ADXL346
-mpu3050-objs += $(MLLITE_DIR)accel/adxl346.o
-endif
-
-ifdef CONFIG_SENSORS_BMA150
-mpu3050-objs += $(MLLITE_DIR)accel/bma150.o
-endif
-
-ifdef CONFIG_SENSORS_BMA222
-mpu3050-objs += $(MLLITE_DIR)accel/bma222.o
-endif
-
-ifdef CONFIG_SENSORS_KXSD9
-mpu3050-objs += $(MLLITE_DIR)accel/kxsd9.o
-endif
-
-ifdef CONFIG_SENSORS_KXTF9
-mpu3050-objs += $(MLLITE_DIR)accel/kxtf9.o
-endif
-
-ifdef CONFIG_SENSORS_LIS331DLH
-mpu3050-objs += $(MLLITE_DIR)accel/lis331.o
-endif
-
-ifdef CONFIG_SENSORS_LSM303DLHA
-mpu3050-objs += $(MLLITE_DIR)accel/lsm303a.o
-endif
-
-ifdef CONFIG_SENSORS_MMA8450
-mpu3050-objs += $(MLLITE_DIR)accel/mma8450.o
-endif
-
-ifdef CONFIG_SENSORS_MMA8451
-mpu3050-objs += $(MLLITE_DIR)accel/mma8451.o
-endif
-
-#
-# Compass options
-#
-ifdef CONFIG_SENSORS_AK8975
-mpu3050-objs += $(MLLITE_DIR)compass/ak8975.o
-endif
-
-ifdef CONFIG_SENSORS_AMI30X
-mpu3050-objs += $(MLLITE_DIR)compass/ami30x.o
-endif
-
-ifdef CONFIG_SENSORS_HMC5883
-mpu3050-objs += $(MLLITE_DIR)compass/hmc5883.o
-endif
-
-ifdef CONFIG_SENSORS_LSM303DLHM
-mpu3050-objs += $(MLLITE_DIR)compass/lsm303m.o
-endif
-
-ifdef CONFIG_SENSORS_MMC314X
-mpu3050-objs += $(MLLITE_DIR)compass/mmc314x.o
-endif
-
-ifdef CONFIG_SENSORS_YAS529
-mpu3050-objs += $(MLLITE_DIR)compass/yas529-kernel.o
-endif
-
-ifdef CONFIG_SENSORS_HSCDTD00XX
-mpu3050-objs += $(MLLITE_DIR)compass/hscdtd00xx.o
-endif
-
-#
-# Pressure options
-#
-ifdef CONFIG_SENSORS_BMA085
-mpu3050-objs += $(MLLITE_DIR)pressure/bma085.o
-endif
-
-EXTRA_CFLAGS += -I$(M)/$(MLLITE_DIR) \
-                -I$(M)/../../include \
-		-Idrivers/misc/mpu3050 \
-                -Iinclude/linux
-
-ifdef CONFIG_SENSORS_MPU_DEBUG
-EXTRA_CFLAGS += -DDEBUG 
-endif
-
-obj-$(CONFIG_SENSORS_MPU6000)= mpu6000.o
-mpu6000-objs += mpuirq.o \
-	mpu-dev.o \
-	mpu-i2c.o \
-	mlsl-kernel.o \
-	mlos-kernel.o \
-	$(MLLITE_DIR)mldl_cfg.o \
-	$(MLLITE_DIR)accel/mantis.o
-
-ifdef CONFIG_SENSORS_AK8975
-mpu6000-objs += $(MLLITE_DIR)compass/ak8975.o
-endif
-
-ifdef CONFIG_SENSORS_MPU6000
-EXTRA_CFLAGS += -DM_HW
-endif
+
+# Kernel makefile for motions sensors
+#
+# 
+
+# MPU
+obj-$(CONFIG_MPU_SENSORS_MPU3050)	+= mpu3050.o
+mpu3050-objs += mpuirq.o \
+	slaveirq.o \
+	mpu-dev.o \
+	mpu-i2c.o \
+	mlsl-kernel.o \
+	mlos-kernel.o \
+	$(MLLITE_DIR)mldl_cfg.o
+
+#
+# Accel options
+#
+ifdef CONFIG_MPU_SENSORS_ADXL346
+mpu3050-objs += $(MLLITE_DIR)accel/adxl346.o
+endif
+
+ifdef CONFIG_MPU_SENSORS_BMA150
+mpu3050-objs += $(MLLITE_DIR)accel/bma150.o
+endif
+
+ifdef CONFIG_MPU_SENSORS_BMA222
+mpu3050-objs += $(MLLITE_DIR)accel/bma222.o
+endif
+
+ifdef CONFIG_MPU_SENSORS_KXSD9
+mpu3050-objs += $(MLLITE_DIR)accel/kxsd9.o
+endif
+
+ifdef CONFIG_MPU_SENSORS_KXTF9
+mpu3050-objs += $(MLLITE_DIR)accel/kxtf9.o
+endif
+
+ifdef CONFIG_MPU_SENSORS_LIS331DLH
+mpu3050-objs += $(MLLITE_DIR)accel/lis331.o
+endif
+
+ifdef CONFIG_MPU_SENSORS_LIS3DH
+mpu3050-objs += $(MLLITE_DIR)accel/lis3dh.o
+endif
+
+ifdef CONFIG_MPU_SENSORS_LSM303DLHA
+mpu3050-objs += $(MLLITE_DIR)accel/lsm303a.o
+endif
+
+ifdef CONFIG_MPU_SENSORS_MMA8450
+mpu3050-objs += $(MLLITE_DIR)accel/mma8450.o
+endif
+
+ifdef CONFIG_MPU_SENSORS_MMA845X
+mpu3050-objs += $(MLLITE_DIR)accel/mma845x.o
+endif
+
+#
+# Compass options
+#
+ifdef CONFIG_MPU_SENSORS_AK8975
+mpu3050-objs += $(MLLITE_DIR)compass/ak8975.o
+endif
+
+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
+
+ifdef CONFIG_MPU_SENSORS_LSM303DLHM
+mpu3050-objs += $(MLLITE_DIR)compass/lsm303m.o
+endif
+
+ifdef CONFIG_MPU_SENSORS_MMC314X
+mpu3050-objs += $(MLLITE_DIR)compass/mmc314x.o
+endif
+
+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
+
+ifdef CONFIG_MPU_SENSORS_HSCDTD004A
+mpu3050-objs += $(MLLITE_DIR)compass/hscdtd004a.o
+endif
+#
+# Pressure options
+#
+ifdef CONFIG_MPU_SENSORS_BMA085
+mpu3050-objs += $(MLLITE_DIR)pressure/bma085.o
+endif
+
+EXTRA_CFLAGS += -I$(M)/$(MLLITE_DIR) \
+                -I$(M)/../../include \
+				-Idrivers/misc/mpu3050 \
+                -Iinclude/linux
+
+obj-$(CONFIG_MPU_SENSORS_MPU6000)+= mpu6000.o
+mpu6000-objs += mpuirq.o \
+	slaveirq.o \
+	mpu-dev.o \
+	mpu-i2c.o \
+	mlsl-kernel.o \
+	mlos-kernel.o \
+	$(MLLITE_DIR)mldl_cfg.o \
+	$(MLLITE_DIR)accel/mantis.o
+
+ifdef CONFIG_MPU_SENSORS_AK8975
+mpu6000-objs += $(MLLITE_DIR)compass/ak8975.o
+endif
+
+ifdef CONFIG_MPU_SENSORS_MPU6000
+EXTRA_CFLAGS += -DM_HW
+endif
+
+obj-$(CONFIG_MPU_SENSORS_TIMERIRQ)+= timerirq.o
+
diff --git a/drivers/misc/mpu3050/README b/drivers/misc/mpu3050/README
old mode 100644
new mode 100755
index 2734dc14163e..047b6ba37c1d
--- a/drivers/misc/mpu3050/README
+++ b/drivers/misc/mpu3050/README
@@ -108,7 +108,7 @@ should be modified for your platform.
 
 #include <linux/mpu.h>
 
-#if defined(CONFIG_SENSORS_MPU3050) || defined(CONFIG_SENSORS_MPU3050_MODULE)
+#if defined(CONFIG_MPU_SENSORS_MPU3050) || defined(CONFIG_MPU_SENSORS_MPU3050_MODULE)
 
 #define SENSOR_MPU_NAME "mpu3050"
 
@@ -119,7 +119,7 @@ static struct mpu3050_platform_data mpu_data = {
 			   0,  0, -1 },
 	/* accel */
 	.accel = {
-#ifdef CONFIG_SENSORS_MPU3050_MODULE
+#ifdef CONFIG_MPU_SENSORS_MPU3050_MODULE
 		 .get_slave_descr = NULL,
 #else
 		 .get_slave_descr = get_accel_slave_descr,
@@ -133,7 +133,7 @@ static struct mpu3050_platform_data mpu_data = {
 	 },
 	/* compass */
 	.compass = {
-#ifdef CONFIG_SENSORS_MPU3050_MODULE
+#ifdef CONFIG_MPU_SENSORS_MPU3050_MODULE
 		 .get_slave_descr = NULL,
 #else
 		 .get_slave_descr = get_compass_slave_descr,
@@ -147,7 +147,7 @@ static struct mpu3050_platform_data mpu_data = {
 	 },
 	/* pressure */
 	.pressure = {
-#ifdef CONFIG_SENSORS_MPU3050_MODULE
+#ifdef CONFIG_MPU_SENSORS_MPU3050_MODULE
 		 .get_slave_descr = NULL,
 #else
 		 .get_slave_descr = get_pressure_slave_descr,
@@ -162,7 +162,7 @@ static struct mpu3050_platform_data mpu_data = {
 };
 #endif
 
-#if defined(CONFIG_SENSORS_MPU6000) || defined(CONFIG_SENSORS_MPU6000_MODULE)
+#if defined(CONFIG_MPU_SENSORS_MPU6000) || defined(CONFIG_MPU_SENSORS_MPU6000_MODULE)
 
 #define SENSOR_MPU_NAME "mpu6000"
 
@@ -173,7 +173,7 @@ static struct mpu3050_platform_data mpu_data = {
 			   0,  0, -1 },
 	/* accel */
 	.accel = {
-#ifdef CONFIG_SENSORS_MPU6000_MODULE
+#ifdef CONFIG_MPU_SENSORS_MPU6000_MODULE
 		 .get_slave_descr = NULL,
 #else
 		 .get_slave_descr = get_accel_slave_descr,
@@ -187,7 +187,7 @@ static struct mpu3050_platform_data mpu_data = {
 	 },
 	/* compass */
 	.compass = {
-#ifdef CONFIG_SENSORS_MPU6000_MODULE
+#ifdef CONFIG_MPU_SENSORS_MPU6000_MODULE
 		 .get_slave_descr = NULL,
 #else
 		 .get_slave_descr = get_compass_slave_descr,
@@ -201,7 +201,7 @@ static struct mpu3050_platform_data mpu_data = {
 	 },
 	/* pressure */
 	.pressure = {
-#ifdef CONFIG_SENSORS_MPU6000_MODULE
+#ifdef CONFIG_MPU_SENSORS_MPU6000_MODULE
 		 .get_slave_descr = NULL,
 #else
 		 .get_slave_descr = get_pressure_slave_descr,
@@ -234,6 +234,17 @@ done as well:
     gpio_request(MPU_GPIO_IRQ,"MPUIRQ");
     gpio_direction_input(MPU_GPIO_IRQ)
 
+NOTE:
+=====
+In previous releases, the sensors were defined using CONFIG_SENSORS_SENSORNAME convention. 
+From this release onwards this convention will be changed to CONFIG_MPU_SENSORS_SENSORNAME. 
+Please make note of this change.
+
+Dynamic Debug
+=============
+
+The mpu3050 makes use of dynamic debug.  For details on how to use this
+refer to Documentation/dynamic-debug-howto.txt
 
 Android File Permissions
 ========================
@@ -243,8 +254,17 @@ To set up the file permissions on an android system, the /dev/mpu and
 inside the perms_ structure.
 
 static struct perms_ devperms[] = {
-    { "/dev/mpu"           ,0640,   AID_SYSTEM,    AID_SYSTEM,     1 },
+    { "/dev/mpu"           ,0660,   AID_SYSTEM,    AID_SYSTEM,     1 },
 };
 
 Sufficient file permissions need to be give to read and write it by the system.
 
+For gingerbread and later the system/core/rootdir/ueventd.rc file needs to be
+modified with the appripriate lines added.
+
+# MPU sensors and IRQ
+/dev/mpu                  0660   system     system
+/dev/mpuirq               0660   system     system
+/dev/accelirq             0660   system     system
+/dev/compassirq           0660   system     system
+/dev/pressureirq          0660   system     system
diff --git a/drivers/misc/mpu3050/accel/adxl346.c b/drivers/misc/mpu3050/accel/adxl346.c
old mode 100644
new mode 100755
index 2f76313208ec..14cb38a829ee
--- a/drivers/misc/mpu3050/accel/adxl346.c
+++ b/drivers/misc/mpu3050/accel/adxl346.c
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
 
 /**
@@ -116,7 +129,10 @@ int adxl346_read(void *mlsl_handle,
 		 struct ext_slave_platform_data *pdata,
 		 unsigned char *data)
 {
-	return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
+	int result;
+	result = MLSLSerialRead(mlsl_handle, pdata->address,
+				slave->reg, slave->len, data);
+	return result;
 }
 
 struct ext_slave_descr adxl346_descr = {
@@ -126,6 +142,7 @@ struct ext_slave_descr adxl346_descr = {
 	/*.resume           = */ adxl346_resume,
 	/*.read             = */ adxl346_read,
 	/*.config           = */ NULL,
+	/*.get_config       = */ NULL,
 	/*.name             = */ "adx1346",
 	/*.type             = */ EXT_SLAVE_TYPE_ACCELEROMETER,
 	/*.id               = */ ACCEL_ID_ADI346,
diff --git a/drivers/misc/mpu3050/accel/bma150.c b/drivers/misc/mpu3050/accel/bma150.c
old mode 100644
new mode 100755
index f5e99d1b6d63..30fed1564850
--- a/drivers/misc/mpu3050/accel/bma150.c
+++ b/drivers/misc/mpu3050/accel/bma150.c
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
 
 /**
@@ -61,7 +74,7 @@ static int bma150_resume(void *mlsl_handle,
 	result =
 	    MLSLSerialWriteSingle(mlsl_handle, pdata->address, 0x0a, 0x02);
 	ERROR_CHECK(result);
-	MLOSSleep(10);
+	MLOSSleep(3);
 
 	result =
 	    MLSLSerialRead(mlsl_handle, pdata->address, 0x14, 1, &reg);
@@ -95,7 +108,10 @@ static int bma150_read(void *mlsl_handle,
 		       struct ext_slave_platform_data *pdata,
 		       unsigned char *data)
 {
-	return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
+	int result;
+	result = MLSLSerialRead(mlsl_handle, pdata->address,
+				slave->reg, slave->len, data);
+	return result;
 }
 
 static struct ext_slave_descr bma150_descr = {
@@ -105,6 +121,7 @@ static struct ext_slave_descr bma150_descr = {
 	/*.resume           = */ bma150_resume,
 	/*.read             = */ bma150_read,
 	/*.config           = */ NULL,
+	/*.get_config       = */ NULL,
 	/*.name             = */ "bma150",
 	/*.type             = */ EXT_SLAVE_TYPE_ACCELEROMETER,
 	/*.id               = */ ACCEL_ID_BMA150,
diff --git a/drivers/misc/mpu3050/accel/bma222.c b/drivers/misc/mpu3050/accel/bma222.c
old mode 100644
new mode 100755
index bd0c87ccd8cd..534a1e5fa64b
--- a/drivers/misc/mpu3050/accel/bma222.c
+++ b/drivers/misc/mpu3050/accel/bma222.c
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
 
 /*
@@ -95,7 +108,10 @@ static int bma222_read(void *mlsl_handle,
 		       struct ext_slave_platform_data *pdata,
 		       unsigned char *data)
 {
-	return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
+	int result;
+	result = MLSLSerialRead(mlsl_handle, pdata->address,
+				slave->reg, slave->len, data);
+	return result;
 }
 
 static struct ext_slave_descr bma222_descr = {
@@ -105,6 +121,7 @@ static struct ext_slave_descr bma222_descr = {
 	/*.resume           = */ bma222_resume,
 	/*.read             = */ bma222_read,
 	/*.config           = */ NULL,
+	/*.get_config       = */ NULL,
 	/*.name             = */ "bma222",
 	/*.type             = */ EXT_SLAVE_TYPE_ACCELEROMETER,
 	/*.id               = */ ACCEL_ID_BMA222,
diff --git a/drivers/misc/mpu3050/accel/cma3000.c b/drivers/misc/mpu3050/accel/cma3000.c
old mode 100644
new mode 100755
index 8c6b3c8245b8..05925951c628
--- a/drivers/misc/mpu3050/accel/cma3000.c
+++ b/drivers/misc/mpu3050/accel/cma3000.c
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
 
 /**
@@ -65,7 +78,10 @@ int cma3000_read(void *mlsl_handle,
 		 struct ext_slave_platform_data *pdata,
 		 unsigned char *data)
 {
-	return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
+	int result;
+	result = MLSLSerialRead(mlsl_handle, pdata->address,
+				slave->reg, slave->len, data);
+	return result;
 }
 
 struct ext_slave_descr cma3000_descr = {
diff --git a/drivers/misc/mpu3050/accel/kxsd9.c b/drivers/misc/mpu3050/accel/kxsd9.c
old mode 100644
new mode 100755
index 10ed3b2ac6db..77bc52c8e586
--- a/drivers/misc/mpu3050/accel/kxsd9.c
+++ b/drivers/misc/mpu3050/accel/kxsd9.c
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
 
 /**
@@ -44,7 +57,6 @@ static int kxsd9_suspend(void *mlsl_handle,
 			 struct ext_slave_platform_data *pdata)
 {
 	int result;
-	(void *) slave;
 	/* CTRL_REGB: low-power standby mode */
 	result =
 	    MLSLSerialWriteSingle(mlsl_handle, pdata->address, 0x0d, 0x0);
@@ -99,7 +111,10 @@ static int kxsd9_read(void *mlsl_handle,
 		      struct ext_slave_platform_data *pdata,
 		      unsigned char *data)
 {
-	return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
+	int result;
+	result = MLSLSerialRead(mlsl_handle, pdata->address,
+				slave->reg, slave->len, data);
+	return result;
 }
 
 static struct ext_slave_descr kxsd9_descr = {
@@ -109,6 +124,7 @@ static struct ext_slave_descr kxsd9_descr = {
 	/*.resume           = */ kxsd9_resume,
 	/*.read             = */ kxsd9_read,
 	/*.config           = */ NULL,
+	/*.get_config       = */ NULL,
 	/*.name             = */ "kxsd9",
 	/*.type             = */ EXT_SLAVE_TYPE_ACCELEROMETER,
 	/*.id               = */ ACCEL_ID_KXSD9,
diff --git a/drivers/misc/mpu3050/accel/kxtf9.c b/drivers/misc/mpu3050/accel/kxtf9.c
old mode 100644
new mode 100755
index 9eae342d029f..e2490af1ca77
--- a/drivers/misc/mpu3050/accel/kxtf9.c
+++ b/drivers/misc/mpu3050/accel/kxtf9.c
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
 
 /**
@@ -18,6 +31,9 @@
 /* - Include Files. - */
 /* ------------------ */
 
+#undef MPL_LOG_NDEBUG
+#define MPL_LOG_NDEBUG 1
+
 #ifdef __KERNEL__
 #include <linux/module.h>
 #endif
@@ -30,22 +46,322 @@
 #undef MPL_LOG_TAG
 #define MPL_LOG_TAG "MPL-acc"
 
+#define KXTF9_XOUT_HPF_L                (0x00) /* 0000 0000 */
+#define KXTF9_XOUT_HPF_H                (0x01) /* 0000 0001 */
+#define KXTF9_YOUT_HPF_L                (0x02) /* 0000 0010 */
+#define KXTF9_YOUT_HPF_H                (0x03) /* 0000 0011 */
+#define KXTF9_ZOUT_HPF_L                (0x04) /* 0001 0100 */
+#define KXTF9_ZOUT_HPF_H                (0x05) /* 0001 0101 */
+#define KXTF9_XOUT_L                    (0x06) /* 0000 0110 */
+#define KXTF9_XOUT_H                    (0x07) /* 0000 0111 */
+#define KXTF9_YOUT_L                    (0x08) /* 0000 1000 */
+#define KXTF9_YOUT_H                    (0x09) /* 0000 1001 */
+#define KXTF9_ZOUT_L                    (0x0A) /* 0001 1010 */
+#define KXTF9_ZOUT_H                    (0x0B) /* 0001 1011 */
+#define KXTF9_ST_RESP                   (0x0C) /* 0000 1100 */
+#define KXTF9_WHO_AM_I                  (0x0F) /* 0000 1111 */
+#define KXTF9_TILT_POS_CUR              (0x10) /* 0001 0000 */
+#define KXTF9_TILT_POS_PRE              (0x11) /* 0001 0001 */
+#define KXTF9_INT_SRC_REG1              (0x15) /* 0001 0101 */
+#define KXTF9_INT_SRC_REG2              (0x16) /* 0001 0110 */
+#define KXTF9_STATUS_REG                (0x18) /* 0001 1000 */
+#define KXTF9_INT_REL                   (0x1A) /* 0001 1010 */
+#define KXTF9_CTRL_REG1                 (0x1B) /* 0001 1011 */
+#define KXTF9_CTRL_REG2                 (0x1C) /* 0001 1100 */
+#define KXTF9_CTRL_REG3                 (0x1D) /* 0001 1101 */
+#define KXTF9_INT_CTRL_REG1             (0x1E) /* 0001 1110 */
+#define KXTF9_INT_CTRL_REG2             (0x1F) /* 0001 1111 */
+#define KXTF9_INT_CTRL_REG3             (0x20) /* 0010 0000 */
+#define KXTF9_DATA_CTRL_REG             (0x21) /* 0010 0001 */
+#define KXTF9_TILT_TIMER                (0x28) /* 0010 1000 */
+#define KXTF9_WUF_TIMER                 (0x29) /* 0010 1001 */
+#define KXTF9_TDT_TIMER                 (0x2B) /* 0010 1011 */
+#define KXTF9_TDT_H_THRESH              (0x2C) /* 0010 1100 */
+#define KXTF9_TDT_L_THRESH              (0x2D) /* 0010 1101 */
+#define KXTF9_TDT_TAP_TIMER             (0x2E) /* 0010 1110 */
+#define KXTF9_TDT_TOTAL_TIMER           (0x2F) /* 0010 1111 */
+#define KXTF9_TDT_LATENCY_TIMER         (0x30) /* 0011 0000 */
+#define KXTF9_TDT_WINDOW_TIMER          (0x31) /* 0011 0001 */
+#define KXTF9_WUF_THRESH                (0x5A) /* 0101 1010 */
+#define KXTF9_TILT_ANGLE                (0x5C) /* 0101 1100 */
+#define KXTF9_HYST_SET                  (0x5F) /* 0101 1111 */
+
+#define KXTF9_MAX_DUR (0xFF)
+#define KXTF9_MAX_THS (0xFF)
+#define KXTF9_THS_COUNTS_P_G (32)
+
 /* --------------------- */
 /* -    Variables.     - */
 /* --------------------- */
 
+struct kxtf9_config {
+	unsigned int odr; /* Output data rate mHz */
+	unsigned int fsr; /* full scale range mg */
+	unsigned int ths; /* Motion no-motion thseshold mg */
+	unsigned int dur; /* Motion no-motion duration ms */
+	unsigned int irq_type;
+	unsigned char reg_ths;
+	unsigned char reg_dur;
+	unsigned char reg_odr;
+	unsigned char reg_int_cfg1;
+	unsigned char reg_int_cfg2;
+	unsigned char ctrl_reg1;
+};
+
+struct kxtf9_private_data {
+	struct kxtf9_config suspend;
+	struct kxtf9_config resume;
+};
+
 /*****************************************
     Accelerometer Initialization Functions
 *****************************************/
 
+static int kxtf9_set_ths(void *mlsl_handle,
+			struct ext_slave_platform_data *pdata,
+			struct kxtf9_config *config,
+			int apply,
+			long ths)
+{
+	int result = ML_SUCCESS;
+	if ((ths * KXTF9_THS_COUNTS_P_G / 1000) > KXTF9_MAX_THS)
+		ths = (KXTF9_MAX_THS * 1000) / KXTF9_THS_COUNTS_P_G;
+
+	if (ths < 0)
+		ths = 0;
+
+	config->ths = ths;
+	config->reg_ths = (unsigned char)
+		((long)(ths * KXTF9_THS_COUNTS_P_G) / 1000);
+	MPL_LOGV("THS: %d, 0x%02x\n", config->ths, (int)config->reg_ths);
+	if (apply)
+		result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					KXTF9_WUF_THRESH,
+					config->reg_ths);
+	return result;
+}
+
+static int kxtf9_set_dur(void *mlsl_handle,
+			struct ext_slave_platform_data *pdata,
+			struct kxtf9_config *config,
+			int apply,
+			long dur)
+{
+	int result = ML_SUCCESS;
+	long reg_dur = (dur * config->odr) / 1000000;
+	config->dur = dur;
+
+	if (reg_dur > KXTF9_MAX_DUR)
+		reg_dur = KXTF9_MAX_DUR;
+
+	config->reg_dur = (unsigned char) reg_dur;
+	MPL_LOGV("DUR: %d, 0x%02x\n", config->dur, (int)config->reg_dur);
+	if (apply)
+		result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					KXTF9_WUF_TIMER,
+					(unsigned char)reg_dur);
+	return result;
+}
+
+/**
+ * Sets the IRQ to fire when one of the IRQ events occur.  Threshold and
+ * duration will not be used uless the type is MOT or NMOT.
+ *
+ * @param config configuration to apply to, suspend or resume
+ * @param irq_type The type of IRQ.  Valid values are
+ * - MPU_SLAVE_IRQ_TYPE_NONE
+ * - MPU_SLAVE_IRQ_TYPE_MOTION
+ * - MPU_SLAVE_IRQ_TYPE_DATA_READY
+ */
+static int kxtf9_set_irq(void *mlsl_handle,
+			struct ext_slave_platform_data *pdata,
+			struct kxtf9_config *config,
+			int apply,
+			long irq_type)
+{
+	int result = ML_SUCCESS;
+	struct kxtf9_private_data *private_data = pdata->private_data;
+
+	config->irq_type = (unsigned char)irq_type;
+	config->ctrl_reg1 &= ~0x22;
+	if (irq_type == MPU_SLAVE_IRQ_TYPE_DATA_READY) {
+		config->ctrl_reg1 |= 0x20;
+		config->reg_int_cfg1 = 0x38;
+		config->reg_int_cfg2 = 0x00;
+	} else if (irq_type == MPU_SLAVE_IRQ_TYPE_MOTION) {
+		config->ctrl_reg1 |= 0x02;
+		if ((unsigned long) config ==
+			(unsigned long) &private_data->suspend)
+			config->reg_int_cfg1 = 0x34;
+		else
+			config->reg_int_cfg1 = 0x24;
+		config->reg_int_cfg2 = 0xE0;
+	} else {
+		config->reg_int_cfg1 = 0x00;
+		config->reg_int_cfg2 = 0x00;
+	}
+
+	if (apply) {
+		/* Must clear bit 7 before writing new configuration */
+		result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					KXTF9_CTRL_REG1, 0x40);
+		result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					KXTF9_INT_CTRL_REG1,
+					config->reg_int_cfg1);
+		result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					KXTF9_INT_CTRL_REG2,
+					config->reg_int_cfg2);
+		result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					KXTF9_CTRL_REG1,
+					config->ctrl_reg1);
+	}
+	MPL_LOGV("CTRL_REG1: %lx, INT_CFG1: %lx, INT_CFG2: %lx\n",
+		(unsigned long)config->ctrl_reg1,
+		(unsigned long)config->reg_int_cfg1,
+		(unsigned long)config->reg_int_cfg2);
+
+	return result;
+}
+
+/**
+ * Set the Output data rate for the particular configuration
+ *
+ * @param config Config to modify with new ODR
+ * @param odr Output data rate in units of 1/1000Hz
+ */
+static int kxtf9_set_odr(void *mlsl_handle,
+			struct ext_slave_platform_data *pdata,
+			struct kxtf9_config *config,
+			int apply,
+			long odr)
+{
+	unsigned char bits;
+	int result = ML_SUCCESS;
+
+	/* Data sheet says there is 12.5 hz, but that seems to produce a single
+	 * correct data value, thus we remove it from the table */
+	if (odr > 400000) {
+		config->odr = 800000;
+		bits = 0x06;
+	} else if (odr > 200000) {
+		config->odr = 400000;
+		bits = 0x05;
+	} else if (odr > 100000) {
+		config->odr = 200000;
+		bits = 0x04;
+	} else if (odr > 50000) {
+		config->odr = 100000;
+		bits = 0x03;
+	} else if (odr > 25000) {
+		config->odr = 50000;
+		bits = 0x02;
+	} else if (odr != 0) {
+		config->odr = 25000;
+		bits = 0x01;
+	} else {
+		config->odr = 0;
+		bits = 0;
+	}
+
+	if (odr != 0)
+		config->ctrl_reg1 |= 0x80;
+
+	config->reg_odr = bits;
+	kxtf9_set_dur(mlsl_handle, pdata,
+		config, apply, config->dur);
+	MPL_LOGV("ODR: %d, 0x%02x\n", config->odr, (int)config->ctrl_reg1);
+	if (apply) {
+		result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					KXTF9_DATA_CTRL_REG,
+					config->reg_odr);
+		result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					KXTF9_CTRL_REG1,
+					0x40);
+		result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					KXTF9_CTRL_REG1,
+					config->ctrl_reg1);
+	}
+	return result;
+}
+
+/**
+ * Set the full scale range of the accels
+ *
+ * @param config pointer to configuration
+ * @param fsr requested full scale range
+ */
+static int kxtf9_set_fsr(void *mlsl_handle,
+			struct ext_slave_platform_data *pdata,
+			struct kxtf9_config *config,
+			int apply,
+			long fsr)
+{
+	int result = ML_SUCCESS;
+
+	config->ctrl_reg1 = (config->ctrl_reg1 & 0xE7);
+	if (fsr <= 2000) {
+		config->fsr = 2000;
+		config->ctrl_reg1 |= 0x00;
+	} else if (fsr <= 4000) {
+		config->fsr = 4000;
+		config->ctrl_reg1 |= 0x08;
+	} else {
+		config->fsr = 8000;
+		config->ctrl_reg1 |= 0x10;
+	}
+
+	MPL_LOGV("FSR: %d\n", config->fsr);
+	if (apply) {
+		/* Must clear bit 7 before writing new configuration */
+		result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					KXTF9_CTRL_REG1, 0x40);
+		result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					KXTF9_CTRL_REG1, config->ctrl_reg1);
+	}
+	return result;
+}
+
 static int kxtf9_suspend(void *mlsl_handle,
 			 struct ext_slave_descr *slave,
 			 struct ext_slave_platform_data *pdata)
 {
 	int result;
-	result =
-	    MLSLSerialWriteSingle(mlsl_handle, pdata->address, 0x1b, 0);
+	unsigned char data;
+	struct kxtf9_private_data *private_data = pdata->private_data;
+
+	/* Wake up */
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				KXTF9_CTRL_REG1, 0x40);
+	ERROR_CHECK(result);
+	/* INT_CTRL_REG1: */
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				KXTF9_INT_CTRL_REG1,
+				private_data->suspend.reg_int_cfg1);
+	ERROR_CHECK(result);
+	/* WUF_THRESH: */
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				KXTF9_WUF_THRESH,
+				private_data->suspend.reg_ths);
 	ERROR_CHECK(result);
+	/* DATA_CTRL_REG */
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				KXTF9_DATA_CTRL_REG,
+				private_data->suspend.reg_odr);
+	ERROR_CHECK(result);
+	/* WUF_TIMER */
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				KXTF9_WUF_TIMER, private_data->suspend.reg_dur);
+	ERROR_CHECK(result);
+
+	/* Normal operation  */
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				KXTF9_CTRL_REG1,
+				private_data->suspend.ctrl_reg1);
+	ERROR_CHECK(result);
+	result = MLSLSerialRead(mlsl_handle, pdata->address,
+				KXTF9_INT_REL, 1, &data);
+	ERROR_CHECK(result);
+
 	return result;
 }
 
@@ -58,53 +374,245 @@ static int kxtf9_resume(void *mlsl_handle,
 			struct ext_slave_platform_data *pdata)
 {
 	int result = ML_SUCCESS;
-	unsigned char reg;
+	unsigned char data;
+	struct kxtf9_private_data *private_data = pdata->private_data;
 
-	/* RAM reset */
-	result =
-	    MLSLSerialWriteSingle(mlsl_handle, pdata->address, 0x1d, 0xcd);
-	ERROR_CHECK(result);
-	MLOSSleep(10);
 	/* Wake up */
-	result =
-	    MLSLSerialWriteSingle(mlsl_handle, pdata->address, 0x1b, 0x42);
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				KXTF9_CTRL_REG1, 0x40);
 	ERROR_CHECK(result);
 	/* INT_CTRL_REG1: */
-	result =
-	    MLSLSerialWriteSingle(mlsl_handle, pdata->address, 0x1e, 0x14);
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				KXTF9_INT_CTRL_REG1,
+				private_data->resume.reg_int_cfg1);
 	ERROR_CHECK(result);
 	/* WUF_THRESH: */
-	result =
-	    MLSLSerialWriteSingle(mlsl_handle, pdata->address, 0x5a, 0x00);
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				KXTF9_WUF_THRESH, private_data->resume.reg_ths);
 	ERROR_CHECK(result);
 	/* DATA_CTRL_REG */
-	result =
-	    MLSLSerialWriteSingle(mlsl_handle, pdata->address, 0x21, 0x04);
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				KXTF9_DATA_CTRL_REG,
+				private_data->resume.reg_odr);
 	ERROR_CHECK(result);
 	/* WUF_TIMER */
-	result =
-	    MLSLSerialWriteSingle(mlsl_handle, pdata->address, 0x29, 0x02);
-	ERROR_CHECK(result);
-
-	/* Full Scale */
-	reg = 0xc2;
-	reg &= ~ACCEL_KIONIX_CTRL_MASK;
-	reg |= 0x00;
-	if (slave->range.mantissa == 4)
-		reg |= 0x08;
-	else if (slave->range.mantissa == 8)
-		reg |= 0x10;
-	else {
-		slave->range.mantissa = 2;
-		reg |= 0x00;
-	}
-	slave->range.fraction = 0;
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				KXTF9_WUF_TIMER, private_data->resume.reg_dur);
+	ERROR_CHECK(result);
 
 	/* Normal operation  */
-	result =
-	    MLSLSerialWriteSingle(mlsl_handle, pdata->address, 0x1b, reg);
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				KXTF9_CTRL_REG1,
+				private_data->resume.ctrl_reg1);
+	ERROR_CHECK(result);
+	result = MLSLSerialRead(mlsl_handle, pdata->address,
+				KXTF9_INT_REL, 1, &data);
 	ERROR_CHECK(result);
-	MLOSSleep(50);
+
+	return ML_SUCCESS;
+}
+
+static int kxtf9_init(void *mlsl_handle,
+		struct ext_slave_descr *slave,
+		struct ext_slave_platform_data *pdata)
+{
+
+	struct kxtf9_private_data *private_data;
+	int result = ML_SUCCESS;
+
+	private_data = (struct kxtf9_private_data *)
+		MLOSMalloc(sizeof(struct kxtf9_private_data));
+
+	if (!private_data)
+		return ML_ERROR_MEMORY_EXAUSTED;
+
+	/* RAM reset */
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				KXTF9_CTRL_REG1,
+				0x40); /* Fastest Reset */
+	ERROR_CHECK(result);
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				KXTF9_DATA_CTRL_REG,
+				0x36); /* Fastest Reset */
+	ERROR_CHECK(result);
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				KXTF9_CTRL_REG3, 0xcd); /* Reset */
+	ERROR_CHECK(result);
+	MLOSSleep(2);
+
+	pdata->private_data = private_data;
+
+	private_data->resume.ctrl_reg1 = 0xC0;
+	private_data->suspend.ctrl_reg1 = 0x40;
+
+	result = kxtf9_set_dur(mlsl_handle, pdata, &private_data->suspend,
+			FALSE, 1000);
+	ERROR_CHECK(result);
+	result = kxtf9_set_dur(mlsl_handle, pdata, &private_data->resume,
+			FALSE,  2540);
+	ERROR_CHECK(result);
+
+	result = kxtf9_set_odr(mlsl_handle, pdata, &private_data->suspend,
+			FALSE, 50000);
+	ERROR_CHECK(result);
+	result = kxtf9_set_odr(mlsl_handle, pdata, &private_data->resume,
+			FALSE, 200000);
+
+	result = kxtf9_set_fsr(mlsl_handle, pdata, &private_data->suspend,
+			FALSE, 2000);
+	ERROR_CHECK(result);
+	result = kxtf9_set_fsr(mlsl_handle, pdata, &private_data->resume,
+			FALSE, 2000);
+	ERROR_CHECK(result);
+
+	result = kxtf9_set_ths(mlsl_handle, pdata, &private_data->suspend,
+			FALSE, 80);
+	ERROR_CHECK(result);
+	result = kxtf9_set_ths(mlsl_handle, pdata, &private_data->resume,
+			FALSE, 40);
+	ERROR_CHECK(result);
+
+	result = kxtf9_set_irq(mlsl_handle, pdata, &private_data->suspend,
+			FALSE,
+			MPU_SLAVE_IRQ_TYPE_NONE);
+	ERROR_CHECK(result);
+	result = kxtf9_set_irq(mlsl_handle, pdata, &private_data->resume,
+			FALSE,
+			MPU_SLAVE_IRQ_TYPE_NONE);
+	ERROR_CHECK(result);
+	return result;
+}
+
+static int kxtf9_exit(void *mlsl_handle,
+			  struct ext_slave_descr *slave,
+			  struct ext_slave_platform_data *pdata)
+{
+	if (pdata->private_data)
+		return MLOSFree(pdata->private_data);
+	else
+		return ML_SUCCESS;
+}
+
+static int kxtf9_config(void *mlsl_handle,
+			struct ext_slave_descr *slave,
+			struct ext_slave_platform_data *pdata,
+			struct ext_slave_config *data)
+{
+	struct kxtf9_private_data *private_data = pdata->private_data;
+	if (!data->data)
+		return ML_ERROR_INVALID_PARAMETER;
+
+	switch (data->key) {
+	case MPU_SLAVE_CONFIG_ODR_SUSPEND:
+		return kxtf9_set_odr(mlsl_handle, pdata,
+					&private_data->suspend,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_ODR_RESUME:
+		return kxtf9_set_odr(mlsl_handle, pdata,
+					&private_data->resume,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_FSR_SUSPEND:
+		return kxtf9_set_fsr(mlsl_handle, pdata,
+					&private_data->suspend,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_FSR_RESUME:
+		return kxtf9_set_fsr(mlsl_handle, pdata,
+					&private_data->resume,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_MOT_THS:
+		return kxtf9_set_ths(mlsl_handle, pdata,
+					&private_data->suspend,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_NMOT_THS:
+		return kxtf9_set_ths(mlsl_handle, pdata,
+					&private_data->resume,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_MOT_DUR:
+		return kxtf9_set_dur(mlsl_handle, pdata,
+					&private_data->suspend,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_NMOT_DUR:
+		return kxtf9_set_dur(mlsl_handle, pdata,
+					&private_data->resume,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_IRQ_SUSPEND:
+		return kxtf9_set_irq(mlsl_handle, pdata,
+					&private_data->suspend,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_IRQ_RESUME:
+		return kxtf9_set_irq(mlsl_handle, pdata,
+					&private_data->resume,
+					data->apply,
+					*((long *)data->data));
+	default:
+		return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
+	};
+
+	return ML_SUCCESS;
+}
+
+static int kxtf9_get_config(void *mlsl_handle,
+				struct ext_slave_descr *slave,
+				struct ext_slave_platform_data *pdata,
+				struct ext_slave_config *data)
+{
+	struct kxtf9_private_data *private_data = pdata->private_data;
+	if (!data->data)
+		return ML_ERROR_INVALID_PARAMETER;
+
+	switch (data->key) {
+	case MPU_SLAVE_CONFIG_ODR_SUSPEND:
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->suspend.odr;
+		break;
+	case MPU_SLAVE_CONFIG_ODR_RESUME:
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->resume.odr;
+		break;
+	case MPU_SLAVE_CONFIG_FSR_SUSPEND:
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->suspend.fsr;
+		break;
+	case MPU_SLAVE_CONFIG_FSR_RESUME:
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->resume.fsr;
+		break;
+	case MPU_SLAVE_CONFIG_MOT_THS:
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->suspend.ths;
+		break;
+	case MPU_SLAVE_CONFIG_NMOT_THS:
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->resume.ths;
+		break;
+	case MPU_SLAVE_CONFIG_MOT_DUR:
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->suspend.dur;
+		break;
+	case MPU_SLAVE_CONFIG_NMOT_DUR:
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->resume.dur;
+		break;
+	case MPU_SLAVE_CONFIG_IRQ_SUSPEND:
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->suspend.irq_type;
+		break;
+	case MPU_SLAVE_CONFIG_IRQ_RESUME:
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->resume.irq_type;
+		break;
+	default:
+		return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
+	};
 
 	return ML_SUCCESS;
 }
@@ -114,16 +622,29 @@ static int kxtf9_read(void *mlsl_handle,
 		      struct ext_slave_platform_data *pdata,
 		      unsigned char *data)
 {
-	return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
+	int result;
+	unsigned char reg;
+	result = MLSLSerialRead(mlsl_handle, pdata->address,
+				KXTF9_INT_SRC_REG2, 1, &reg);
+	ERROR_CHECK(result);
+
+	if (!(reg & 0x10))
+		return ML_ERROR_ACCEL_DATA_NOT_READY;
+
+	result = MLSLSerialRead(mlsl_handle, pdata->address,
+				slave->reg, slave->len, data);
+	ERROR_CHECK(result);
+	return result;
 }
 
 static struct ext_slave_descr kxtf9_descr = {
-	/*.init             = */ NULL,
-	/*.exit             = */ NULL,
+	/*.init             = */ kxtf9_init,
+	/*.exit             = */ kxtf9_exit,
 	/*.suspend          = */ kxtf9_suspend,
 	/*.resume           = */ kxtf9_resume,
 	/*.read             = */ kxtf9_read,
-	/*.config           = */ NULL,
+	/*.config           = */ kxtf9_config,
+	/*.get_config       = */ kxtf9_get_config,
 	/*.name             = */ "kxtf9",
 	/*.type             = */ EXT_SLAVE_TYPE_ACCELEROMETER,
 	/*.id               = */ ACCEL_ID_KXTF9,
diff --git a/drivers/misc/mpu3050/accel/lis331.c b/drivers/misc/mpu3050/accel/lis331.c
old mode 100644
new mode 100755
index b98dbc62d135..53c599b2ef27
--- a/drivers/misc/mpu3050/accel/lis331.c
+++ b/drivers/misc/mpu3050/accel/lis331.c
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
 
 /**
@@ -18,6 +31,9 @@
 /* - Include Files. - */
 /* ------------------ */
 
+#undef MPL_LOG_NDEBUG
+#define MPL_LOG_NDEBUG 1
+
 #ifdef __KERNEL__
 #include <linux/module.h>
 #endif
@@ -73,6 +89,8 @@ struct lis331dlh_config {
 	unsigned char reg_ths;
 	unsigned char reg_dur;
 	unsigned char ctrl_reg1;
+	unsigned char irq_type;
+	unsigned char mot_int1_cfg;
 };
 
 struct lis331dlh_private_data {
@@ -85,23 +103,36 @@ struct lis331dlh_private_data {
     Accelerometer Initialization Functions
 *****************************************/
 
-void lis331dlh_set_ths(struct lis331dlh_config *config,
-		long ths)
+static int lis331dlh_set_ths(void *mlsl_handle,
+			struct ext_slave_platform_data *pdata,
+			struct lis331dlh_config *config,
+			int apply,
+			long ths)
 {
-	if ((unsigned int) ths > 1000 * config->fsr)
-		ths = (long) 1000 * config->fsr;
+	int result = ML_SUCCESS;
+	if ((unsigned int) ths >= config->fsr)
+		ths = (long) config->fsr - 1;
 
 	if (ths < 0)
 		ths = 0;
 
 	config->ths = ths;
 	config->reg_ths = (unsigned char)(long)((ths * 128L) / (config->fsr));
-	MPL_LOGD("THS: %d, 0x%02x\n", config->ths, (int)config->reg_ths);
+	MPL_LOGV("THS: %d, 0x%02x\n", config->ths, (int)config->reg_ths);
+	if (apply)
+		result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					LIS331_INT1_THS,
+					config->reg_ths);
+	return result;
 }
 
-void lis331dlh_set_dur(struct lis331dlh_config *config,
-		long dur)
+static int lis331dlh_set_dur(void *mlsl_handle,
+			struct ext_slave_platform_data *pdata,
+			struct lis331dlh_config *config,
+			int apply,
+			long dur)
 {
+	int result = ML_SUCCESS;
 	long reg_dur = (dur * config->odr) / 1000000L;
 	config->dur = dur;
 
@@ -109,7 +140,54 @@ void lis331dlh_set_dur(struct lis331dlh_config *config,
 		reg_dur = LIS331_MAX_DUR;
 
 	config->reg_dur = (unsigned char) reg_dur;
-	MPL_LOGD("DUR: %d, 0x%02x\n", config->dur, (int)config->reg_dur);
+	MPL_LOGV("DUR: %d, 0x%02x\n", config->dur, (int)config->reg_dur);
+	if (apply)
+		result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					LIS331_INT1_DURATION,
+					(unsigned char)reg_dur);
+	return result;
+}
+
+/**
+ * Sets the IRQ to fire when one of the IRQ events occur.  Threshold and
+ * duration will not be used uless the type is MOT or NMOT.
+ *
+ * @param config configuration to apply to, suspend or resume
+ * @param irq_type The type of IRQ.  Valid values are
+ * - MPU_SLAVE_IRQ_TYPE_NONE
+ * - MPU_SLAVE_IRQ_TYPE_MOTION
+ * - MPU_SLAVE_IRQ_TYPE_DATA_READY
+ */
+static int lis331dlh_set_irq(void *mlsl_handle,
+			struct ext_slave_platform_data *pdata,
+			struct lis331dlh_config *config,
+			int apply,
+			long irq_type)
+{
+	int result = ML_SUCCESS;
+	unsigned char reg1;
+	unsigned char reg2;
+
+	config->irq_type = (unsigned char)irq_type;
+	if (irq_type == MPU_SLAVE_IRQ_TYPE_DATA_READY) {
+		reg1 = 0x02;
+		reg2 = 0x00;
+	} else if (irq_type == MPU_SLAVE_IRQ_TYPE_MOTION) {
+		reg1 = 0x00;
+		reg2 = config->mot_int1_cfg;
+	} else {
+		reg1 = 0x00;
+		reg2 = 0x00;
+	}
+
+	if (apply) {
+		result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					LIS331_CTRL_REG3, reg1);
+		result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					LIS331_INT1_CFG, reg2);
+	}
+
+	return result;
 }
 
 /**
@@ -118,11 +196,14 @@ void lis331dlh_set_dur(struct lis331dlh_config *config,
  * @param config Config to modify with new ODR
  * @param odr Output data rate in units of 1/1000Hz
  */
-static void lis331dlh_set_odr(
-	struct lis331dlh_config *config,
-	long odr)
+static int lis331dlh_set_odr(void *mlsl_handle,
+			struct ext_slave_platform_data *pdata,
+			struct lis331dlh_config *config,
+			int apply,
+			long odr)
 {
 	unsigned char bits;
+	int result = ML_SUCCESS;
 
 	if (odr > 400000) {
 		config->odr = 1000000;
@@ -157,31 +238,58 @@ static void lis331dlh_set_odr(
 	}
 
 	config->ctrl_reg1 = bits | (config->ctrl_reg1 & 0x7);
-	lis331dlh_set_dur(config, config->dur);
-	MPL_LOGD("ODR: %d, 0x%02x\n", config->odr, (int)config->ctrl_reg1);
+	lis331dlh_set_dur(mlsl_handle, pdata,
+			config, apply, config->dur);
+	MPL_LOGV("ODR: %d, 0x%02x\n", config->odr, (int)config->ctrl_reg1);
+	if (apply)
+		result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					LIS331_CTRL_REG1,
+					config->ctrl_reg1);
+	return result;
 }
 
-static void lis331dlh_set_fsr(
-	struct lis331dlh_config *config,
-	long fsr)
+/**
+ * Set the full scale range of the accels
+ *
+ * @param config pointer to configuration
+ * @param fsr requested full scale range
+ */
+static int lis331dlh_set_fsr(void *mlsl_handle,
+			struct ext_slave_platform_data *pdata,
+			struct lis331dlh_config *config,
+			int apply,
+			long fsr)
 {
-	if (fsr <= 2048)
+	unsigned char reg1 = 0x40;
+	int result = ML_SUCCESS;
+
+	if (fsr <= 2048) {
 		config->fsr = 2048;
-	else if (fsr <= 4096)
+	} else if (fsr <= 4096) {
+		reg1 |= 0x30;
 		config->fsr = 4096;
-	else
+	} else {
+		reg1 |= 0x10;
 		config->fsr = 8192;
+	}
+
+	lis331dlh_set_ths(mlsl_handle, pdata,
+			config, apply, config->ths);
+	MPL_LOGV("FSR: %d\n", config->fsr);
+	if (apply)
+		result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					LIS331_CTRL_REG4, reg1);
 
-	lis331dlh_set_ths(config, config->ths);
-	MPL_LOGD("FSR: %d\n", config->fsr);
+	return result;
 }
 
-int lis331dlh_suspend(void *mlsl_handle,
-		      struct ext_slave_descr *slave,
-		      struct ext_slave_platform_data *pdata)
+static int lis331dlh_suspend(void *mlsl_handle,
+			struct ext_slave_descr *slave,
+			struct ext_slave_platform_data *pdata)
 {
-	int result;
-	unsigned char reg;
+	int result = ML_SUCCESS;
+	unsigned char reg1;
+	unsigned char reg2;
 	struct lis331dlh_private_data *private_data = pdata->private_data;
 
 	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
@@ -190,36 +298,49 @@ int lis331dlh_suspend(void *mlsl_handle,
 
 	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
 				       LIS331_CTRL_REG2, 0x0f);
-	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
-				       LIS331_CTRL_REG3, 0x00);
-	reg = 0x40;
+	reg1 = 0x40;
 	if (private_data->suspend.fsr == 8192)
-		reg |= 0x30;
+		reg1 |= 0x30;
 	else if (private_data->suspend.fsr == 4096)
-		reg |= 0x10;
+		reg1 |= 0x10;
 	/* else bits [4..5] are already zero */
 
 	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
-				       LIS331_CTRL_REG4, reg);
+				       LIS331_CTRL_REG4, reg1);
 	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
 				       LIS331_INT1_THS,
 				       private_data->suspend.reg_ths);
 	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
 				       LIS331_INT1_DURATION,
 				       private_data->suspend.reg_dur);
+
+	if (private_data->suspend.irq_type == MPU_SLAVE_IRQ_TYPE_DATA_READY) {
+		reg1 = 0x02;
+		reg2 = 0x00;
+	} else if (private_data->suspend.irq_type ==
+		   MPU_SLAVE_IRQ_TYPE_MOTION) {
+		reg1 = 0x00;
+		reg2 = private_data->suspend.mot_int1_cfg;
+	} else {
+		reg1 = 0x00;
+		reg2 = 0x00;
+	}
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				       LIS331_CTRL_REG3, reg1);
 	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
-				       LIS331_INT1_CFG, 0x2a);
+				       LIS331_INT1_CFG, reg2);
 	result = MLSLSerialRead(mlsl_handle, pdata->address,
-				LIS331_HP_FILTER_RESET, 1, &reg);
+				LIS331_HP_FILTER_RESET, 1, &reg1);
 	return result;
 }
 
-int lis331dlh_resume(void *mlsl_handle,
-		     struct ext_slave_descr *slave,
-		     struct ext_slave_platform_data *pdata)
+static int lis331dlh_resume(void *mlsl_handle,
+			struct ext_slave_descr *slave,
+			struct ext_slave_platform_data *pdata)
 {
 	int result = ML_SUCCESS;
-	unsigned char reg;
+	unsigned char reg1;
+	unsigned char reg2;
 	struct lis331dlh_private_data *private_data = pdata->private_data;
 
 	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
@@ -229,45 +350,66 @@ int lis331dlh_resume(void *mlsl_handle,
 	MLOSSleep(6);
 
 	/* Full Scale */
-	reg = 0x40;
-	reg &= ~LIS331_CTRL_MASK;
+	reg1 = 0x40;
 	if (private_data->resume.fsr == 8192)
-		reg |= 0x30;
+		reg1 |= 0x30;
 	else if (private_data->resume.fsr == 4096)
-		reg |= 0x10;
+		reg1 |= 0x10;
 
 	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
-				       LIS331_CTRL_REG4, reg);
+				       LIS331_CTRL_REG4, reg1);
 	ERROR_CHECK(result);
 
 	/* Configure high pass filter */
 	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
 				       LIS331_CTRL_REG2, 0x0F);
 	ERROR_CHECK(result);
+
+	if (private_data->resume.irq_type == MPU_SLAVE_IRQ_TYPE_DATA_READY) {
+		reg1 = 0x02;
+		reg2 = 0x00;
+	} else if (private_data->resume.irq_type ==
+		   MPU_SLAVE_IRQ_TYPE_MOTION) {
+		reg1 = 0x00;
+		reg2 = private_data->resume.mot_int1_cfg;
+	} else {
+		reg1 = 0x00;
+		reg2 = 0x00;
+	}
 	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
-				       LIS331_CTRL_REG3, 0x00);
+				       LIS331_CTRL_REG3, reg1);
 	ERROR_CHECK(result);
 	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
-				       LIS331_INT1_THS, 0x02);
+				       LIS331_INT1_THS,
+				       private_data->resume.reg_ths);
 	ERROR_CHECK(result);
 	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
-				       LIS331_INT1_DURATION, 0x7F);
+				       LIS331_INT1_DURATION,
+				       private_data->resume.reg_dur);
 	ERROR_CHECK(result);
 	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
-				       LIS331_INT1_CFG, 0x95);
+				       LIS331_INT1_CFG, reg2);
 	ERROR_CHECK(result);
 	result = MLSLSerialRead(mlsl_handle, pdata->address,
-				LIS331_HP_FILTER_RESET, 1, &reg);
+				LIS331_HP_FILTER_RESET, 1, &reg1);
 	ERROR_CHECK(result);
 	return result;
 }
 
-int lis331dlh_read(void *mlsl_handle,
-		   struct ext_slave_descr *slave,
-		   struct ext_slave_platform_data *pdata,
-		   unsigned char *data)
+static int lis331dlh_read(void *mlsl_handle,
+			struct ext_slave_descr *slave,
+			struct ext_slave_platform_data *pdata,
+			unsigned char *data)
 {
-	return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
+	int result = ML_SUCCESS;
+	result = MLSLSerialRead(mlsl_handle, pdata->address,
+				LIS331_STATUS_REG, 1, data);
+	if (data[0] & 0x0F) {
+		result = MLSLSerialRead(mlsl_handle, pdata->address,
+					slave->reg, slave->len, data);
+		return result;
+	} else
+		return ML_ERROR_ACCEL_DATA_NOT_READY;
 }
 
 static int lis331dlh_init(void *mlsl_handle,
@@ -285,15 +427,31 @@ static int lis331dlh_init(void *mlsl_handle,
 
 	private_data->resume.ctrl_reg1 = 0x37;
 	private_data->suspend.ctrl_reg1 = 0x47;
-
-	lis331dlh_set_odr(&private_data->suspend, 50000);
-	lis331dlh_set_odr(&private_data->resume, 200000);
-	lis331dlh_set_fsr(&private_data->suspend, 2048);
-	lis331dlh_set_fsr(&private_data->resume, 2048);
-	lis331dlh_set_ths(&private_data->suspend, 80);
-	lis331dlh_set_ths(&private_data->resume, 40);
-	lis331dlh_set_dur(&private_data->suspend, 1000);
-	lis331dlh_set_dur(&private_data->resume,  2540);
+	private_data->resume.mot_int1_cfg = 0x95;
+	private_data->suspend.mot_int1_cfg = 0x2a;
+
+	lis331dlh_set_odr(mlsl_handle, pdata, &private_data->suspend,
+			FALSE, 0);
+	lis331dlh_set_odr(mlsl_handle, pdata, &private_data->resume,
+			FALSE, 200000);
+	lis331dlh_set_fsr(mlsl_handle, pdata, &private_data->suspend,
+			FALSE, 2048);
+	lis331dlh_set_fsr(mlsl_handle, pdata, &private_data->resume,
+			FALSE, 2048);
+	lis331dlh_set_ths(mlsl_handle, pdata, &private_data->suspend,
+			FALSE, 80);
+	lis331dlh_set_ths(mlsl_handle, pdata, &private_data->resume,
+			FALSE, 40);
+	lis331dlh_set_dur(mlsl_handle, pdata, &private_data->suspend,
+			FALSE, 1000);
+	lis331dlh_set_dur(mlsl_handle, pdata, &private_data->resume,
+			FALSE,  2540);
+	lis331dlh_set_irq(mlsl_handle, pdata, &private_data->suspend,
+			FALSE,
+			MPU_SLAVE_IRQ_TYPE_NONE);
+	lis331dlh_set_irq(mlsl_handle, pdata, &private_data->resume,
+			FALSE,
+			MPU_SLAVE_IRQ_TYPE_NONE);
 	return ML_SUCCESS;
 }
 
@@ -318,36 +476,111 @@ static int lis331dlh_config(void *mlsl_handle,
 
 	switch (data->key) {
 	case MPU_SLAVE_CONFIG_ODR_SUSPEND:
-		lis331dlh_set_odr(&private_data->suspend,
-				*((long *)data->data));
+		return lis331dlh_set_odr(mlsl_handle, pdata,
+					&private_data->suspend,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_ODR_RESUME:
+		return lis331dlh_set_odr(mlsl_handle, pdata,
+					&private_data->resume,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_FSR_SUSPEND:
+		return lis331dlh_set_fsr(mlsl_handle, pdata,
+					&private_data->suspend,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_FSR_RESUME:
+		return lis331dlh_set_fsr(mlsl_handle, pdata,
+					&private_data->resume,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_MOT_THS:
+		return lis331dlh_set_ths(mlsl_handle, pdata,
+					&private_data->suspend,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_NMOT_THS:
+		return lis331dlh_set_ths(mlsl_handle, pdata,
+					&private_data->resume,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_MOT_DUR:
+		return lis331dlh_set_dur(mlsl_handle, pdata,
+					&private_data->suspend,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_NMOT_DUR:
+		return lis331dlh_set_dur(mlsl_handle, pdata,
+					&private_data->resume,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_IRQ_SUSPEND:
+		return lis331dlh_set_irq(mlsl_handle, pdata,
+					&private_data->suspend,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_IRQ_RESUME:
+		return lis331dlh_set_irq(mlsl_handle, pdata,
+					&private_data->resume,
+					data->apply,
+					*((long *)data->data));
+	default:
+		return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
+	};
+
+	return ML_SUCCESS;
+}
+
+static int lis331dlh_get_config(void *mlsl_handle,
+				struct ext_slave_descr *slave,
+				struct ext_slave_platform_data *pdata,
+				struct ext_slave_config *data)
+{
+	struct lis331dlh_private_data *private_data = pdata->private_data;
+	if (!data->data)
+		return ML_ERROR_INVALID_PARAMETER;
+
+	switch (data->key) {
+	case MPU_SLAVE_CONFIG_ODR_SUSPEND:
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->suspend.odr;
 		break;
 	case MPU_SLAVE_CONFIG_ODR_RESUME:
-		lis331dlh_set_odr(&private_data->resume,
-				*((long *)data->data));
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->resume.odr;
 		break;
 	case MPU_SLAVE_CONFIG_FSR_SUSPEND:
-		lis331dlh_set_fsr(&private_data->suspend,
-				*((long *)data->data));
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->suspend.fsr;
 		break;
 	case MPU_SLAVE_CONFIG_FSR_RESUME:
-		lis331dlh_set_fsr(&private_data->resume,
-				*((long *)data->data));
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->resume.fsr;
 		break;
 	case MPU_SLAVE_CONFIG_MOT_THS:
-		lis331dlh_set_ths(&private_data->suspend,
-				*((long *)data->data));
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->suspend.ths;
 		break;
 	case MPU_SLAVE_CONFIG_NMOT_THS:
-		lis331dlh_set_ths(&private_data->resume,
-				*((long *)data->data));
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->resume.ths;
 		break;
 	case MPU_SLAVE_CONFIG_MOT_DUR:
-		lis331dlh_set_dur(&private_data->suspend,
-				*((long *)data->data));
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->suspend.dur;
 		break;
 	case MPU_SLAVE_CONFIG_NMOT_DUR:
-		lis331dlh_set_dur(&private_data->resume,
-				*((long *)data->data));
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->resume.dur;
+		break;
+	case MPU_SLAVE_CONFIG_IRQ_SUSPEND:
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->suspend.irq_type;
+		break;
+	case MPU_SLAVE_CONFIG_IRQ_RESUME:
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->resume.irq_type;
 		break;
 	default:
 		return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
@@ -356,13 +589,14 @@ static int lis331dlh_config(void *mlsl_handle,
 	return ML_SUCCESS;
 }
 
-struct ext_slave_descr lis331dlh_descr = {
+static struct ext_slave_descr lis331dlh_descr = {
 	/*.init             = */ lis331dlh_init,
 	/*.exit             = */ lis331dlh_exit,
 	/*.suspend          = */ lis331dlh_suspend,
 	/*.resume           = */ lis331dlh_resume,
 	/*.read             = */ lis331dlh_read,
 	/*.config           = */ lis331dlh_config,
+	/*.get_config       = */ lis331dlh_get_config,
 	/*.name             = */ "lis331dlh",
 	/*.type             = */ EXT_SLAVE_TYPE_ACCELEROMETER,
 	/*.id               = */ ACCEL_ID_LIS331,
diff --git a/drivers/misc/mpu3050/accel/lis3dh.c b/drivers/misc/mpu3050/accel/lis3dh.c
new file mode 100755
index 000000000000..ee5e3539b988
--- /dev/null
+++ b/drivers/misc/mpu3050/accel/lis3dh.c
@@ -0,0 +1,624 @@
+/*
+ $License:
+    Copyright (C) 2010 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/>.
+  $
+ */
+
+/**
+ *  @defgroup   ACCELDL (Motion Library - Accelerometer Driver Layer)
+ *  @brief      Provides the interface to setup and handle an accelerometers
+ *              connected to the secondary I2C interface of the gyroscope.
+ *
+ *  @{
+ *      @file   lis3dh.c
+ *      @brief  Accelerometer setup and handling methods for ST LIS3DH
+ */
+
+/* ------------------ */
+/* - Include Files. - */
+/* ------------------ */
+
+#undef MPL_LOG_NDEBUG
+#define MPL_LOG_NDEBUG 0
+
+#ifdef __KERNEL__
+#include <linux/module.h>
+#endif
+
+#include "mpu.h"
+#include "mlsl.h"
+#include "mlos.h"
+
+#include <log.h>
+#undef MPL_LOG_TAG
+#define MPL_LOG_TAG "MPL-acc"
+
+/* full scale setting - register & mask */
+#define LIS3DH_CTRL_REG1         (0x20)
+#define LIS3DH_CTRL_REG2         (0x21)
+#define LIS3DH_CTRL_REG3         (0x22)
+#define LIS3DH_CTRL_REG4         (0x23)
+#define LIS3DH_CTRL_REG5         (0x24)
+#define LIS3DH_CTRL_REG6         (0x25)
+#define LIS3DH_REFERENCE         (0x26)
+#define LIS3DH_STATUS_REG        (0x27)
+#define LIS3DH_OUT_X_L           (0x28)
+#define LIS3DH_OUT_X_H           (0x29)
+#define LIS3DH_OUT_Y_L           (0x2a)
+#define LIS3DH_OUT_Y_H           (0x2b)
+#define LIS3DH_OUT_Z_L           (0x2b)
+#define LIS3DH_OUT_Z_H           (0x2d)
+
+#define LIS3DH_INT1_CFG          (0x30)
+#define LIS3DH_INT1_SRC          (0x31)
+#define LIS3DH_INT1_THS          (0x32)
+#define LIS3DH_INT1_DURATION     (0x33)
+
+#define LIS3DH_MAX_DUR (0x7F)
+
+
+/* --------------------- */
+/* -    Variables.     - */
+/* --------------------- */
+
+struct lis3dh_config {
+	unsigned int odr;
+	unsigned int fsr; /* full scale range mg */
+	unsigned int ths; /* Motion no-motion thseshold mg */
+	unsigned int dur; /* Motion no-motion duration ms */
+	unsigned char reg_ths;
+	unsigned char reg_dur;
+	unsigned char ctrl_reg1;
+	unsigned char irq_type;
+	unsigned char mot_int1_cfg;
+};
+
+struct lis3dh_private_data {
+	struct lis3dh_config suspend;
+	struct lis3dh_config resume;
+};
+
+
+/*****************************************
+    Accelerometer Initialization Functions
+*****************************************/
+
+static int lis3dh_set_ths(void *mlsl_handle,
+			struct ext_slave_platform_data *pdata,
+			struct lis3dh_config *config,
+			int apply,
+			long ths)
+{
+	int result = ML_SUCCESS;
+	if ((unsigned int) ths > 1000 * config->fsr)
+		ths = (long) 1000 * config->fsr;
+
+	if (ths < 0)
+		ths = 0;
+
+	config->ths = ths;
+	config->reg_ths = (unsigned char)(long)((ths * 128L) / (config->fsr));
+	MPL_LOGV("THS: %d, 0x%02x\n", config->ths, (int)config->reg_ths);
+	if (apply)
+		result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					LIS3DH_INT1_THS,
+					config->reg_ths);
+	return result;
+}
+
+static int lis3dh_set_dur(void *mlsl_handle,
+			struct ext_slave_platform_data *pdata,
+			struct lis3dh_config *config,
+			int apply,
+			long dur)
+{
+	int result = ML_SUCCESS;
+	long reg_dur = (dur * config->odr) / 1000000L;
+	config->dur = dur;
+
+	if (reg_dur > LIS3DH_MAX_DUR)
+		reg_dur = LIS3DH_MAX_DUR;
+
+	config->reg_dur = (unsigned char) reg_dur;
+	MPL_LOGV("DUR: %d, 0x%02x\n", config->dur, (int)config->reg_dur);
+	if (apply)
+		result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					LIS3DH_INT1_DURATION,
+					(unsigned char)reg_dur);
+	return result;
+}
+
+/**
+ * Sets the IRQ to fire when one of the IRQ events occur.  Threshold and
+ * duration will not be used uless the type is MOT or NMOT.
+ *
+ * @param config configuration to apply to, suspend or resume
+ * @param irq_type The type of IRQ.  Valid values are
+ * - MPU_SLAVE_IRQ_TYPE_NONE
+ * - MPU_SLAVE_IRQ_TYPE_MOTION
+ * - MPU_SLAVE_IRQ_TYPE_DATA_READY
+ */
+static int lis3dh_set_irq(void *mlsl_handle,
+			struct ext_slave_platform_data *pdata,
+			struct lis3dh_config *config,
+			int apply,
+			long irq_type)
+{
+	int result = ML_SUCCESS;
+	unsigned char reg1;
+	unsigned char reg2;
+
+	config->irq_type = (unsigned char)irq_type;
+	if (irq_type == MPU_SLAVE_IRQ_TYPE_DATA_READY) {
+		reg1 = 0x10;
+		reg2 = 0x00;
+	} else if (irq_type == MPU_SLAVE_IRQ_TYPE_MOTION) {
+		reg1 = 0x40;
+		reg2 = config->mot_int1_cfg;
+	} else {
+		reg1 = 0x00;
+		reg2 = 0x00;
+	}
+
+	if (apply) {
+		result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					LIS3DH_CTRL_REG3, reg1);
+		result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					LIS3DH_INT1_CFG, reg2);
+	}
+
+	return result;
+}
+
+/**
+ * Set the Output data rate for the particular configuration
+ *
+ * @param config Config to modify with new ODR
+ * @param odr Output data rate in units of 1/1000Hz
+ */
+static int lis3dh_set_odr(void *mlsl_handle,
+			struct ext_slave_platform_data *pdata,
+			struct lis3dh_config *config,
+			int apply,
+			long odr)
+{
+	unsigned char bits;
+	int result = ML_SUCCESS;
+
+	if (odr > 400000) {
+		config->odr = 1250000;
+		bits = 0x90;
+	} else if (odr > 200000) {
+		config->odr = 400000;
+		bits = 0x70;
+	} else if (odr > 100000) {
+		config->odr = 200000;
+		bits = 0x60;
+	} else if (odr > 50000) {
+		config->odr = 100000;
+		bits = 0x50;
+	} else if (odr > 25000) {
+		config->odr = 50000;
+		bits = 0x40;
+	} else if (odr > 10000) {
+		config->odr = 25000;
+		bits = 0x30;
+	} else if (odr > 1000) {
+		config->odr = 10000;
+		bits = 0x20;
+	} else if (odr > 500) {
+		config->odr = 1000;
+		bits = 0x10;
+	} else {
+		config->odr = 0;
+		bits = 0;
+	}
+
+	config->ctrl_reg1 = bits | (config->ctrl_reg1 & 0xf);
+	lis3dh_set_dur(mlsl_handle, pdata,
+			config, apply, config->dur);
+	MPL_LOGV("ODR: %d, 0x%02x\n", config->odr, (int)config->ctrl_reg1);
+	if (apply)
+		result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					LIS3DH_CTRL_REG1,
+					config->ctrl_reg1);
+	return result;
+}
+
+/**
+ * Set the full scale range of the accels
+ *
+ * @param config pointer to configuration
+ * @param fsr requested full scale range
+ */
+static int lis3dh_set_fsr(void *mlsl_handle,
+			struct ext_slave_platform_data *pdata,
+			struct lis3dh_config *config,
+			int apply,
+			long fsr)
+{
+	int result = ML_SUCCESS;
+	unsigned char reg1 = 0x48;
+
+	if (fsr <= 2048) {
+		config->fsr = 2048;
+	} else if (fsr <= 4096) {
+		reg1 |= 0x10;
+		config->fsr = 4096;
+	} else if (fsr <= 8192) {
+		reg1 |= 0x20;
+		config->fsr = 8192;
+	} else {
+		reg1 |= 0x30;
+		config->fsr = 16348;
+	}
+
+	lis3dh_set_ths(mlsl_handle, pdata,
+			config, apply, config->ths);
+	MPL_LOGV("FSR: %d\n", config->fsr);
+	if (apply)
+		result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					LIS3DH_CTRL_REG4, reg1);
+
+	return result;
+}
+
+static int lis3dh_suspend(void *mlsl_handle,
+			struct ext_slave_descr *slave,
+			struct ext_slave_platform_data *pdata)
+{
+	int result = ML_SUCCESS;
+	unsigned char reg1;
+	unsigned char reg2;
+	struct lis3dh_private_data *private_data = pdata->private_data;
+
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				       LIS3DH_CTRL_REG1,
+				       private_data->suspend.ctrl_reg1);
+
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				       LIS3DH_CTRL_REG2, 0x31);
+	reg1 = 0x48;
+	if (private_data->suspend.fsr == 16384)
+		reg1 |= 0x30;
+	else if (private_data->suspend.fsr == 8192)
+		reg1 |= 0x20;
+	else if (private_data->suspend.fsr == 4096)
+		reg1 |= 0x10;
+	else if (private_data->suspend.fsr == 2048)
+		reg1 |= 0x00;
+
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				       LIS3DH_CTRL_REG4, reg1);
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				       LIS3DH_INT1_THS,
+				       private_data->suspend.reg_ths);
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				       LIS3DH_INT1_DURATION,
+				       private_data->suspend.reg_dur);
+
+	if (private_data->suspend.irq_type == MPU_SLAVE_IRQ_TYPE_DATA_READY) {
+		reg1 = 0x10;
+		reg2 = 0x00;
+	} else if (private_data->suspend.irq_type ==
+		   MPU_SLAVE_IRQ_TYPE_MOTION) {
+		reg1 = 0x40;
+		reg2 = private_data->suspend.mot_int1_cfg;
+	} else {
+		reg1 = 0x00;
+		reg2 = 0x00;
+	}
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				       LIS3DH_CTRL_REG3, reg1);
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				       LIS3DH_INT1_CFG, reg2);
+	result = MLSLSerialRead(mlsl_handle, pdata->address,
+				LIS3DH_CTRL_REG6, 1, &reg1);
+
+	return result;
+}
+
+static int lis3dh_resume(void *mlsl_handle,
+			struct ext_slave_descr *slave,
+			struct ext_slave_platform_data *pdata)
+{
+	tMLError result;
+	unsigned char reg1;
+	unsigned char reg2;
+	struct lis3dh_private_data *private_data = pdata->private_data;
+
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				       LIS3DH_CTRL_REG1,
+				       private_data->resume.ctrl_reg1);
+	ERROR_CHECK(result);
+	MLOSSleep(6);
+
+	/* Full Scale */
+	reg1 = 0x48;
+	if (private_data->suspend.fsr == 16384)
+		reg1 |= 0x30;
+	else if (private_data->suspend.fsr == 8192)
+		reg1 |= 0x20;
+	else if (private_data->suspend.fsr == 4096)
+		reg1 |= 0x10;
+	else if (private_data->suspend.fsr == 2048)
+		reg1 |= 0x00;
+
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				       LIS3DH_CTRL_REG4, reg1);
+	ERROR_CHECK(result);
+
+	/* Configure high pass filter */
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				       LIS3DH_CTRL_REG2, 0x31);
+	ERROR_CHECK(result);
+
+	if (private_data->resume.irq_type == MPU_SLAVE_IRQ_TYPE_DATA_READY) {
+		reg1 = 0x10;
+		reg2 = 0x00;
+	} else if (private_data->resume.irq_type ==
+		   MPU_SLAVE_IRQ_TYPE_MOTION) {
+		reg1 = 0x40;
+		reg2 = private_data->resume.mot_int1_cfg;
+	} else {
+		reg1 = 0x00;
+		reg2 = 0x00;
+	}
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				       LIS3DH_CTRL_REG3, reg1);
+	ERROR_CHECK(result);
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				       LIS3DH_INT1_THS,
+				       private_data->resume.reg_ths);
+	ERROR_CHECK(result);
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				       LIS3DH_INT1_DURATION,
+				       private_data->resume.reg_dur);
+	ERROR_CHECK(result);
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				       LIS3DH_INT1_CFG, reg2);
+	ERROR_CHECK(result);
+	result = MLSLSerialRead(mlsl_handle, pdata->address,
+				LIS3DH_CTRL_REG6, 1, &reg1);
+	ERROR_CHECK(result);
+	return result;
+}
+
+static int lis3dh_read(void *mlsl_handle,
+			struct ext_slave_descr *slave,
+			struct ext_slave_platform_data *pdata,
+			unsigned char *data)
+{
+	int result = ML_SUCCESS;
+	result = MLSLSerialRead(mlsl_handle, pdata->address,
+				LIS3DH_STATUS_REG, 1, data);
+	if (data[0] & 0x0F) {
+		result = MLSLSerialRead(mlsl_handle, pdata->address,
+					slave->reg, slave->len, data);
+		return result;
+	} else
+		return ML_ERROR_ACCEL_DATA_NOT_READY;
+}
+
+static int lis3dh_init(void *mlsl_handle,
+			  struct ext_slave_descr *slave,
+			  struct ext_slave_platform_data *pdata)
+{
+	tMLError result;
+
+	struct lis3dh_private_data *private_data;
+	private_data = (struct lis3dh_private_data *)
+		MLOSMalloc(sizeof(struct lis3dh_private_data));
+
+	if (!private_data)
+		return ML_ERROR_MEMORY_EXAUSTED;
+
+	pdata->private_data = private_data;
+
+	private_data->resume.ctrl_reg1 = 0x67;
+	private_data->suspend.ctrl_reg1 = 0x18;
+	private_data->resume.mot_int1_cfg = 0x95;
+	private_data->suspend.mot_int1_cfg = 0x2a;
+
+	lis3dh_set_odr(mlsl_handle, pdata, &private_data->suspend,
+			FALSE, 0);
+	lis3dh_set_odr(mlsl_handle, pdata, &private_data->resume,
+			FALSE, 200000);
+	lis3dh_set_fsr(mlsl_handle, pdata, &private_data->suspend,
+			FALSE, 2048);
+	lis3dh_set_fsr(mlsl_handle, pdata, &private_data->resume,
+			FALSE, 2048);
+	lis3dh_set_ths(mlsl_handle, pdata, &private_data->suspend,
+			FALSE, 80);
+	lis3dh_set_ths(mlsl_handle, pdata, &private_data->resume,
+			FALSE, 40);
+	lis3dh_set_dur(mlsl_handle, pdata, &private_data->suspend,
+			FALSE, 1000);
+	lis3dh_set_dur(mlsl_handle, pdata, &private_data->resume,
+			FALSE,  2540);
+	lis3dh_set_irq(mlsl_handle, pdata, &private_data->suspend,
+			FALSE,
+			MPU_SLAVE_IRQ_TYPE_NONE);
+	lis3dh_set_irq(mlsl_handle, pdata, &private_data->resume,
+			FALSE,
+			MPU_SLAVE_IRQ_TYPE_NONE);
+
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				       LIS3DH_CTRL_REG1, 0x07);
+	MLOSSleep(6);
+
+	return ML_SUCCESS;
+}
+
+static int lis3dh_exit(void *mlsl_handle,
+			  struct ext_slave_descr *slave,
+			  struct ext_slave_platform_data *pdata)
+{
+	if (pdata->private_data)
+		return MLOSFree(pdata->private_data);
+	else
+		return ML_SUCCESS;
+}
+
+static int lis3dh_config(void *mlsl_handle,
+			struct ext_slave_descr *slave,
+			struct ext_slave_platform_data *pdata,
+			struct ext_slave_config *data)
+{
+	struct lis3dh_private_data *private_data = pdata->private_data;
+	if (!data->data)
+		return ML_ERROR_INVALID_PARAMETER;
+
+	switch (data->key) {
+	case MPU_SLAVE_CONFIG_ODR_SUSPEND:
+		return lis3dh_set_odr(mlsl_handle, pdata,
+					&private_data->suspend,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_ODR_RESUME:
+		return lis3dh_set_odr(mlsl_handle, pdata,
+					&private_data->resume,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_FSR_SUSPEND:
+		return lis3dh_set_fsr(mlsl_handle, pdata,
+					&private_data->suspend,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_FSR_RESUME:
+		return lis3dh_set_fsr(mlsl_handle, pdata,
+					&private_data->resume,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_MOT_THS:
+		return lis3dh_set_ths(mlsl_handle, pdata,
+					&private_data->suspend,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_NMOT_THS:
+		return lis3dh_set_ths(mlsl_handle, pdata,
+					&private_data->resume,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_MOT_DUR:
+		return lis3dh_set_dur(mlsl_handle, pdata,
+					&private_data->suspend,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_NMOT_DUR:
+		return lis3dh_set_dur(mlsl_handle, pdata,
+					&private_data->resume,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_IRQ_SUSPEND:
+		return lis3dh_set_irq(mlsl_handle, pdata,
+					&private_data->suspend,
+					data->apply,
+					*((long *)data->data));
+	case MPU_SLAVE_CONFIG_IRQ_RESUME:
+		return lis3dh_set_irq(mlsl_handle, pdata,
+					&private_data->resume,
+					data->apply,
+					*((long *)data->data));
+	default:
+		return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
+	};
+	return ML_SUCCESS;
+}
+
+static int lis3dh_get_config(void *mlsl_handle,
+				struct ext_slave_descr *slave,
+				struct ext_slave_platform_data *pdata,
+				struct ext_slave_config *data)
+{
+	struct lis3dh_private_data *private_data = pdata->private_data;
+	if (!data->data)
+		return ML_ERROR_INVALID_PARAMETER;
+
+	switch (data->key) {
+	case MPU_SLAVE_CONFIG_ODR_SUSPEND:
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->suspend.odr;
+		break;
+	case MPU_SLAVE_CONFIG_ODR_RESUME:
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->resume.odr;
+		break;
+	case MPU_SLAVE_CONFIG_FSR_SUSPEND:
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->suspend.fsr;
+		break;
+	case MPU_SLAVE_CONFIG_FSR_RESUME:
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->resume.fsr;
+		break;
+	case MPU_SLAVE_CONFIG_MOT_THS:
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->suspend.ths;
+		break;
+	case MPU_SLAVE_CONFIG_NMOT_THS:
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->resume.ths;
+		break;
+	case MPU_SLAVE_CONFIG_MOT_DUR:
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->suspend.dur;
+		break;
+	case MPU_SLAVE_CONFIG_NMOT_DUR:
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->resume.dur;
+		break;
+	case MPU_SLAVE_CONFIG_IRQ_SUSPEND:
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->suspend.irq_type;
+		break;
+	case MPU_SLAVE_CONFIG_IRQ_RESUME:
+		(*(unsigned long *)data->data) =
+			(unsigned long) private_data->resume.irq_type;
+		break;
+	default:
+		return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
+	};
+
+	return ML_SUCCESS;
+}
+
+static struct ext_slave_descr lis3dh_descr = {
+	/*.init             = */ lis3dh_init,
+	/*.exit             = */ lis3dh_exit,
+	/*.suspend          = */ lis3dh_suspend,
+	/*.resume           = */ lis3dh_resume,
+	/*.read             = */ lis3dh_read,
+	/*.config           = */ lis3dh_config,
+	/*.get_config       = */ lis3dh_get_config,
+	/*.name             = */ "lis3dh",
+	/*.type             = */ EXT_SLAVE_TYPE_ACCELEROMETER,
+	/*.id               = */ ACCEL_ID_LIS3DH,
+	/*.reg              = */ 0x28 | 0x80, /* 0x80 for burst reads */
+	/*.len              = */ 6,
+	/*.endian           = */ EXT_SLAVE_BIG_ENDIAN,
+	/*.range            = */ {2, 480},
+};
+
+struct ext_slave_descr *lis3dh_get_slave_descr(void)
+{
+	return &lis3dh_descr;
+}
+EXPORT_SYMBOL(lis3dh_get_slave_descr);
+
+/*
+ *  @}
+*/
diff --git a/drivers/misc/mpu3050/accel/lsm303a.c b/drivers/misc/mpu3050/accel/lsm303a.c
old mode 100644
new mode 100755
index 47e2ac10d1ff..b8494962d3ac
--- a/drivers/misc/mpu3050/accel/lsm303a.c
+++ b/drivers/misc/mpu3050/accel/lsm303a.c
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
 
 /**
@@ -131,7 +144,10 @@ int lsm303dlha_read(void *mlsl_handle,
 		    struct ext_slave_platform_data *pdata,
 		    unsigned char *data)
 {
-	return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
+	int result;
+	result = MLSLSerialRead(mlsl_handle, pdata->address,
+				slave->reg, slave->len, data);
+	return result;
 }
 
 struct ext_slave_descr lsm303dlha_descr = {
@@ -141,6 +157,7 @@ struct ext_slave_descr lsm303dlha_descr = {
 	/*.resume           = */ lsm303dlha_resume,
 	/*.read             = */ lsm303dlha_read,
 	/*.config           = */ NULL,
+	/*.get_config       = */ NULL,
 	/*.name             = */ "lsm303dlha",
 	/*.type             = */ EXT_SLAVE_TYPE_ACCELEROMETER,
 	/*.id               = */ ACCEL_ID_LSM303,
diff --git a/drivers/misc/mpu3050/accel/mantis.c b/drivers/misc/mpu3050/accel/mantis.c
old mode 100644
new mode 100755
index 9e6f3e442e92..1cb9847fee05
--- a/drivers/misc/mpu3050/accel/mantis.c
+++ b/drivers/misc/mpu3050/accel/mantis.c
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
 /**
  *  @defgroup   ACCELDL (Motion Library - Accelerometer Driver Layer)
@@ -10,7 +23,7 @@
  *
  *  @{
  *      @file   lis331.c
- *      @brief  Accelerometer setup and handling methods for ST LIS331
+ *      @brief  Accelerometer setup and handling methods for Invensense MANTIS
  */
 
 /* ------------------ */
@@ -29,35 +42,143 @@
 #undef MPL_LOG_TAG
 #define MPL_LOG_TAG "MPL-acc"
 
-#define ACCEL_ST_SLEEP_REG          (0x20)
-#define ACCEL_ST_SLEEP_MASK         (0x20)
-
 /* --------------------- */
 /* -    Variables.     - */
 /* --------------------- */
 
+struct mantis_config {
+	unsigned int odr; /* output data rate 1/1000 Hz*/
+	unsigned int fsr; /* full scale range mg */
+	unsigned int ths; /* Motion no-motion thseshold mg */
+	unsigned int dur; /* Motion no-motion duration ms */
+};
+
+struct mantis_private_data {
+	struct mantis_config suspend;
+	struct mantis_config resume;
+};
+
+
 /*****************************************
-    Accelerometer Initialization Functions
-*****************************************/
+ *Accelerometer Initialization Functions
+ *****************************************/
+/**
+ * Record the odr for use in computing duration values.
+ *
+ * @param config Config to set, suspend or resume structure
+ * @param odr output data rate in 1/1000 hz
+ */
+void mantis_set_odr(struct mantis_config *config,
+		long odr)
+{
+	config->odr = odr;
+}
+
+void mantis_set_ths(struct mantis_config *config,
+		long ths)
+{
+	if (ths < 0)
+		ths = 0;
+
+	config->ths = ths;
+	MPL_LOGV("THS: %d\n", config->ths);
+}
+
+void mantis_set_dur(struct mantis_config *config,
+		long dur)
+{
+	if (dur < 0)
+		dur = 0;
+
+	config->dur = dur;
+	MPL_LOGV("DUR: %d\n", config->dur);
+}
+
+static void mantis_set_fsr(
+	struct mantis_config *config,
+	long fsr)
+{
+	if (fsr <= 2000)
+		config->fsr = 2000;
+	else if (fsr <= 4000)
+		config->fsr = 4000;
+	else
+		config->fsr = 8000;
+
+	MPL_LOGV("FSR: %d\n", config->fsr);
+}
+
+static int mantis_init(void *mlsl_handle,
+		       struct ext_slave_descr *slave,
+		       struct ext_slave_platform_data *pdata)
+{
+	struct mantis_private_data *private_data;
+	private_data = (struct mantis_private_data *)
+		MLOSMalloc(sizeof(struct mantis_private_data));
+
+	if (!private_data)
+		return ML_ERROR_MEMORY_EXAUSTED;
+
+	pdata->private_data = private_data;
+
+	mantis_set_odr(&private_data->suspend, 0);
+	mantis_set_odr(&private_data->resume, 200000);
+	mantis_set_fsr(&private_data->suspend, 2000);
+	mantis_set_fsr(&private_data->resume, 2000);
+	mantis_set_ths(&private_data->suspend, 80);
+	mantis_set_ths(&private_data->resume, 40);
+	mantis_set_dur(&private_data->suspend, 1000);
+	mantis_set_dur(&private_data->resume,  2540);
+	return ML_SUCCESS;
+}
+
+static int mantis_exit(void *mlsl_handle,
+			  struct ext_slave_descr *slave,
+			  struct ext_slave_platform_data *pdata)
+{
+	if (pdata->private_data)
+		return MLOSFree(pdata->private_data);
+	else
+		return ML_SUCCESS;
+}
 
 int mantis_suspend(void *mlsl_handle,
 		   struct ext_slave_descr *slave,
 		   struct ext_slave_platform_data *pdata)
 {
+	unsigned char reg;
+	int result;
+
+	result = MLSLSerialRead(mlsl_handle, pdata->address,
+				MPUREG_PWR_MGMT_2, 1, &reg);
+	ERROR_CHECK(result);
+	reg |= (BIT_STBY_XA | BIT_STBY_YA | BIT_STBY_ZA);
+
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				MPUREG_PWR_MGMT_2, reg);
+	ERROR_CHECK(result);
+
 	return ML_SUCCESS;
 }
 
-/* full scale setting - register & mask */
-#define ACCEL_ST_CTRL_REG          (0x23)
-#define ACCEL_ST_CTRL_MASK         (0x30)
-
 int mantis_resume(void *mlsl_handle,
 		  struct ext_slave_descr *slave,
 		  struct ext_slave_platform_data *pdata)
 {
 	int result = ML_SUCCESS;
-#ifdef M_HW
 	unsigned char reg;
+	struct mantis_private_data *private_data;
+
+	private_data = (struct mantis_private_data *) pdata->private_data;
+
+	MLSLSerialRead(mlsl_handle, pdata->address,
+		MPUREG_PWR_MGMT_2, 1, &reg);
+
+	reg &= ~(BIT_STBY_XA | BIT_STBY_YA | BIT_STBY_ZA);
+
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				MPUREG_PWR_MGMT_2, reg);
+	ERROR_CHECK(result);
 
 	if (slave->range.mantissa == 2)
 		reg = 0;
@@ -72,7 +193,28 @@ int mantis_resume(void *mlsl_handle,
 
 	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
 				       MPUREG_ACCEL_CONFIG, reg);
-#endif
+	ERROR_CHECK(result);
+
+	reg = (unsigned char) private_data->suspend.ths / ACCEL_MOT_THR_LSB;
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				MPUREG_ACCEL_MOT_THR, reg);
+	ERROR_CHECK(result);
+
+	reg = (unsigned char)
+		ACCEL_ZRMOT_THR_LSB_CONVERSION(private_data->resume.ths);
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				MPUREG_ACCEL_ZRMOT_THR, reg);
+	ERROR_CHECK(result);
+
+	reg = (unsigned char) private_data->suspend.ths / ACCEL_MOT_DUR_LSB;
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				MPUREG_ACCEL_MOT_DUR, reg);
+	ERROR_CHECK(result);
+
+	reg = (unsigned char) private_data->resume.ths / ACCEL_ZRMOT_DUR_LSB;
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				MPUREG_ACCEL_ZRMOT_DUR, reg);
+	ERROR_CHECK(result);
 	return result;
 }
 
@@ -80,16 +222,69 @@ int mantis_read(void *mlsl_handle,
 		struct ext_slave_descr *slave,
 		struct ext_slave_platform_data *pdata, unsigned char *data)
 {
-	return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
+	int result;
+	result = MLSLSerialRead(mlsl_handle, pdata->address,
+				slave->reg, slave->len, data);
+	return result;
+}
+
+static int mantis_config(void *mlsl_handle,
+			struct ext_slave_descr *slave,
+			struct ext_slave_platform_data *pdata,
+			struct ext_slave_config *data)
+{
+	struct mantis_private_data *private_data = pdata->private_data;
+	if (!data->data)
+		return ML_ERROR_INVALID_PARAMETER;
+
+	switch (data->key) {
+	case MPU_SLAVE_CONFIG_ODR_SUSPEND:
+		mantis_set_odr(&private_data->suspend,
+				*((long *)data->data));
+		break;
+	case MPU_SLAVE_CONFIG_ODR_RESUME:
+		mantis_set_odr(&private_data->resume,
+				*((long *)data->data));
+		break;
+	case MPU_SLAVE_CONFIG_FSR_SUSPEND:
+		mantis_set_fsr(&private_data->suspend,
+				*((long *)data->data));
+		break;
+	case MPU_SLAVE_CONFIG_FSR_RESUME:
+		mantis_set_fsr(&private_data->resume,
+				*((long *)data->data));
+		break;
+	case MPU_SLAVE_CONFIG_MOT_THS:
+		mantis_set_ths(&private_data->suspend,
+			       (*((long *)data->data)));
+		break;
+	case MPU_SLAVE_CONFIG_NMOT_THS:
+		mantis_set_ths(&private_data->resume,
+			       (*((long *)data->data)));
+		break;
+	case MPU_SLAVE_CONFIG_MOT_DUR:
+		mantis_set_dur(&private_data->suspend,
+			       (*((long *)data->data)));
+		break;
+	case MPU_SLAVE_CONFIG_NMOT_DUR:
+		mantis_set_dur(&private_data->resume,
+			       (*((long *)data->data)));
+		break;
+	default:
+		return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
+	};
+
+	return ML_SUCCESS;
 }
 
 struct ext_slave_descr mantis_descr = {
-	/*.init             = */ NULL,
-	/*.exit             = */ NULL,
+	/*.init             = */ mantis_init,
+	/*.exit             = */ mantis_exit,
 	/*.suspend          = */ mantis_suspend,
 	/*.resume           = */ mantis_resume,
 	/*.read             = */ mantis_read,
-	/*.config           = */ NULL,
+	/*.config           = */ mantis_config,
+	/*.get_config       = */ NULL,
 	/*.name             = */ "mantis",
 	/*.type             = */ EXT_SLAVE_TYPE_ACCELEROMETER,
 	/*.id               = */ ACCEL_ID_MPU6000,
diff --git a/drivers/misc/mpu3050/accel/mma8450.c b/drivers/misc/mpu3050/accel/mma8450.c
old mode 100644
new mode 100755
index fec9c741a3a8..ffc92fd8bbdf
--- a/drivers/misc/mpu3050/accel/mma8450.c
+++ b/drivers/misc/mpu3050/accel/mma8450.c
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
 
 /**
@@ -18,9 +31,11 @@
 /* - Include Files. - */
 /* ------------------ */
 
+#include <stdlib.h>
 #include "mpu.h"
 #include "mlsl.h"
 #include "mlos.h"
+#include <string.h>
 
 #include <log.h>
 #undef MPL_LOG_TAG
@@ -90,7 +105,8 @@ int mma8450_resume(void *mlsl_handle,
 
 	/* XYZ_DATA_CFG: event flag enabled on all axis */
 	result =
-	    MLSLSerialWriteSingle(mlsl_handle, pdata->address, 0x16, 0x05);
+	    MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				  0x16, 0x05);
 	ERROR_CHECK(result);
 	/* CTRL_REG1: rate + scale config + wakeup */
 	result =
@@ -106,7 +122,13 @@ int mma8450_read(void *mlsl_handle,
 		 struct ext_slave_platform_data *pdata,
 		 unsigned char *data)
 {
-	return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
+	int result;
+	unsigned char local_data[4]; /* Status register + 3 bytes data */
+	result = MLSLSerialRead(mlsl_handle, pdata->address,
+				slave->reg, sizeof(local_data), local_data);
+    ERROR_CHECK(result);
+    memcpy(data, &local_data[1], (slave->len)-1);
+    return result;
 }
 
 struct ext_slave_descr mma8450_descr = {
@@ -116,11 +138,12 @@ struct ext_slave_descr mma8450_descr = {
 	/*.resume           = */ mma8450_resume,
 	/*.read             = */ mma8450_read,
 	/*.config           = */ NULL,
+	/*.get_config       = */ NULL,
 	/*.name             = */ "mma8450",
 	/*.type             = */ EXT_SLAVE_TYPE_ACCELEROMETER,
 	/*.id               = */ ACCEL_ID_MMA8450,
 	/*.reg              = */ 0x00,
-	/*.len              = */ 3,
+	/*.len              = */ 4,
 	/*.endian           = */ EXT_SLAVE_FS8_BIG_ENDIAN,
 	/*.range            = */ {2, 0},
 };
diff --git a/drivers/misc/mpu3050/accel/mma845x.c b/drivers/misc/mpu3050/accel/mma845x.c
new file mode 100755
index 000000000000..27150ad86994
--- /dev/null
+++ b/drivers/misc/mpu3050/accel/mma845x.c
@@ -0,0 +1,158 @@
+/*
+ $License:
+    Copyright (C) 2010 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/>.
+  $
+ */
+
+/**
+ *  @defgroup   ACCELDL (Motion Library - Accelerometer Driver Layer)
+ *  @brief      Provides the interface to setup and handle an accelerometers
+ *              connected to the secondary I2C interface of the gyroscope.
+ *
+ *  @{
+ *      @file   mma845x.c
+ *      @brief  Accelerometer setup and handling methods for Freescale MMA845X
+ */
+
+/* ------------------ */
+/* - Include Files. - */
+/* ------------------ */
+
+#ifdef __KERNEL__
+#include <linux/module.h>
+#endif
+
+#include <stdlib.h>
+#include "mpu.h"
+#include "mlsl.h"
+#include "mlos.h"
+#include <string.h>
+
+#include <log.h>
+#undef MPL_LOG_TAG
+#define MPL_LOG_TAG "MPL-acc"
+
+#define ACCEL_MMA845X_CTRL_REG1      (0x2A)
+#define ACCEL_MMA845X_SLEEP_MASK     (0x01)
+
+/* full scale setting - register & mask */
+#define ACCEL_MMA845X_CFG_REG       (0x0E)
+#define ACCEL_MMA845X_CTRL_MASK     (0x03)
+
+/* --------------------- */
+/* -    Variables.     - */
+/* --------------------- */
+
+/*****************************************
+    Accelerometer Initialization Functions
+*****************************************/
+
+int mma845x_suspend(void *mlsl_handle,
+		    struct ext_slave_descr *slave,
+		    struct ext_slave_platform_data *pdata)
+{
+	int result;
+	unsigned char reg;
+	result =
+	    MLSLSerialRead(mlsl_handle, pdata->address,
+			   ACCEL_MMA845X_CTRL_REG1, 1, &reg);
+	ERROR_CHECK(result);
+	reg &= ~ACCEL_MMA845X_SLEEP_MASK;
+	result =
+	    MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				  ACCEL_MMA845X_CTRL_REG1, reg);
+	ERROR_CHECK(result);
+	return result;
+}
+
+
+int mma845x_resume(void *mlsl_handle,
+		   struct ext_slave_descr *slave,
+		   struct ext_slave_platform_data *pdata)
+{
+	int result = ML_SUCCESS;
+	unsigned char reg;
+
+	result = MLSLSerialRead(mlsl_handle, pdata->address,
+				ACCEL_MMA845X_CFG_REG, 1, &reg);
+	ERROR_CHECK(result);
+
+	/* data rate = 200Hz */
+
+	/* Full Scale */
+	reg &= ~ACCEL_MMA845X_CTRL_MASK;
+	if (slave->range.mantissa == 4)
+		reg |= 0x1;
+	else if (slave->range.mantissa == 8)
+		reg |= 0x2;
+	else {
+		slave->range.mantissa = 2;
+		reg |= 0x0;
+	}
+	slave->range.fraction = 0;
+
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				ACCEL_MMA845X_CFG_REG, reg);
+	ERROR_CHECK(result);
+	/* 200Hz + active mode */
+	result =
+	    MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+			    ACCEL_MMA845X_CTRL_REG1, 0x11);
+	ERROR_CHECK(result);
+
+	return result;
+}
+
+int mma845x_read(void *mlsl_handle,
+		 struct ext_slave_descr *slave,
+		 struct ext_slave_platform_data *pdata,
+		 unsigned char *data)
+{
+	int result;
+	unsigned char local_data[7]; /* Status register + 6 bytes data */
+	result = MLSLSerialRead(mlsl_handle, pdata->address,
+				slave->reg, sizeof(local_data), local_data);
+	ERROR_CHECK(result);
+	memcpy(data, &local_data[1], slave->len);
+	return result;
+}
+
+struct ext_slave_descr mma845x_descr = {
+	/*.init             = */ NULL,
+	/*.exit             = */ NULL,
+	/*.suspend          = */ mma845x_suspend,
+	/*.resume           = */ mma845x_resume,
+	/*.read             = */ mma845x_read,
+	/*.config           = */ NULL,
+	/*.get_config       = */ NULL,
+	/*.name             = */ "mma845x",
+	/*.type             = */ EXT_SLAVE_TYPE_ACCELEROMETER,
+	/*.id               = */ ACCEL_ID_MMA845X,
+	/*.reg              = */ 0x00,
+	/*.len              = */ 6,
+	/*.endian           = */ EXT_SLAVE_FS16_BIG_ENDIAN,
+	/*.range            = */ {2, 0},
+};
+
+struct ext_slave_descr *mma845x_get_slave_descr(void)
+{
+	return &mma845x_descr;
+}
+EXPORT_SYMBOL(mma845x_get_slave_descr);
+
+/**
+ *  @}
+ */
diff --git a/drivers/misc/mpu3050/compass/ak8975.c b/drivers/misc/mpu3050/compass/ak8975.c
old mode 100644
new mode 100755
index 5f020cfad2f6..b8aed30ba39b
--- a/drivers/misc/mpu3050/compass/ak8975.c
+++ b/drivers/misc/mpu3050/compass/ak8975.c
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
 
 /**
@@ -147,13 +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,
+	/*.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/compass/ami306.c b/drivers/misc/mpu3050/compass/ami306.c
new file mode 100755
index 000000000000..75ca007ef01c
--- /dev/null
+++ b/drivers/misc/mpu3050/compass/ami306.c
@@ -0,0 +1,191 @@
+/*
+ $License:
+    Copyright (C) 2010 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/>.
+  $
+ */
+
+/**
+ *  @defgroup   COMPASSDL (Motion Library - Accelerometer Driver Layer)
+ *  @brief      Provides the interface to setup and handle an accelerometers
+ *              connected to the secondary I2C interface of the gyroscope.
+ *
+ *  @{
+ *     @file   ami306.c
+ *     @brief  Magnetometer setup and handling methods for Aichi AMI306
+ *             compass.
+ */
+
+/* ------------------ */
+/* - Include Files. - */
+/* ------------------ */
+
+#ifdef __KERNEL__
+#include <linux/module.h>
+#endif
+
+#include <delay.h>
+
+#include "mpu.h"
+#include "mlsl.h"
+#include "mlos.h"
+
+#include <log.h>
+#undef MPL_LOG_TAG
+#define MPL_LOG_TAG "MPL-compass"
+
+#define AMI306_REG_DATAX (0x10)
+#define AMI306_REG_STAT1 (0x18)
+#define AMI306_REG_CNTL1 (0x1B)
+#define AMI306_REG_CNTL2 (0x1C)
+#define AMI306_REG_CNTL3 (0x1D)
+#define AMI306_REG_CNTL4_1 (0x5C)
+#define AMI306_REG_CNTL4_2 (0x5D)
+
+#define AMI306_BIT_CNTL1_PC1  (0x80)
+#define AMI306_BIT_CNTL1_ODR1 (0x10)
+#define AMI306_BIT_CNTL1_FS1  (0x02)
+
+#define AMI306_BIT_CNTL2_IEN  (0x10)
+#define AMI306_BIT_CNTL2_DREN (0x08)
+#define AMI306_BIT_CNTL2_DRP  (0x04)
+#define AMI306_BIT_CNTL3_F0RCE (0x40)
+
+int ami306_suspend(void *mlsl_handle,
+		   struct ext_slave_descr *slave,
+		   struct ext_slave_platform_data *pdata)
+{
+	int result;
+	unsigned char reg;
+	result =
+	    MLSLSerialRead(mlsl_handle, pdata->address, AMI306_REG_CNTL1,
+			   1, &reg);
+	ERROR_CHECK(result);
+
+	reg &= ~(AMI306_BIT_CNTL1_PC1|AMI306_BIT_CNTL1_FS1);
+	result =
+	    MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				  AMI306_REG_CNTL1, reg);
+	ERROR_CHECK(result);
+
+	return result;
+}
+
+int ami306_resume(void *mlsl_handle,
+		  struct ext_slave_descr *slave,
+		  struct ext_slave_platform_data *pdata)
+{
+	int result = ML_SUCCESS;
+	unsigned char regs[] = {
+		 AMI306_REG_CNTL4_1,
+		 0x7E,
+		 0xA0
+	};
+    /* Step1. Set CNTL1 reg to power model active (Write CNTL1:PC1=1) */
+	result =
+	    MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				  AMI306_REG_CNTL1,
+				  AMI306_BIT_CNTL1_PC1|AMI306_BIT_CNTL1_FS1);
+	ERROR_CHECK(result);
+
+    /* Step2. Set CNTL2 reg to DRDY active high and enabled
+       (Write CNTL2:DREN=1) */
+	result =
+	    MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				  AMI306_REG_CNTL2,
+				  AMI306_BIT_CNTL2_DREN |
+				  AMI306_BIT_CNTL2_DRP);
+	ERROR_CHECK(result);
+
+    /* Step3. Set CNTL4 reg to for measurement speed (Write CNTL4, 0xA07E) */
+	result =
+	    MLSLSerialWrite(mlsl_handle, pdata->address, DIM(regs), regs);
+	ERROR_CHECK(result);
+
+    /* Step4. skipped */
+
+    /* Step5. Set CNTL3 reg to forced measurement period
+       (Write CNTL3:FORCE=1) */
+	result =
+		MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				  AMI306_REG_CNTL3, AMI306_BIT_CNTL3_F0RCE);
+
+	return result;
+}
+
+int ami306_read(void *mlsl_handle,
+		struct ext_slave_descr *slave,
+		struct ext_slave_platform_data *pdata, unsigned char *data)
+{
+	unsigned char stat;
+	int result = ML_SUCCESS;
+	int status = ML_SUCCESS;
+
+
+	/* Measurement(x,y,z) */
+	result =
+		MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				      AMI306_REG_CNTL3,
+				      AMI306_BIT_CNTL3_F0RCE);
+	ERROR_CHECK(result);
+	udelay(500);
+
+    /* Step6. Read status reg and check if data ready (DRDY) */
+	result =
+	    MLSLSerialRead(mlsl_handle, pdata->address, AMI306_REG_STAT1,
+			   1, &stat);
+	ERROR_CHECK(result);
+
+    /* Step6. Does DRDY output the rising edge? */
+	if (stat & 0x40) {
+		result =
+		    MLSLSerialRead(mlsl_handle, pdata->address,
+				   AMI306_REG_DATAX, 6,
+				   (unsigned char *) data);
+		ERROR_CHECK(result);
+		status = ML_SUCCESS;
+	} else if (stat & 0x20)
+		status = ML_ERROR_COMPASS_DATA_OVERFLOW;
+
+	return status;
+}
+
+struct ext_slave_descr ami306_descr = {
+	/*.init             = */ NULL,
+	/*.exit             = */ NULL,
+	/*.suspend          = */ ami306_suspend,
+	/*.resume           = */ ami306_resume,
+	/*.read             = */ ami306_read,
+	/*.config           = */ NULL,
+	/*.get_config       = */ NULL,
+	/*.name             = */ "ami306",
+	/*.type             = */ EXT_SLAVE_TYPE_COMPASS,
+	/*.id               = */ COMPASS_ID_AMI306,
+	/*.reg              = */ 0x10,
+	/*.len              = */ 6,
+	/*.endian           = */ EXT_SLAVE_LITTLE_ENDIAN,
+	/*.range            = */ {5461, 3333}
+	/* For AMI305,the range field needs to be modified to {9830.4f}*/
+};
+
+struct ext_slave_descr *ami306_get_slave_descr(void)
+{
+	return &ami306_descr;
+}
+EXPORT_SYMBOL(ami306_get_slave_descr);
+
+/**
+ *  @}
+ */
diff --git a/drivers/misc/mpu3050/compass/ami30x.c b/drivers/misc/mpu3050/compass/ami30x.c
old mode 100644
new mode 100755
index 28cd5f415ca3..5e4a33efc7f2
--- a/drivers/misc/mpu3050/compass/ami30x.c
+++ b/drivers/misc/mpu3050/compass/ami30x.c
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
 
 /**
@@ -132,6 +145,7 @@ struct ext_slave_descr ami30x_descr = {
 	/*.resume           = */ ami30x_resume,
 	/*.read             = */ ami30x_read,
 	/*.config           = */ NULL,
+	/*.get_config       = */ NULL,
 	/*.name             = */ "ami30x",
 	/*.type             = */ EXT_SLAVE_TYPE_COMPASS,
 	/*.id               = */ COMPASS_ID_AMI30X,
diff --git a/drivers/misc/mpu3050/compass/hmc5883.c b/drivers/misc/mpu3050/compass/hmc5883.c
old mode 100644
new mode 100755
index 3e67d2e97dd9..02afd58fd7b7
--- a/drivers/misc/mpu3050/compass/hmc5883.c
+++ b/drivers/misc/mpu3050/compass/hmc5883.c
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
 
 /**
@@ -220,6 +233,7 @@ struct ext_slave_descr hmc5883_descr = {
 	/*.resume           = */ hmc5883_resume,
 	/*.read             = */ hmc5883_read,
 	/*.config           = */ NULL,
+	/*.get_config       = */ NULL,
 	/*.name             = */ "hmc5883",
 	/*.type             = */ EXT_SLAVE_TYPE_COMPASS,
 	/*.id               = */ COMPASS_ID_HMC5883,
diff --git a/drivers/misc/mpu3050/compass/hscdtd002b.c b/drivers/misc/mpu3050/compass/hscdtd002b.c
new file mode 100755
index 000000000000..bf26cae06d2d
--- /dev/null
+++ b/drivers/misc/mpu3050/compass/hscdtd002b.c
@@ -0,0 +1,163 @@
+/*
+ $License:
+    Copyright (C) 2010 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/>.
+  $
+ */
+
+/**
+ *  @brief      Provides the interface to setup and handle a compass
+ *              connected to the primary I2C interface of the gyroscope.
+ *
+ *  @{
+ *      @file   hscdtd002b.c
+ *      @brief  Magnetometer setup and handling methods for Alps hscdtd002b
+ *              compass.
+ */
+
+/* ------------------ */
+/* - Include Files. - */
+/* ------------------ */
+
+#ifdef __KERNEL__
+#include <linux/module.h>
+#endif
+
+#include "mpu.h"
+#include "mlsl.h"
+#include "mlos.h"
+
+#include <log.h>
+#undef MPL_LOG_TAG
+#define MPL_LOG_TAG "MPL-compass"
+
+/*----- ALPS HSCDTD002B Registers ------*/
+#define COMPASS_HSCDTD002B_STAT          (0x18)
+#define COMPASS_HSCDTD002B_CTRL1         (0x1B)
+#define COMPASS_HSCDTD002B_CTRL2         (0x1C)
+#define COMPASS_HSCDTD002B_CTRL3         (0x1D)
+#define COMPASS_HSCDTD002B_DATAX         (0x10)
+
+/* --------------------- */
+/* -    Variables.     - */
+/* --------------------- */
+
+/*****************************************
+    Compass Initialization Functions
+*****************************************/
+
+int hscdtd002b_suspend(void *mlsl_handle,
+		       struct ext_slave_descr *slave,
+		       struct ext_slave_platform_data *pdata)
+{
+	int result = ML_SUCCESS;
+
+	/* Power mode: stand-by */
+	result =
+	    MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				  COMPASS_HSCDTD002B_CTRL1, 0x00);
+	ERROR_CHECK(result);
+	MLOSSleep(1);		/* turn-off time */
+
+	return result;
+}
+
+int hscdtd002b_resume(void *mlsl_handle,
+		      struct ext_slave_descr *slave,
+		      struct ext_slave_platform_data *pdata)
+{
+	int result = ML_SUCCESS;
+
+	/* Soft reset */
+	result =
+	    MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				  COMPASS_HSCDTD002B_CTRL3, 0x80);
+	ERROR_CHECK(result);
+	/* Force state; Power mode: active */
+	result =
+	    MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				  COMPASS_HSCDTD002B_CTRL1, 0x82);
+	ERROR_CHECK(result);
+	/* Data ready enable */
+	result =
+	    MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				  COMPASS_HSCDTD002B_CTRL2, 0x08);
+	ERROR_CHECK(result);
+	MLOSSleep(1);		/* turn-on time */
+
+	return result;
+}
+
+int hscdtd002b_read(void *mlsl_handle,
+		    struct ext_slave_descr *slave,
+		    struct ext_slave_platform_data *pdata,
+		    unsigned char *data)
+{
+	unsigned char stat;
+	tMLError result = ML_SUCCESS;
+	int status = ML_SUCCESS;
+
+	/* Read status reg. to check if data is ready */
+	result =
+	    MLSLSerialRead(mlsl_handle, pdata->address,
+			   COMPASS_HSCDTD002B_STAT, 1, &stat);
+	ERROR_CHECK(result);
+	if (stat & 0x40) {
+		result =
+		    MLSLSerialRead(mlsl_handle, pdata->address,
+				   COMPASS_HSCDTD002B_DATAX, 6,
+				   (unsigned char *) data);
+		ERROR_CHECK(result);
+		status = ML_SUCCESS;
+	} else if (stat & 0x20) {
+		status = ML_ERROR_COMPASS_DATA_OVERFLOW;
+	} else {
+		status = ML_ERROR_COMPASS_DATA_NOT_READY;
+	}
+	/* trigger next measurement read */
+	result =
+		MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+			  COMPASS_HSCDTD002B_CTRL3, 0x40);
+	ERROR_CHECK(result);
+
+	return status;
+}
+
+struct ext_slave_descr hscdtd002b_descr = {
+	/*.init             = */ NULL,
+	/*.exit             = */ NULL,
+	/*.suspend          = */ hscdtd002b_suspend,
+	/*.resume           = */ hscdtd002b_resume,
+	/*.read             = */ hscdtd002b_read,
+	/*.config           = */ NULL,
+	/*.get_config       = */ NULL,
+	/*.name             = */ "hscdtd002b",
+	/*.type             = */ EXT_SLAVE_TYPE_COMPASS,
+	/*.id               = */ COMPASS_ID_HSCDTD002B,
+	/*.reg              = */ 0x10,
+	/*.len              = */ 6,
+	/*.endian           = */ EXT_SLAVE_LITTLE_ENDIAN,
+	/*.range            = */ {9830, 4000},
+};
+
+struct ext_slave_descr *hscdtd002b_get_slave_descr(void)
+{
+	return &hscdtd002b_descr;
+}
+EXPORT_SYMBOL(hscdtd002b_get_slave_descr);
+
+/**
+ *  @}
+**/
diff --git a/drivers/misc/mpu3050/compass/hscdtd004a.c b/drivers/misc/mpu3050/compass/hscdtd004a.c
new file mode 100755
index 000000000000..43fc14a23fc4
--- /dev/null
+++ b/drivers/misc/mpu3050/compass/hscdtd004a.c
@@ -0,0 +1,162 @@
+/*
+ $License:
+    Copyright (C) 2010 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/>.
+  $
+ */
+
+/**
+ *  @brief      Provides the interface to setup and handle a compass
+ *              connected to the primary I2C interface of the gyroscope.
+ *
+ *  @{
+ *      @file   hscdtd004a.c
+ *      @brief  Magnetometer setup and handling methods for Alps hscdtd004a
+ *              compass.
+ */
+
+/* ------------------ */
+/* - Include Files. - */
+/* ------------------ */
+
+#ifdef __KERNEL__
+#include <linux/module.h>
+#endif
+
+#include "mpu.h"
+#include "mlsl.h"
+#include "mlos.h"
+
+#include <log.h>
+#undef MPL_LOG_TAG
+#define MPL_LOG_TAG "MPL-compass"
+
+/*----- ALPS HSCDTD004A Registers ------*/
+#define COMPASS_HSCDTD004A_STAT          (0x18)
+#define COMPASS_HSCDTD004A_CTRL1         (0x1B)
+#define COMPASS_HSCDTD004A_CTRL2         (0x1C)
+#define COMPASS_HSCDTD004A_CTRL3         (0x1D)
+#define COMPASS_HSCDTD004A_DATAX         (0x10)
+
+/* --------------------- */
+/* -    Variables.     - */
+/* --------------------- */
+
+/*****************************************
+    Compass Initialization Functions
+*****************************************/
+
+int hscdtd004a_suspend(void *mlsl_handle,
+		       struct ext_slave_descr *slave,
+		       struct ext_slave_platform_data *pdata)
+{
+	int result = ML_SUCCESS;
+
+	/* Power mode: stand-by */
+	result =
+	    MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				  COMPASS_HSCDTD004A_CTRL1, 0x00);
+	ERROR_CHECK(result);
+	MLOSSleep(1);		/* turn-off time */
+
+	return result;
+}
+
+int hscdtd004a_resume(void *mlsl_handle,
+		      struct ext_slave_descr *slave,
+		      struct ext_slave_platform_data *pdata)
+{
+	int result = ML_SUCCESS;
+
+	/* Soft reset */
+	result =
+		MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				  COMPASS_HSCDTD004A_CTRL3, 0x80);
+	ERROR_CHECK(result);
+	/* Normal state; Power mode: active */
+	result =
+		MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				  COMPASS_HSCDTD004A_CTRL1, 0x82);
+	ERROR_CHECK(result);
+	/* Data ready enable */
+	result =
+		MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				  COMPASS_HSCDTD004A_CTRL2, 0x7C);
+	ERROR_CHECK(result);
+	MLOSSleep(1);		/* turn-on time */
+	return result;
+}
+
+int hscdtd004a_read(void *mlsl_handle,
+		    struct ext_slave_descr *slave,
+		    struct ext_slave_platform_data *pdata,
+		    unsigned char *data)
+{
+	unsigned char stat;
+	tMLError result = ML_SUCCESS;
+	int status = ML_SUCCESS;
+
+	/* Read status reg. to check if data is ready */
+	result =
+		MLSLSerialRead(mlsl_handle, pdata->address,
+			   COMPASS_HSCDTD004A_STAT, 1, &stat);
+	ERROR_CHECK(result);
+	if (stat & 0x48) {
+		result =
+			 MLSLSerialRead(mlsl_handle, pdata->address,
+				   COMPASS_HSCDTD004A_DATAX, 6,
+				   (unsigned char *) data);
+		ERROR_CHECK(result);
+		status = ML_SUCCESS;
+	} else if (stat & 0x68) {
+		status = ML_ERROR_COMPASS_DATA_OVERFLOW;
+	} else {
+		status = ML_ERROR_COMPASS_DATA_NOT_READY;
+	}
+	/* trigger next measurement read */
+	result =
+		MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+			COMPASS_HSCDTD004A_CTRL3, 0x40);
+	ERROR_CHECK(result);
+	return status;
+
+}
+
+struct ext_slave_descr hscdtd004a_descr = {
+	/*.init             = */ NULL,
+	/*.exit             = */ NULL,
+	/*.suspend          = */ hscdtd004a_suspend,
+	/*.resume           = */ hscdtd004a_resume,
+	/*.read             = */ hscdtd004a_read,
+	/*.config           = */ NULL,
+	/*.get_config       = */ NULL,
+	/*.name             = */ "hscdtd004a",
+	/*.type             = */ EXT_SLAVE_TYPE_COMPASS,
+	/*.id               = */ COMPASS_ID_HSCDTD004A,
+	/*.reg              = */ 0x10,
+	/*.len              = */ 6,
+	/*.endian           = */ EXT_SLAVE_LITTLE_ENDIAN,
+	/*.range            = */ {9830, 4000},
+};
+
+struct ext_slave_descr *hscdtd004a_get_slave_descr(void)
+{
+	return &hscdtd004a_descr;
+}
+EXPORT_SYMBOL(hscdtd004a_get_slave_descr);
+
+/**
+ *  @}
+**/
diff --git a/drivers/misc/mpu3050/compass/lsm303m.c b/drivers/misc/mpu3050/compass/lsm303m.c
old mode 100644
new mode 100755
index 082ee45be05f..871d002fd364
--- a/drivers/misc/mpu3050/compass/lsm303m.c
+++ b/drivers/misc/mpu3050/compass/lsm303m.c
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
 
 /**
@@ -210,6 +223,7 @@ struct ext_slave_descr lsm303dlhm_descr = {
 	/*.resume           = */ lsm303dlhm_resume,
 	/*.read             = */ lsm303dlhm_read,
 	/*.config           = */ NULL,
+	/*.get_config       = */ NULL,
 	/*.name             = */ "lsm303dlhm",
 	/*.type             = */ EXT_SLAVE_TYPE_COMPASS,
 	/*.id               = */ COMPASS_ID_LSM303,
diff --git a/drivers/misc/mpu3050/compass/mmc314x.c b/drivers/misc/mpu3050/compass/mmc314x.c
old mode 100644
new mode 100755
index 4bff05d0cb2f..010d7a78d149
--- a/drivers/misc/mpu3050/compass/mmc314x.c
+++ b/drivers/misc/mpu3050/compass/mmc314x.c
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
 
 /**
@@ -150,6 +163,7 @@ struct ext_slave_descr mmc314x_descr = {
 	/*.resume           = */ mmc314x_resume,
 	/*.read             = */ mmc314x_read,
 	/*.config           = */ NULL,
+	/*.get_config       = */ NULL,
 	/*.name             = */ "mmc314x",
 	/*.type             = */ EXT_SLAVE_TYPE_COMPASS,
 	/*.id               = */ COMPASS_ID_MMC314X,
diff --git a/drivers/misc/mpu3050/compass/yas529-kernel.c b/drivers/misc/mpu3050/compass/yas529-kernel.c
old mode 100644
new mode 100755
index b4be440baa14..239ab669cc1b
--- a/drivers/misc/mpu3050/compass/yas529-kernel.c
+++ b/drivers/misc/mpu3050/compass/yas529-kernel.c
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
 /**
  *  @defgroup   ACCELDL (Motion Library - Accelerometer Driver Layer)
@@ -443,6 +456,7 @@ struct ext_slave_descr yas529_descr = {
 	/*.resume           = */ yas529_resume,
 	/*.read             = */ yas529_read,
 	/*.config           = */ NULL,
+	/*.get_config       = */ NULL,
 	/*.name             = */ "yas529",
 	/*.type             = */ EXT_SLAVE_TYPE_COMPASS,
 	/*.id               = */ COMPASS_ID_YAS529,
diff --git a/drivers/misc/mpu3050/compass/yas530-kernel.c b/drivers/misc/mpu3050/compass/yas530-kernel.c
new file mode 100755
index 000000000000..f6dbb5691eb6
--- /dev/null
+++ b/drivers/misc/mpu3050/compass/yas530-kernel.c
@@ -0,0 +1,163 @@
+/*
+ $License:
+    Copyright (C) 2010 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/>.
+  $License:
+    Copyright (C) 2010 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/>.
+  $
+  */
+ /**
+  *  @defgroup   ACCELDL (Motion Library - Accelerometer Driver Layer)
+  *  @brief      Provides the interface to setup and handle an accelerometers
+  *              connected to the secondary I2C interface of the gyroscope.
+  *
+  *  @{
+  *      @file   yas530.c
+  *      @brief  Magnetometer setup and handling methods for Yamaha yas530
+  *              compass.
+  */
+
+ /* ------------------ */
+ /* - Include Files. - */
+ /* ------------------ */
+
+#include "mpu.h"
+#include "mltypes.h"
+
+#include "mlsl.h"
+#include "mlos.h"
+
+#ifdef __KERNEL__
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <i2c.h>
+#endif
+
+#include <log.h>
+#undef MPL_LOG_TAG
+#define MPL_LOG_TAG "MPL-yas530:"
+
+
+extern int geomagnetic_api_resume(void);
+extern int geomagnetic_api_suspend(void);
+extern int geomagnetic_api_read(int *xyz, int *raw, int *xy1y2, int *accuracy);
+
+ /*****************************************
+     Compass Initialization Functions
+ *****************************************/
+
+static int
+yas530_suspend
+(
+   void *mlsl_handle,
+   struct ext_slave_descr *slave,
+   struct ext_slave_platform_data *pdata
+)
+{
+  int result = ML_SUCCESS;
+
+  geomagnetic_api_suspend();
+
+  return result;
+}
+
+
+static int
+yas530_resume
+(
+   void *mlsl_handle,
+   struct ext_slave_descr *slave,
+   struct ext_slave_platform_data *pdata
+)
+{
+  geomagnetic_api_resume();
+  return ML_SUCCESS;
+}
+
+
+static int
+yas530_read
+(
+     void *mlsl_handle,
+     struct ext_slave_descr *slave,
+     struct ext_slave_platform_data *pdata,
+     unsigned char *data
+)
+{
+  int xyz[3];
+  int raw[3];
+  short rawfixed[3];
+  int xy1y2[3];
+  int accuracy;
+
+  geomagnetic_api_read(xyz, raw, xy1y2, &accuracy);
+
+  rawfixed[0] = (short) (xyz[0]/100);
+  rawfixed[1] = (short) (xyz[1]/100);
+  rawfixed[2] = (short) (xyz[2]/100);
+
+  data[0] = rawfixed[0] >> 8;
+  data[1] = rawfixed[0] & 0xFF;
+  data[2] = rawfixed[1] >> 8;
+  data[3] = rawfixed[1] & 0xFF;
+  data[4] = rawfixed[2] >> 8;
+  data[5] = rawfixed[2] & 0xFF;
+
+  return ML_SUCCESS;
+}
+
+
+
+struct ext_slave_descr yas530_descr = {
+     /*.init          = */ NULL,
+     /*.exit          = */ NULL,
+     /*.suspend          = */ yas530_suspend,
+     /*.resume           = */ yas530_resume,
+     /*.read             = */ yas530_read,
+     /*.config           = */ NULL,
+     /*.name             = */ "yas530",
+     /*.type             = */ EXT_SLAVE_TYPE_COMPASS,
+     /*.id               = */ COMPASS_ID_YAS530,
+     /*.reg              = */ 0x06,
+     /*.len              = */ 6,
+     /*.endian           = */ EXT_SLAVE_BIG_ENDIAN,
+     /*.range            = */ {3276, 8001},
+};
+
+struct ext_slave_descr *yas530_get_slave_descr(void)
+{
+     return &yas530_descr;
+}
+
+#ifdef __KERNEL__
+ EXPORT_SYMBOL(yas530_get_slave_descr);
+#endif
+
+ /**
+  *  @}
+ **/
diff --git a/drivers/misc/mpu3050/compass/yas530.c b/drivers/misc/mpu3050/compass/yas530.c
new file mode 100755
index 000000000000..9fc9acbde65b
--- /dev/null
+++ b/drivers/misc/mpu3050/compass/yas530.c
@@ -0,0 +1,406 @@
+/*
+ $License:
+    Copyright (C) 2010 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/>.
+  $
+ */
+/**
+ *  @defgroup   ACCELDL (Motion Library - Accelerometer Driver Layer)
+ *  @brief      Provides the interface to setup and handle an accelerometers
+ *              connected to the secondary I2C interface of the gyroscope.
+ *
+ *  @{
+ *      @file   yas530.c
+ *      @brief  Magnetometer setup and handling methods for Yamaha yas530
+ *              compass.
+ */
+
+/* ------------------ */
+/* - Include Files. - */
+/* ------------------ */
+
+#ifdef __KERNEL__
+#include <linux/module.h>
+#endif
+
+#include "mpu.h"
+#include "mlsl.h"
+#include "mlos.h"
+
+#include <log.h>
+#undef MPL_LOG_TAG
+#define MPL_LOG_TAG "MPL-compass"
+
+/*----- YAMAHA YAS529 Registers ------*/
+#define YAS530_REGADDR_DEVICE_ID          (0x80)
+#define YAS530_REGADDR_ACTUATE_INIT_COIL  (0x81)
+#define YAS530_REGADDR_MEASURE_COMMAND    (0x82)
+#define YAS530_REGADDR_CONFIG             (0x83)
+#define YAS530_REGADDR_MEASURE_INTERVAL   (0x84)
+#define YAS530_REGADDR_OFFSET_X           (0x85)
+#define YAS530_REGADDR_OFFSET_Y1          (0x86)
+#define YAS530_REGADDR_OFFSET_Y2          (0x87)
+#define YAS530_REGADDR_TEST1              (0x88)
+#define YAS530_REGADDR_TEST2              (0x89)
+#define YAS530_REGADDR_CAL                (0x90)
+#define YAS530_REGADDR_MEASURE_DATA       (0xb0)
+
+
+/* --------------------- */
+/* -    Variables.     - */
+/* --------------------- */
+static int Cx, Cy1, Cy2;
+static int /*a1, */a2, a3, a4, a5, a6, a7, a8, a9;
+static int k;
+
+static char dx, dy1, dy2;
+static char d2, d3, d4, d5, d6, d7, d8, d9, d0;
+static char dck;
+
+/*****************************************
+    Accelerometer Initialization Functions
+*****************************************/
+
+int set_hardware_offset(void *mlsl_handle,
+		   struct ext_slave_descr *slave,
+		   struct ext_slave_platform_data *pdata,
+		   char offset_x, char offset_y1, char offset_y2)
+{
+	char data;
+	int result = ML_SUCCESS;
+
+	data = offset_x & 0x3f;
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+		YAS530_REGADDR_OFFSET_X, data);
+	ERROR_CHECK(result);
+
+	data = offset_y1 & 0x3f;
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+		YAS530_REGADDR_OFFSET_Y1, data);
+	ERROR_CHECK(result);
+
+	data = offset_y2 & 0x3f;
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+		YAS530_REGADDR_OFFSET_Y2, data);
+	ERROR_CHECK(result);
+
+	return result;
+}
+
+int set_measure_command(void *mlsl_handle,
+		   struct ext_slave_descr *slave,
+		   struct ext_slave_platform_data *pdata,
+		   int ldtc, int fors, int dlymes)
+{
+	int result = ML_SUCCESS;
+
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+		YAS530_REGADDR_MEASURE_COMMAND, 0x01);
+	ERROR_CHECK(result);
+
+	return result;
+}
+
+int measure_normal(void *mlsl_handle,
+		   struct ext_slave_descr *slave,
+		   struct ext_slave_platform_data *pdata,
+		   int *busy, unsigned short *t,
+		   unsigned short *x, unsigned short *y1, unsigned short *y2)
+{
+	unsigned char data[8];
+	unsigned short b, to, xo, y1o, y2o;
+	int result;
+
+	result = set_measure_command(mlsl_handle, slave, pdata, 0, 0, 0);
+	MLOSSleep(2);
+
+	result = MLSLSerialRead(mlsl_handle, pdata->address,
+		YAS530_REGADDR_MEASURE_DATA, 8, data);
+	ERROR_CHECK(result);
+	MLOSSleep(2);
+
+	b = (data[0]>>7) & 0x01;
+	to = ((data[0]<<2) & 0x1fc) | ((data[1]>>6) & 0x03);
+	xo = ((data[2]<<5) & 0xfe0) | ((data[3]>>3) & 0x1f);
+	y1o = ((data[4]<<5) & 0xfe0) | ((data[5]>>3) & 0x1f);
+	y2o = ((data[6]<<5) & 0xfe0) | ((data[7]>>3) & 0x1f);
+
+	*busy = b;
+	*t = to;
+	*x = xo;
+	*y1 = y1o;
+	*y2 = y2o;
+
+	return result;
+}
+
+int check_offset(void *mlsl_handle,
+		   struct ext_slave_descr *slave,
+		   struct ext_slave_platform_data *pdata,
+		   char offset_x, char offset_y1, char offset_y2,
+		   int *flag_x, int *flag_y1, int *flag_y2)
+{
+	int result;
+	int busy;
+	short t, x, y1, y2;
+
+	result = set_hardware_offset(mlsl_handle, slave, pdata,
+		offset_x, offset_y1, offset_y2);
+	ERROR_CHECK(result);
+
+	result = measure_normal(mlsl_handle, slave, pdata,
+		&busy, &t, &x, &y1, &y2);
+	ERROR_CHECK(result);
+
+	*flag_x = 0;
+	*flag_y1 = 0;
+	*flag_y2 = 0;
+
+	if (x > 2048)
+		*flag_x = 1;
+	if (y1 > 2048)
+		*flag_y1 = 1;
+	if (y2 > 2048)
+		*flag_y2 = 1;
+	if (x < 2048)
+		*flag_x = -1;
+	if (y1 < 2048)
+		*flag_y1 = -1;
+	if (y2 < 2048)
+		*flag_y2 = -1;
+
+	return result;
+}
+
+int measure_and_set_offset(void *mlsl_handle,
+		   struct ext_slave_descr *slave,
+		   struct ext_slave_platform_data *pdata,
+		   char *offset)
+{
+	int i;
+	int result = ML_SUCCESS;
+	char offset_x = 0, offset_y1 = 0, offset_y2 = 0;
+	int flag_x = 0, flag_y1 = 0, flag_y2 = 0;
+	static const int correct[5] = {16, 8, 4, 2, 1};
+
+	for (i = 0; i < 5; i++) {
+		result = check_offset(mlsl_handle, slave, pdata,
+			offset_x, offset_y1, offset_y2,
+			&flag_x, &flag_y1, &flag_y2);
+		ERROR_CHECK(result);
+
+		if (flag_x)
+			offset_x += flag_x * correct[i];
+		if (flag_y1)
+			offset_y1 += flag_y1 * correct[i];
+		if (flag_y2)
+			offset_y2 += flag_y2 * correct[i];
+	}
+
+	result = set_hardware_offset(mlsl_handle, slave, pdata,
+		offset_x, offset_y1, offset_y2);
+	ERROR_CHECK(result);
+
+	offset[0] = offset_x;
+	offset[1] = offset_y1;
+	offset[2] = offset_y2;
+
+	return result;
+}
+
+void coordinate_conversion(short x, short y1, short y2, short t,
+						  int *xo, int *yo, int *zo)
+{
+	int sx, sy1, sy2, sy, sz;
+	int hx, hy, hz;
+
+	sx  = x - (Cx  * t) / 100;
+	sy1 = y1 - (Cy1 * t) / 100;
+	sy2 = y2 - (Cy2 * t) / 100;
+
+	sy = sy1 - sy2;
+	sz = -sy1 - sy2;
+
+	hx = k * ((100 * sx + a2 * sy + a3 * sz) / 10);
+	hy = k * ((a4 * sx + a5 * sy + a6 * sz) / 10);
+	hz = k * ((a7 * sx + a8 * sy + a9 * sz) / 10);
+
+	*xo = hx;
+	*yo = hy;
+	*zo = hz;
+}
+
+int yas530_suspend(void *mlsl_handle,
+		   struct ext_slave_descr *slave,
+		   struct ext_slave_platform_data *pdata)
+{
+	int result = ML_SUCCESS;
+
+	return result;
+}
+
+int yas530_resume(void *mlsl_handle,
+		  struct ext_slave_descr *slave,
+		  struct ext_slave_platform_data *pdata)
+{
+	int result = ML_SUCCESS;
+
+	unsigned char dummyData = 0x00;
+	char offset[3] = {0, 0, 0};
+	unsigned char data[16];
+	unsigned char read_reg[1];
+
+	/* =============================================== */
+
+	/* Step 1 - Test register initialization */
+	dummyData = 0x00;
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+		YAS530_REGADDR_TEST1, dummyData);
+	ERROR_CHECK(result);
+
+	result =
+	    MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				  YAS530_REGADDR_TEST2, dummyData);
+	ERROR_CHECK(result);
+
+	/* Device ID read  */
+	result = MLSLSerialRead(mlsl_handle, pdata->address,
+		YAS530_REGADDR_DEVICE_ID, 1, read_reg);
+
+	/*Step 2 Read the CAL register */
+	/* CAL data read */
+	result = MLSLSerialRead(mlsl_handle, pdata->address,
+		YAS530_REGADDR_CAL, 16, data);
+	ERROR_CHECK(result);
+	/* CAL data Second Read */
+	result = MLSLSerialRead(mlsl_handle, pdata->address,
+		YAS530_REGADDR_CAL, 16, data);
+	ERROR_CHECK(result);
+
+	/*Cal data */
+	dx = data[0];
+	dy1 = data[1];
+	dy2 = data[2];
+	d2 = (data[3]>>2) & 0x03f;
+	d3 = ((data[3]<<2) & 0x0c) | ((data[4]>>6) & 0x03);
+	d4 = data[4] & 0x3f;
+	d5 = (data[5]>>2) & 0x3f;
+	d6 = ((data[5]<<4) & 0x30) | ((data[6]>>4) & 0x0f);
+	d7 = ((data[6]<<3) & 0x78) | ((data[7]>>5) & 0x07);
+	d8 = ((data[7]<<1) & 0x3e) | ((data[8]>>7) & 0x01);
+	d9 = ((data[8]<<1) & 0xfe) | ((data[9]>>7) & 0x01);
+	d0 = (data[9]>>2) & 0x1f;
+	dck = ((data[9]<<1) & 0x06) | ((data[10]>>7) & 0x01);
+
+
+	/*Correction Data */
+	Cx = dx * 6 - 768;
+	Cy1 = dy1 * 6 - 768;
+	Cy2 = dy2 * 6 - 768;
+	a2 = d2 - 32;
+	a3 = d3 - 8;
+	a4 = d4 - 32;
+	a5 = d5 + 38;
+	a6 = d6 - 32;
+	a7 = d7 - 64;
+	a8 = d8 - 32;
+	a9 = d9;
+	k = d0 + 10;
+
+	/*Obtain the [49:47] bits */
+	dck &= 0x07;
+
+	/*Step 3 : Storing the CONFIG with the CLK value */
+	dummyData = 0x00 | (dck << 2);
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+		YAS530_REGADDR_CONFIG, dummyData);
+	ERROR_CHECK(result);
+
+	/*Step 4 : Set Acquisition Interval Register */
+	dummyData = 0x00;
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+		YAS530_REGADDR_MEASURE_INTERVAL, dummyData);
+	ERROR_CHECK(result);
+
+	/*Step 5 : Reset Coil */
+	dummyData = 0x00;
+	result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+		YAS530_REGADDR_ACTUATE_INIT_COIL, dummyData);
+	ERROR_CHECK(result);
+
+	/* Offset Measurement and Set*/
+	result = measure_and_set_offset(mlsl_handle, slave, pdata, offset);
+	ERROR_CHECK(result);
+
+	return result;
+}
+
+int yas530_read(void *mlsl_handle,
+		struct ext_slave_descr *slave,
+		struct ext_slave_platform_data *pdata, unsigned char *data)
+{
+	int result = ML_SUCCESS;
+
+	int busy;
+	short t, x, y1, y2;
+	int xyz[3];
+	short rawfixed[3];
+
+	result = measure_normal(mlsl_handle, slave, pdata,
+			&busy, &t, &x, &y1, &y2);
+	ERROR_CHECK(result);
+
+	coordinate_conversion(x, y1, y2, t, &xyz[0], &xyz[1], &xyz[2]);
+
+	rawfixed[0] = (short) (xyz[0]/100);
+	rawfixed[1] = (short) (xyz[1]/100);
+	rawfixed[2] = (short) (xyz[2]/100);
+
+	data[0] = rawfixed[0]>>8;
+	data[1] = rawfixed[0] & 0xFF;
+	data[2] = rawfixed[1]>>8;
+	data[3] = rawfixed[1] & 0xFF;
+	data[4] = rawfixed[2]>>8;
+	data[5] = rawfixed[2] & 0xFF;
+
+	return result;
+}
+
+struct ext_slave_descr yas530_descr = {
+	/*.init             = */ NULL,
+	/*.exit             = */ NULL,
+	/*.suspend          = */ yas530_suspend,
+	/*.resume           = */ yas530_resume,
+	/*.read             = */ yas530_read,
+	/*.config           = */ NULL,
+	/*.get_config       = */ NULL,
+	/*.name             = */ "yas530",
+	/*.type             = */ EXT_SLAVE_TYPE_COMPASS,
+	/*.id               = */ COMPASS_ID_YAS530,
+	/*.reg              = */ 0x06,
+	/*.len              = */ 6,
+	/*.endian           = */ EXT_SLAVE_BIG_ENDIAN,
+	/*.range            = */ {3276, 8001},
+};
+
+struct ext_slave_descr *yas530_get_slave_descr(void)
+{
+	return &yas530_descr;
+}
+EXPORT_SYMBOL(yas530_get_slave_descr);
+
+/**
+ *  @}
+**/
diff --git a/drivers/misc/mpu3050/log.h b/drivers/misc/mpu3050/log.h
old mode 100644
new mode 100755
index ceee28526265..f2f9ea7ece8e
--- 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
old mode 100644
new mode 100755
index 220103bb2b0b..9cc4cf690386
--- a/drivers/misc/mpu3050/mldl_cfg.c
+++ b/drivers/misc/mpu3050/mldl_cfg.c
@@ -1,13 +1,21 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
-/*******************************************************************************
- *
- * $Id: mldl_cfg.c 4635 2011-01-27 07:49:49Z nroyer $
- *
- ******************************************************************************/
 
 /**
  *  @addtogroup MLDL
@@ -289,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;
@@ -298,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;
 
@@ -322,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   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.
  *
- *  @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.
+ *  @pre    Must be called after MLSerialOpen().
+ *  @note   Typically called before MLDmpOpen().
  *
- *  @param[in]  enable
- *                  1 to enable, 0 to disable
+ *  @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.
-**/
+ *  @return ML_SUCCESS if successfull, a non-zero error code otherwise.
+ */
 static int MLDLSetLevelShifterBit(struct mldl_cfg *pdata,
 				  void *mlsl_handle,
 				  unsigned char enable)
@@ -350,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;
@@ -551,6 +567,7 @@ static int MLDLPowerMgmtMPU(struct mldl_cfg *pdata,
 
 	/* Reset if requested */
 	if (reset) {
+		MPL_LOGV("Reset MPU3050\n");
 		result = MLSLSerialWriteSingle(mlsl_handle, pdata->addr,
 					MPUREG_PWR_MGM, b | BIT_H_RESET);
 		ERROR_CHECK(result);
@@ -1114,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;
@@ -1294,7 +1312,10 @@ int mpu3050_close(struct mldl_cfg *mldl_cfg,
 /**
  *  @brief  resume the MPU3050 device and all the other sensor
  *          devices from their low power state.
- *  @param  mlsl_handle
+ *
+ *  @param  mldl_cfg
+ *              pointer to the configuration structure
+ *  @param  gyro_handle
  *              the main file handle to the MPU3050 device.
  *  @param  accel_handle
  *              an handle to the accelerometer device, if sitting
@@ -1311,6 +1332,10 @@ int mpu3050_close(struct mldl_cfg *mldl_cfg,
  *              onto a separate bus. Can match mlsl_handle if
  *              the pressure sensor device operates on the same
  *              primary bus of MPU.
+ *  @param  resume_gyro
+ *              whether resuming the gyroscope device is
+ *              actually needed (if the device supports low power
+ *              mode of some sort).
  *  @param  resume_accel
  *              whether resuming the accelerometer device is
  *              actually needed (if the device supports low power
@@ -1337,7 +1362,7 @@ int mpu3050_resume(struct mldl_cfg *mldl_cfg,
 {
 	int result = ML_SUCCESS;
 
-#ifdef CONFIG_SENSORS_MPU_DEBUG
+#ifdef CONFIG_MPU_SENSORS_DEBUG
 	mpu_print_cfg(mldl_cfg);
 #endif
 
@@ -1367,15 +1392,15 @@ int mpu3050_resume(struct mldl_cfg *mldl_cfg,
 						 &mldl_cfg->pdata->accel);
 		ERROR_CHECK(result);
 		mldl_cfg->accel_is_suspended = FALSE;
+	}
 
-		if (!mldl_cfg->gyro_is_suspended &&
-		    EXT_SLAVE_BUS_SECONDARY == mldl_cfg->pdata->accel.bus) {
-			result = mpu_set_slave(mldl_cfg,
-					       gyro_handle,
-					       mldl_cfg->accel,
-					       &mldl_cfg->pdata->accel);
-			ERROR_CHECK(result);
-		}
+	if (!mldl_cfg->gyro_is_suspended && !mldl_cfg->accel_is_suspended &&
+		EXT_SLAVE_BUS_SECONDARY == mldl_cfg->pdata->accel.bus) {
+		result = mpu_set_slave(mldl_cfg,
+				gyro_handle,
+				mldl_cfg->accel,
+				&mldl_cfg->pdata->accel);
+		ERROR_CHECK(result);
 	}
 
 	if (resume_compass && mldl_cfg->compass_is_suspended) {
@@ -1390,15 +1415,15 @@ int mpu3050_resume(struct mldl_cfg *mldl_cfg,
 						   compass);
 		ERROR_CHECK(result);
 		mldl_cfg->compass_is_suspended = FALSE;
+	}
 
-		if (!mldl_cfg->gyro_is_suspended &&
-		    EXT_SLAVE_BUS_SECONDARY == mldl_cfg->pdata->compass.bus) {
-			result = mpu_set_slave(mldl_cfg,
-					       gyro_handle,
-					       mldl_cfg->compass,
-					       &mldl_cfg->pdata->compass);
-			ERROR_CHECK(result);
-		}
+	if (!mldl_cfg->gyro_is_suspended && !mldl_cfg->compass_is_suspended &&
+		EXT_SLAVE_BUS_SECONDARY == mldl_cfg->pdata->compass.bus) {
+		result = mpu_set_slave(mldl_cfg,
+				gyro_handle,
+				mldl_cfg->compass,
+				&mldl_cfg->pdata->compass);
+		ERROR_CHECK(result);
 	}
 
 	if (resume_pressure && mldl_cfg->pressure_is_suspended) {
@@ -1412,17 +1437,18 @@ int mpu3050_resume(struct mldl_cfg *mldl_cfg,
 						    &mldl_cfg->pdata->
 						    pressure);
 		ERROR_CHECK(result);
-		if (!mldl_cfg->gyro_is_suspended &&
-		    EXT_SLAVE_BUS_SECONDARY == mldl_cfg->pdata->pressure.bus) {
-			result = mpu_set_slave(mldl_cfg,
-					       gyro_handle,
-					       mldl_cfg->pressure,
-					       &mldl_cfg->pdata->pressure);
-			ERROR_CHECK(result);
-		}
 		mldl_cfg->pressure_is_suspended = FALSE;
 	}
 
+	if (!mldl_cfg->gyro_is_suspended && !mldl_cfg->pressure_is_suspended &&
+		EXT_SLAVE_BUS_SECONDARY == mldl_cfg->pdata->pressure.bus) {
+		result = mpu_set_slave(mldl_cfg,
+				gyro_handle,
+				mldl_cfg->pressure,
+				&mldl_cfg->pdata->pressure);
+		ERROR_CHECK(result);
+	}
+
 	/* Now start */
 	if (resume_gyro) {
 		result = dmp_start(mldl_cfg, gyro_handle);
@@ -1432,7 +1458,6 @@ int mpu3050_resume(struct mldl_cfg *mldl_cfg,
 	return result;
 }
 
-
 /**
  *  @brief  suspend the MPU3050 device and all the other sensor
  *          devices into their low power state.
@@ -1481,13 +1506,14 @@ int mpu3050_suspend(struct mldl_cfg *mldl_cfg,
 
 	if (suspend_gyro && !mldl_cfg->gyro_is_suspended) {
 #ifdef M_HW
+		return ML_SUCCESS;
 		/* This puts the bus into bypass mode */
 		result = MLDLSetI2CBypass(mldl_cfg, gyro_handle, 1);
 		ERROR_CHECK(result);
 		result = mpu60xx_pwr_mgmt(mldl_cfg, gyro_handle, 0, SLEEP);
 #else
 		result = MLDLPowerMgmtMPU(mldl_cfg, gyro_handle,
-					  0, SLEEP, 0, 0, 0);
+					0, SLEEP, 0, 0, 0);
 #endif
 		ERROR_CHECK(result);
 	}
@@ -1545,6 +1571,10 @@ int mpu3050_suspend(struct mldl_cfg *mldl_cfg,
 /**
  *  @brief  read raw sensor data from the accelerometer device
  *          in use.
+ *  @param  mldl_cfg
+ *              A pointer to the struct mldl_cfg data structure.
+ *  @param  accel_handle
+ *              The handle to the device the accelerometer is connected to.
  *  @param  data
  *              a buffer to store the raw sensor data.
  *  @return ML_SUCCESS if successful, a non-zero error code otherwise.
@@ -1553,10 +1583,14 @@ int mpu3050_read_accel(struct mldl_cfg *mldl_cfg,
 		       void *accel_handle, unsigned char *data)
 {
 	if (NULL != mldl_cfg->accel && NULL != mldl_cfg->accel->read)
-		return mldl_cfg->accel->read(accel_handle,
-					     mldl_cfg->accel,
-					     &mldl_cfg->pdata->accel,
-					     data);
+		if ((EXT_SLAVE_BUS_SECONDARY == mldl_cfg->pdata->accel.bus)
+			&& (!mldl_cfg->gyro_is_bypassed))
+			return ML_ERROR_FEATURE_NOT_ENABLED;
+		else
+			return mldl_cfg->accel->read(accel_handle,
+						     mldl_cfg->accel,
+						     &mldl_cfg->pdata->accel,
+						     data);
 	else
 		return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
 }
@@ -1564,6 +1598,10 @@ int mpu3050_read_accel(struct mldl_cfg *mldl_cfg,
 /**
  *  @brief  read raw sensor data from the compass device
  *          in use.
+ *  @param  mldl_cfg
+ *              A pointer to the struct mldl_cfg data structure.
+ *  @param  compass_handle
+ *              The handle to the device the compass is connected to.
  *  @param  data
  *              a buffer to store the raw sensor data.
  *  @return ML_SUCCESS if successful, a non-zero error code otherwise.
@@ -1572,10 +1610,14 @@ int mpu3050_read_compass(struct mldl_cfg *mldl_cfg,
 			 void *compass_handle, unsigned char *data)
 {
 	if (NULL != mldl_cfg->compass && NULL != mldl_cfg->compass->read)
-		return mldl_cfg->compass->read(compass_handle,
-					       mldl_cfg->compass,
-					       &mldl_cfg->pdata->compass,
-					       data);
+		if ((EXT_SLAVE_BUS_SECONDARY == mldl_cfg->pdata->compass.bus)
+			&& (!mldl_cfg->gyro_is_bypassed))
+			return ML_ERROR_FEATURE_NOT_ENABLED;
+		else
+			return mldl_cfg->compass->read(compass_handle,
+						mldl_cfg->compass,
+						&mldl_cfg->pdata->compass,
+						data);
 	else
 		return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
 }
@@ -1583,6 +1625,10 @@ int mpu3050_read_compass(struct mldl_cfg *mldl_cfg,
 /**
  *  @brief  read raw sensor data from the pressure device
  *          in use.
+ *  @param  mldl_cfg
+ *              A pointer to the struct mldl_cfg data structure.
+ *  @param  pressure_handle
+ *              The handle to the device the pressure sensor is connected to.
  *  @param  data
  *              a buffer to store the raw sensor data.
  *  @return ML_SUCCESS if successful, a non-zero error code otherwise.
@@ -1591,10 +1637,15 @@ int mpu3050_read_pressure(struct mldl_cfg *mldl_cfg,
 			 void *pressure_handle, unsigned char *data)
 {
 	if (NULL != mldl_cfg->pressure && NULL != mldl_cfg->pressure->read)
-		return mldl_cfg->pressure->read(pressure_handle,
-						mldl_cfg->pressure,
-						&mldl_cfg->pdata->pressure,
-						data);
+		if ((EXT_SLAVE_BUS_SECONDARY == mldl_cfg->pdata->pressure.bus)
+			&& (!mldl_cfg->gyro_is_bypassed))
+			return ML_ERROR_FEATURE_NOT_ENABLED;
+		else
+			return mldl_cfg->pressure->read(
+				pressure_handle,
+				mldl_cfg->pressure,
+				&mldl_cfg->pdata->pressure,
+				data);
 	else
 		return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
 }
@@ -1640,6 +1691,48 @@ int mpu3050_config_pressure(struct mldl_cfg *mldl_cfg,
 		return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
 }
 
+int mpu3050_get_config_accel(struct mldl_cfg *mldl_cfg,
+			void *accel_handle,
+			struct ext_slave_config *data)
+{
+	if (NULL != mldl_cfg->accel && NULL != mldl_cfg->accel->get_config)
+		return mldl_cfg->accel->get_config(accel_handle,
+						mldl_cfg->accel,
+						&mldl_cfg->pdata->accel,
+						data);
+	else
+		return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
+
+}
+
+int mpu3050_get_config_compass(struct mldl_cfg *mldl_cfg,
+			void *compass_handle,
+			struct ext_slave_config *data)
+{
+	if (NULL != mldl_cfg->compass && NULL != mldl_cfg->compass->get_config)
+		return mldl_cfg->compass->get_config(compass_handle,
+						mldl_cfg->compass,
+						&mldl_cfg->pdata->compass,
+						data);
+	else
+		return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
+
+}
+
+int mpu3050_get_config_pressure(struct mldl_cfg *mldl_cfg,
+				void *pressure_handle,
+				struct ext_slave_config *data)
+{
+	if (NULL != mldl_cfg->pressure &&
+	    NULL != mldl_cfg->pressure->get_config)
+		return mldl_cfg->pressure->get_config(pressure_handle,
+						mldl_cfg->pressure,
+						&mldl_cfg->pdata->pressure,
+						data);
+	else
+		return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
+}
+
 
 /**
  *@}
diff --git a/drivers/misc/mpu3050/mldl_cfg.h b/drivers/misc/mpu3050/mldl_cfg.h
old mode 100644
new mode 100755
index 91f349ef2748..ad6a211c5d86
--- a/drivers/misc/mpu3050/mldl_cfg.h
+++ b/drivers/misc/mpu3050/mldl_cfg.h
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
 
 /**
@@ -80,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;
@@ -167,6 +181,16 @@ int mpu3050_config_pressure(struct mldl_cfg *mldl_cfg,
 			    void *pressure_handle,
 			    struct ext_slave_config *data);
 
+int mpu3050_get_config_accel(struct mldl_cfg *mldl_cfg,
+			     void *accel_handle,
+			     struct ext_slave_config *data);
+int mpu3050_get_config_compass(struct mldl_cfg *mldl_cfg,
+			       void *compass_handle,
+			       struct ext_slave_config *data);
+int mpu3050_get_config_pressure(struct mldl_cfg *mldl_cfg,
+				void *pressure_handle,
+				struct ext_slave_config *data);
+
 
 #endif				/* __MLDL_CFG_H__ */
 
diff --git a/drivers/misc/mpu3050/mlos-kernel.c b/drivers/misc/mpu3050/mlos-kernel.c
old mode 100644
new mode 100755
index 091c0a60b784..ced9ba4f6f3c
--- a/drivers/misc/mpu3050/mlos-kernel.c
+++ b/drivers/misc/mpu3050/mlos-kernel.c
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
 /**
  * @defgroup
diff --git a/drivers/misc/mpu3050/mlos.h b/drivers/misc/mpu3050/mlos.h
old mode 100644
new mode 100755
index e65dd62da4d3..4ebb86c9fa5c
--- a/drivers/misc/mpu3050/mlos.h
+++ b/drivers/misc/mpu3050/mlos.h
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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 _MLOS_H
diff --git a/drivers/misc/mpu3050/mlsl-kernel.c b/drivers/misc/mpu3050/mlsl-kernel.c
old mode 100644
new mode 100755
index d1bcf8815561..cb1605131cbf
--- a/drivers/misc/mpu3050/mlsl-kernel.c
+++ b/drivers/misc/mpu3050/mlsl-kernel.c
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
 
 #include "mlsl.h"
@@ -83,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;
@@ -174,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/mlsl.h b/drivers/misc/mpu3050/mlsl.h
old mode 100644
new mode 100755
index 4f012937d877..76f69c77ba98
--- a/drivers/misc/mpu3050/mlsl.h
+++ b/drivers/misc/mpu3050/mlsl.h
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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 __MSSL_H__
diff --git a/drivers/misc/mpu3050/mltypes.h b/drivers/misc/mpu3050/mltypes.h
old mode 100644
new mode 100755
index 3521c00974bd..d0b27fa89e78
--- a/drivers/misc/mpu3050/mltypes.h
+++ b/drivers/misc/mpu3050/mltypes.h
@@ -1,13 +1,21 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
-/******************************************************************************
- *
- * $Id: mltypes.h 4598 2011-01-25 19:33:13Z prao $
- *
- *****************************************************************************/
 
 /**
  *  @defgroup MLERROR
@@ -81,11 +89,12 @@
 ---------------------------*/
 
 /**
- * @struct tMLError The MPL Error Code return type.
+ *  @struct tMLError mltypes.h "mltypes"
+ *  @brief  The MPL Error Code return type.
  *
- * @code
+ *  @code
  *      typedef unsigned char tMLError;
- * @endcode
+ *  @endcode
  */
 typedef unsigned char tMLError;
 
@@ -127,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; }
@@ -200,6 +209,12 @@ typedef int_fast8_t bool;
 #define ML_ERROR_CALIBRATION_LEN        (77)
 #define ML_ERROR_CALIBRATION_CHECKSUM   (78)
 
+/* Accel errors */
+#define ML_ERROR_ACCEL_DATA_OVERFLOW    (79)
+#define ML_ERROR_ACCEL_DATA_UNDERFLOW   (80)
+#define ML_ERROR_ACCEL_DATA_NOT_READY   (81)
+#define ML_ERROR_ACCEL_DATA_ERROR       (82)
+
 /* For Linux coding compliance */
 #ifndef __KERNEL__
 #define EXPORT_SYMBOL(x)
diff --git a/drivers/misc/mpu3050/mpu-dev.c b/drivers/misc/mpu3050/mpu-dev.c
old mode 100644
new mode 100755
index 26bcebcff4e1..e84b63f97faa
--- a/drivers/misc/mpu3050/mpu-dev.c
+++ b/drivers/misc/mpu3050/mpu-dev.c
@@ -1,9 +1,5 @@
 /*
-    mpu-dev.c - mpu3050 char device interface
-
-    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>
+ $License:
     Copyright (C) 2010 InvenSense Corporation, All Rights Reserved.
 
     This program is free software; you can redistribute it and/or modify
@@ -18,8 +14,7 @@
 
     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 +31,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,44 +62,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;
-struct i2c_msg1 {
-	__u16 addr;	/* slave address			*/
-	__u16 flags;
-#define I2C_M_TEN		0x0010	/* this is a ten bit chip address */
-#define I2C_M_RD		0x0001	/* read data, from slave to master */
-#define I2C_M_NOSTART		0x4000	/* if I2C_FUNC_PROTOCOL_MANGLING */
-#define I2C_M_REV_DIR_ADDR	0x2000	/* if I2C_FUNC_PROTOCOL_MANGLING */
-#define I2C_M_IGNORE_NAK	0x1000	/* if I2C_FUNC_PROTOCOL_MANGLING */
-#define I2C_M_NO_RD_ACK		0x0800	/* if I2C_FUNC_PROTOCOL_MANGLING */
-#define I2C_M_RECV_LEN		0x0400	/* length will be first received byte */
-	__u16 len;		/* msg length				*/
-	__u8 *buf;		/* pointer to msg data			*/
-};
-struct i2c_rdwr_ioctl_data1 {
-	struct i2c_msg1 __user *msgs;	/* pointers to i2c_msgs */
-	__u32 nmsgs;			/* number of i2c_msgs */
-};
 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;
@@ -112,7 +162,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;
 }
 
@@ -129,136 +179,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_data1 rdwr_arg;
-	struct i2c_msg1 *rdwr_pa;
-	struct i2c_msg *msgs;
-	u8 __user **data_ptrs;
-	int i, res;
-
-	if (copy_from_user(&rdwr_arg,
-			   (struct i2c_rdwr_ioctl_data1 __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;
-	msgs = (struct i2c_msg *)kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg), GFP_KERNEL);
-	rdwr_pa = (struct i2c_msg1 *)
-	    kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg1), GFP_KERNEL);
-	if (!rdwr_pa)
-		return -ENOMEM;
+	if (!mpu->event && (!(file->f_flags & O_NONBLOCK)))
+		wait_event_interruptible(mpu->mpu_event_wait, mpu->event);
 
-	if (copy_from_user(rdwr_pa, rdwr_arg.msgs,
-			   rdwr_arg.nmsgs * sizeof(struct i2c_msg1))) {
-		kfree(rdwr_pa);
-		return -EFAULT;
-	}
+	if (!mpu->event || NULL == buf
+		|| count < sizeof(mpu->mpu_pm_event) + sizeof(unsigned long))
+		return 0;
 
-	data_ptrs =
-	    kmalloc(rdwr_arg.nmsgs * sizeof(u8 __user *), GFP_KERNEL);
-	if (data_ptrs == NULL) {
-		kfree(rdwr_pa);
-		return -ENOMEM;
+	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;
 	}
 
-	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;
-		}
-		msgs[i].buf = rdwr_pa[i].buf;
-		msgs[i].len = rdwr_pa[i].len;
-		msgs[i].flags = rdwr_pa[i].flags;
-		msgs[i].addr = rdwr_pa[i].addr;
-
-		msgs[i].scl_rate = 400 * 1000;
-	}
-	if (res < 0) {
-		int j;
-		for (j = 0; j < i; ++j)
-			kfree(rdwr_pa[j].buf);
-		kfree(data_ptrs);
-		kfree(rdwr_pa);
-		kfree(msgs);
-		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, msgs,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);
-	kfree(msgs);
-	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;
-	kfree(tmp);
-	return ret;
+	poll_wait(file, &mpu->mpu_event_wait, poll);
+	if (mpu->event)
+		mask |= POLLIN | POLLRDNORM;
+	return mask;
 }
 
 static int
@@ -403,51 +397,245 @@ mpu_ioctl_get_mpu_config(struct i2c_client *client, unsigned long arg)
 	retval =
 	    copy_from_user(local_mldl_cfg, (struct mldl_cfg __user *) arg,
 			   sizeof(struct mldl_cfg));
-	if (retval)
+	if (retval) {
+		dev_err(&this_client->adapter->dev,
+			"%s|%s:%d: EFAULT on arg\n",
+			__FILE__, __func__, __LINE__);
+		retval = -EFAULT;
 		goto out;
+	}
 
 	/* Fill in the accel, compass, pressure and pdata pointers */
 	if (mldl_cfg->accel) {
 		retval = copy_to_user((void __user *)local_mldl_cfg->accel,
 				      mldl_cfg->accel,
 				      sizeof(*mldl_cfg->accel));
-		if (retval)
+		if (retval) {
+			dev_err(&this_client->adapter->dev,
+				"%s|%s:%d: EFAULT on accel\n",
+				__FILE__, __func__, __LINE__);
+			retval = -EFAULT;
 			goto out;
+		}
 	}
 
 	if (mldl_cfg->compass) {
 		retval = copy_to_user((void __user *)local_mldl_cfg->compass,
 				      mldl_cfg->compass,
 				      sizeof(*mldl_cfg->compass));
-		if (retval)
+		if (retval) {
+			dev_err(&this_client->adapter->dev,
+				"%s|%s:%d: EFAULT on compass\n",
+				__FILE__, __func__, __LINE__);
+			retval = -EFAULT;
 			goto out;
+		}
 	}
 
 	if (mldl_cfg->pressure) {
-		retval = copy_to_user(local_mldl_cfg->pressure,
+		retval = copy_to_user((void __user *)local_mldl_cfg->pressure,
 				      mldl_cfg->pressure,
 				      sizeof(*mldl_cfg->pressure));
-		if (retval)
+		if (retval) {
+			dev_err(&this_client->adapter->dev,
+				"%s|%s:%d: EFAULT on pressure\n",
+				__FILE__, __func__, __LINE__);
+			retval = -EFAULT;
 			goto out;
+		}
 	}
 
 	if (mldl_cfg->pdata) {
 		retval = copy_to_user((void __user *)local_mldl_cfg->pdata,
 				      mldl_cfg->pdata,
 				      sizeof(*mldl_cfg->pdata));
-		if (retval)
+		if (retval) {
+			dev_err(&this_client->adapter->dev,
+				"%s|%s:%d: EFAULT on pdata\n",
+				__FILE__, __func__, __LINE__);
+			retval = -EFAULT;
 			goto out;
+		}
 	}
 
 	/* Do not modify the accel, compass, pressure and pdata pointers */
 	retval = copy_to_user((struct mldl_cfg __user *) arg,
 			      mldl_cfg, offsetof(struct mldl_cfg, accel));
 
+	if (retval)
+		retval = -EFAULT;
 out:
 	kfree(local_mldl_cfg);
 	return retval;
 }
 
+/**
+ * Pass a requested slave configuration to the slave sensor
+ *
+ * @param adapter the adaptor to use to communicate with the slave
+ * @param mldl_cfg the mldl configuration structuer
+ * @param slave pointer to the slave descriptor
+ * @param usr_config The configuration to pass to the slave sensor
+ *
+ * @return 0 or non-zero error code
+ */
+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;
+	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;
+		}
+		config.data = data;
+	}
+	retval = slave->config(adapter, slave, pdata, &config);
+	kfree(config.data);
+	return retval;
+}
+
+/**
+ * Get a requested slave configuration from the slave sensor
+ *
+ * @param adapter the adaptor to use to communicate with the slave
+ * @param mldl_cfg the mldl configuration structuer
+ * @param slave pointer to the slave descriptor
+ * @param usr_config The configuration for the slave to fill out
+ *
+ * @return 0 or non-zero error code
+ */
+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;
+	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) {
+			retval = -EFAULT;
+			kfree(data);
+			return retval;
+		}
+		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;
+}
+
 /* ioctl - I/O control */
 static long mpu_ioctl(struct file *file,
 		      unsigned int cmd, unsigned long arg)
@@ -468,233 +656,69 @@ 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));
-		break;
-	case MPU_SET_RAM:
-		retval = copy_from_user(mldl_cfg->ram,
-					(unsigned char __user *) arg,
-					sizeof(mldl_cfg->ram));
-		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));
-		break;
-	case MPU_GET_RAM:
-		retval = copy_to_user((unsigned char __user *) arg,
-				      mldl_cfg->ram,
-				      sizeof(mldl_cfg->ram));
+	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:
-	{
-		if ((mldl_cfg->accel) && (mldl_cfg->accel->config)) {
-			struct ext_slave_config config;
-			retval = copy_from_user(
-				&config,
-				(struct ext_slave_config *)arg,
-				sizeof(config));
-			if (retval)
-				break;
-
-			if (config.len && config.data) {
-				int *data;
-				data = kzalloc(config.len, GFP_KERNEL);
-				if (!data) {
-					retval = ML_ERROR_MEMORY_EXAUSTED;
-					break;
-				}
-				retval = copy_from_user(data,
-							(void *)config.data,
-							config.len);
-				if (retval) {
-					kfree(data);
-					break;
-				}
-				config.data = data;
-			}
-			retval = mldl_cfg->accel->config(
-				accel_adapter,
+		retval = slave_config(accel_adapter, mldl_cfg,
 				mldl_cfg->accel,
 				&mldl_cfg->pdata->accel,
-				&config);
-			kfree(config.data);
-		}
+				(struct ext_slave_config __user *) arg);
 		break;
-	}
 	case MPU_CONFIG_COMPASS:
-	{
-		if ((mldl_cfg->compass) && (mldl_cfg->compass->config)) {
-			struct ext_slave_config config;
-			retval = copy_from_user(
-				&config,
-				(struct ext_slave_config *)arg,
-				sizeof(config));
-			if (retval)
-				break;
-
-			if (config.len && config.data) {
-				int *data;
-				data = kzalloc(config.len, GFP_KERNEL);
-				if (!data) {
-					retval = ML_ERROR_MEMORY_EXAUSTED;
-					break;
-				}
-				retval = copy_from_user(data,
-							(void *)config.data,
-							config.len);
-				if (retval) {
-					kfree(data);
-					break;
-				}
-				config.data = data;
-			}
-			retval = mldl_cfg->compass->config(
-				compass_adapter,
+		retval = slave_config(compass_adapter, mldl_cfg,
 				mldl_cfg->compass,
 				&mldl_cfg->pdata->compass,
-				&config);
-			kfree(config.data);
-		}
+				(struct ext_slave_config __user *) arg);
 		break;
-	}
 	case MPU_CONFIG_PRESSURE:
-	{
-		if ((mldl_cfg->pressure) && (mldl_cfg->pressure->config)) {
-			struct ext_slave_config config;
-			retval = copy_from_user(
-				&config,
-				(struct ext_slave_config *)arg,
-				sizeof(config));
-			if (retval)
-				break;
-
-			if (config.len && config.data) {
-				int *data;
-				data = kzalloc(config.len, GFP_KERNEL);
-				if (!data) {
-					retval = ML_ERROR_MEMORY_EXAUSTED;
-					break;
-				}
-				retval = copy_from_user(data,
-							(void *)config.data,
-							config.len);
-				if (retval) {
-					kfree(data);
-					break;
-				}
-				config.data = data;
-			}
-			retval = mldl_cfg->pressure->config(
-				pressure_adapter,
+		retval = slave_config(pressure_adapter, mldl_cfg,
 				mldl_cfg->pressure,
 				&mldl_cfg->pdata->pressure,
-				&config);
-			kfree(config.data);
-		}
+				(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_READ_MEMORY:
-	case MPU_WRITE_MEMORY:
 	case MPU_SUSPEND:
 	{
 		unsigned long sensors;
@@ -729,55 +753,59 @@ static long mpu_ioctl(struct file *file,
 					sensors & ML_THREE_AXIS_PRESSURE);
 	}
 	break;
-	case MPU_READ_ACCEL:
-		{
-			unsigned char data[6];
-			retval =
-			    mpu3050_read_accel(mldl_cfg, client->adapter,
-					       data);
-			if (ML_SUCCESS == retval)
-				retval =
-				    copy_to_user((unsigned char __user *) arg,
-						 data, sizeof(data));
-		}
+	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];
+		retval = mpu3050_read_accel(mldl_cfg, client->adapter,
+					    data);
+		if ((ML_SUCCESS == retval) &&
+		    (copy_to_user((unsigned char __user *) arg,
+			    data, sizeof(data))))
+			retval = -EFAULT;
+	}
+	break;
 	case MPU_READ_COMPASS:
-		{
-			unsigned char data[6];
-			struct i2c_adapter *compass_adapt =
-			    i2c_get_adapter(mldl_cfg->pdata->compass.
-					    adapt_num);
-			retval =
-			    mpu3050_read_compass(mldl_cfg, compass_adapt,
+	{
+		unsigned char data[6];
+		struct i2c_adapter *compass_adapt =
+			i2c_get_adapter(mldl_cfg->pdata->compass.
+					adapt_num);
+		retval = mpu3050_read_compass(mldl_cfg, compass_adapt,
 						 data);
-			if (ML_SUCCESS == retval)
-				retval =
-				    copy_to_user((unsigned char *) arg,
-						 data, sizeof(data));
-		}
-		break;
+		if ((ML_SUCCESS == retval) &&
+			(copy_to_user((unsigned char *) arg,
+				data, sizeof(data))))
+			retval = -EFAULT;
+	}
+	break;
 	case MPU_READ_PRESSURE:
-		{
-			unsigned char data[3];
-			struct i2c_adapter *pressure_adapt =
-			    i2c_get_adapter(mldl_cfg->pdata->pressure.
-					    adapt_num);
-			retval =
-			    mpu3050_read_pressure(mldl_cfg, pressure_adapt,
-						 data);
-			if (ML_SUCCESS == retval)
-				retval =
-				    copy_to_user((unsigned char __user *) arg,
-						 data, sizeof(data));
-		}
-		break;
+	{
+		unsigned char data[3];
+		struct i2c_adapter *pressure_adapt =
+			i2c_get_adapter(mldl_cfg->pdata->pressure.
+					adapt_num);
+		retval =
+			mpu3050_read_pressure(mldl_cfg, pressure_adapt,
+					data);
+		if ((ML_SUCCESS == retval) &&
+		    (copy_to_user((unsigned char __user *) arg,
+			    data, sizeof(data))))
+			retval = -EFAULT;
+	}
+	break;
 	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;
 }
 
@@ -801,10 +829,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)
@@ -825,8 +856,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,
@@ -836,8 +868,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);
@@ -859,9 +892,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__);
 }
 
@@ -880,7 +915,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);
@@ -893,6 +929,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;
 }
 
@@ -911,7 +948,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,
@@ -922,8 +960,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;
 }
 
@@ -931,6 +970,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
@@ -981,15 +1022,30 @@ 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;
 
-#if defined(CONFIG_SENSORS_MPU3050_MODULE) || \
-    defined(CONFIG_SENSORS_MPU6000_MODULE)
+#if defined(CONFIG_MPU_SENSORS_MPU3050_MODULE) || \
+    defined(CONFIG_MPU_SENSORS_MPU6000_MODULE)
 		pdata->accel.get_slave_descr = get_accel_slave_descr;
 		pdata->compass.get_slave_descr = get_compass_slave_descr;
 		pdata->pressure.get_slave_descr = get_pressure_slave_descr;
@@ -1013,7 +1069,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 {
@@ -1100,8 +1156,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);
 	}
 
 
@@ -1220,20 +1276,17 @@ static struct i2c_driver mpu3050_driver = {
 
 static int __init mpu_init(void)
 {
-	printk("xxm -> enter mpu_init\n");
 	int res = i2c_add_driver(&mpu3050_driver);
-	pid = 0;
-	printk(KERN_DEBUG "%s\n", __func__);
-	printk("xxm-> end mpu_init\n");
-	if (res){
-		dev_err(&this_client->adapter->dev, "%s\n",
+	pr_debug("%s\n", __func__);
+	if (res)
+		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/mpu-i2c.c b/drivers/misc/mpu3050/mpu-i2c.c
old mode 100644
new mode 100755
index 3c7e3efcc472..b1298d313abf
--- a/drivers/misc/mpu3050/mpu-i2c.c
+++ b/drivers/misc/mpu3050/mpu-i2c.c
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
 
 /**
@@ -17,7 +30,6 @@
 #include <linux/i2c.h>
 #include "mpu.h"
 
-#define MPU_SPEED 	400 * 1000
 int sensor_i2c_write(struct i2c_adapter *i2c_adap,
 		     unsigned char address,
 		     unsigned int len, unsigned char const *data)
@@ -32,7 +44,6 @@ int sensor_i2c_write(struct i2c_adapter *i2c_adap,
 	msgs[0].flags = 0;	/* write */
 	msgs[0].buf = (unsigned char *) data;
 	msgs[0].len = len;
-	msgs[0].scl_rate = MPU_SPEED;
 
 	res = i2c_transfer(i2c_adap, msgs, 1);
 	if (res < 1)
@@ -51,6 +62,7 @@ int sensor_i2c_write_register(struct i2c_adapter *i2c_adap,
 	data[1] = value;
 	return sensor_i2c_write(i2c_adap, address, 2, data);
 }
+
 int sensor_i2c_read(struct i2c_adapter *i2c_adap,
 		    unsigned char address,
 		    unsigned char reg,
@@ -66,13 +78,11 @@ int sensor_i2c_read(struct i2c_adapter *i2c_adap,
 	msgs[0].flags = 0;	/* write */
 	msgs[0].buf = &reg;
 	msgs[0].len = 1;
-	msgs[0].scl_rate = MPU_SPEED;
 
 	msgs[1].addr = address;
 	msgs[1].flags = I2C_M_RD;
 	msgs[1].buf = data;
 	msgs[1].len = len;
-	msgs[1].scl_rate = MPU_SPEED;
 
 	res = i2c_transfer(i2c_adap, msgs, 2);
 	if (res < 2)
@@ -109,25 +119,21 @@ int mpu_memory_read(struct i2c_adapter *i2c_adap,
 	msgs[0].flags = 0;
 	msgs[0].buf = bank;
 	msgs[0].len = sizeof(bank);
-	msgs[0].scl_rate = MPU_SPEED;
 
 	msgs[1].addr = mpu_addr;
 	msgs[1].flags = 0;
 	msgs[1].buf = addr;
 	msgs[1].len = sizeof(addr);
-	msgs[1].scl_rate = MPU_SPEED;
 
 	msgs[2].addr = mpu_addr;
 	msgs[2].flags = 0;
 	msgs[2].buf = &buf;
 	msgs[2].len = 1;
-	msgs[2].scl_rate = MPU_SPEED;
 
 	msgs[3].addr = mpu_addr;
 	msgs[3].flags = I2C_M_RD;
 	msgs[3].buf = data;
 	msgs[3].len = len;
-	msgs[3].scl_rate = MPU_SPEED;
 
 	ret = i2c_transfer(i2c_adap, msgs, 4);
 	if (ret != 4)
@@ -167,20 +173,17 @@ int mpu_memory_write(struct i2c_adapter *i2c_adap,
 	msgs[0].flags = 0;
 	msgs[0].buf = bank;
 	msgs[0].len = sizeof(bank);
-	msgs[0].scl_rate = MPU_SPEED;
 
 	msgs[1].addr = mpu_addr;
 	msgs[1].flags = 0;
 	msgs[1].buf = addr;
 	msgs[1].len = sizeof(addr);
-	msgs[1].scl_rate = MPU_SPEED;
 
 	msgs[2].addr = mpu_addr;
 	msgs[2].flags = 0;
 	msgs[2].buf = (unsigned char *) buf;
 	msgs[2].len = len + 1;
-	msgs[2].scl_rate = MPU_SPEED;
-	
+
 	ret = i2c_transfer(i2c_adap, msgs, 3);
 	if (ret != 3)
 		return ret;
diff --git a/drivers/misc/mpu3050/mpu-i2c.h b/drivers/misc/mpu3050/mpu-i2c.h
old mode 100644
new mode 100755
index 7d58027977b2..0bbc8c64594e
--- a/drivers/misc/mpu3050/mpu-i2c.h
+++ b/drivers/misc/mpu3050/mpu-i2c.h
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
 /**
  * @defgroup
diff --git a/drivers/misc/mpu3050/mpuirq.c b/drivers/misc/mpu3050/mpuirq.c
old mode 100644
new mode 100755
index 01ab307ec9a7..ce1ad409cbf4
--- a/drivers/misc/mpu3050/mpuirq.c
+++ b/drivers/misc/mpu3050/mpuirq.c
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
 #include <linux/interrupt.h>
 #include <linux/module.h>
@@ -16,8 +29,6 @@
 #include <linux/i2c-dev.h>
 #include <linux/workqueue.h>
 #include <linux/poll.h>
-#include <linux/gpio.h>
-#include <mach/gpio.h>
 
 #include <linux/errno.h>
 #include <linux/fs.h>
@@ -50,7 +61,7 @@ struct mpuirq_dev_data {
 };
 
 static struct mpuirq_dev_data mpuirq_dev_data;
-static struct irq_data mpuirq_data;
+static struct mpuirq_data mpuirq_data;
 static char *interface = MPUIRQ_NAME;
 
 static void mpu_accel_data_work_fcn(struct work_struct *work);
@@ -61,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;
 }
 
@@ -81,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,
@@ -195,23 +205,20 @@ static irqreturn_t mpuirq_handler(int irq, void *dev_id)
 
 	/* wake up (unblock) for reading data from userspace */
 	/* and ignore first interrupt generated in module init */
-	if (mpuirq_data.interruptcount > 1) {
-		mpuirq_dev_data.data_ready = 1;
-
-		do_gettimeofday(&irqtime);
-		mpuirq_data.irqtime = (((long long) irqtime.tv_sec) << 32);
-		mpuirq_data.irqtime += irqtime.tv_usec;
-
-		if ((mpuirq_dev_data.accel_divider >= 0) &&
-		    (0 ==
-		     (mycount % (mpuirq_dev_data.accel_divider + 1)))) {
-			schedule_work((struct work_struct
-				       *) (&mpuirq_dev_data));
-		}
+	mpuirq_dev_data.data_ready = 1;
+
+	do_gettimeofday(&irqtime);
+	mpuirq_data.irqtime = (((long long) irqtime.tv_sec) << 32);
+	mpuirq_data.irqtime += irqtime.tv_usec;
 
-		wake_up_interruptible(&mpuirq_wait);
+	if ((mpuirq_dev_data.accel_divider >= 0) &&
+		(0 == (mycount % (mpuirq_dev_data.accel_divider + 1)))) {
+		schedule_work((struct work_struct
+				*) (&mpuirq_dev_data));
 	}
 
+	wake_up_interruptible(&mpuirq_wait);
+
 	return IRQ_HANDLED;
 
 }
@@ -267,28 +274,14 @@ int mpuirq_init(struct i2c_client *mpu_client)
 			flags = IRQF_TRIGGER_FALLING;
 		else
 			flags = IRQF_TRIGGER_RISING;
-		/* mpu irq register xxm*/
-		res = gpio_request(mpuirq_dev_data.irq, "mpu3050_int");
-		if(res)
-		{
-			printk("failed to request mpu3050_int GPIO %d\n",			
-						gpio_to_irq(mpuirq_dev_data.irq));
-			return res;
-		}
-		res = gpio_direction_input(mpuirq_dev_data.irq);
-		if(res)
-		{
-			printk("failed to set mpu3050_int GPIO input\n");
-			return res;
-		}
-		printk("gpio_to_irq(mpuirq_dev_data.irq) == %d \r\n",	
-				gpio_to_irq(mpuirq_dev_data.irq));
-		res =request_irq(gpio_to_irq(mpuirq_dev_data.irq), mpuirq_handler, flags,
-							interface,&mpuirq_dev_data.irq);
+
+		res =
+		    request_irq(mpuirq_dev_data.irq, mpuirq_handler, flags,
+				interface, &mpuirq_dev_data.irq);
 		if (res) {
 			dev_err(&mpu_client->adapter->dev,
-				"myirqtest: cannot register IRQ %d,return value is %d\n",
-				gpio_to_irq(mpuirq_dev_data.irq),res);
+				"myirqtest: cannot register IRQ %d\n",
+				mpuirq_dev_data.irq);
 		} else {
 			res = misc_register(&mpuirq_device);
 			if (res < 0) {
diff --git a/drivers/misc/mpu3050/mpuirq.h b/drivers/misc/mpu3050/mpuirq.h
old mode 100644
new mode 100755
index 374cd337b239..a71c79c75e8c
--- a/drivers/misc/mpu3050/mpuirq.h
+++ b/drivers/misc/mpu3050/mpuirq.h
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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 __MPUIRQ__
@@ -9,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
old mode 100644
new mode 100755
index e66da3b3edeb..a3c7bfec4b4b
--- a/drivers/misc/mpu3050/slaveirq.c
+++ b/drivers/misc/mpu3050/slaveirq.c
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
 #include <linux/interrupt.h>
 #include <linux/module.h>
@@ -15,8 +28,6 @@
 #include <linux/i2c.h>
 #include <linux/i2c-dev.h>
 #include <linux/poll.h>
-#include <linux/gpio.h>
-#include <mach/gpio.h>
 
 #include <linux/errno.h>
 #include <linux/fs.h>
@@ -25,19 +36,20 @@
 #include <linux/wait.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
+#include <linux/wait.h>
+#include <linux/slab.h>
 
 #include "mpu.h"
 #include "slaveirq.h"
 #include "mldl_cfg.h"
 #include "mpu-i2c.h"
-#include <linux/wait.h>
-#include <linux/delay.h>
+
 /* function which gets slave data and sends it to SLAVE */
 
 struct slaveirq_dev_data {
 	struct miscdevice dev;
 	struct i2c_client *slave_client;
-	struct irq_data data;
+	struct mpuirq_data data;
 	wait_queue_head_t slaveirq_wait;
 	int irq;
 	int pid;
@@ -77,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);
@@ -100,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 =
@@ -156,17 +171,14 @@ 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 */
-	if (data->data.interruptcount > 1) {
-		data->data_ready = 1;
+	data->data_ready = 1;
 
-		do_gettimeofday(&irqtime);
-		data->data.irqtime = (((long long) irqtime.tv_sec) << 32);
-		data->data.irqtime += irqtime.tv_usec;
-		data->data.data_type |= 1;
+	do_gettimeofday(&irqtime);
+	data->data.irqtime = (((long long) irqtime.tv_sec) << 32);
+	data->data.irqtime += irqtime.tv_usec;
+	data->data.data_type |= 1;
 
-		wake_up_interruptible(&data->slaveirq_wait);
-	}
+	wake_up_interruptible(&data->slaveirq_wait);
 
 	return IRQ_HANDLED;
 
@@ -213,24 +225,10 @@ int slaveirq_init(struct i2c_adapter *slave_adapter,
 	data->data_ready = 0;
 	data->timeout = 0;
 
-	/* mpu irq register xxm*/
-	res = gpio_request(data->irq, name);
-	if(res)
-	{
-		printk("failed to request %s GPIO %d\n",			
-					name,data->irq);
-		return res;
-	}
-	res = gpio_direction_input(data->irq);
-	if(res)
-	{
-		printk("failed to set %s GPIO input\n",name);
-		return res;
-	}
-	printk("%s registing irq  == %d \r\n",name,gpio_to_irq(data->irq));
-	//gpio_pull_updown(data->irq, GPIOPullUp);
-	//gpio_set_value(data->irq,GPIO_HIGH);
-	res = request_irq(gpio_to_irq(data->irq), slaveirq_handler, IRQF_TRIGGER_FALLING,data->dev.name, data);
+	init_waitqueue_head(&data->slaveirq_wait);
+
+	res = request_irq(data->irq, slaveirq_handler, IRQF_TRIGGER_RISING,
+			  data->dev.name, data);
 
 	if (res) {
 		dev_err(&slave_adapter->dev,
@@ -247,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
old mode 100644
new mode 100755
index ac53f1e9225a..b4e1115f1b0a
--- a/drivers/misc/mpu3050/slaveirq.h
+++ b/drivers/misc/mpu3050/slaveirq.h
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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 __SLAVEIRQ__
@@ -14,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
new file mode 100755
index 000000000000..41c3ac981016
--- /dev/null
+++ b/drivers/misc/mpu3050/timerirq.c
@@ -0,0 +1,299 @@
+/*
+ $License:
+    Copyright (C) 2010 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/>.
+  $
+ */
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/stat.h>
+#include <linux/signal.h>
+#include <linux/miscdevice.h>
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
+#include <linux/poll.h>
+
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include <linux/timer.h>
+#include <linux/slab.h>
+
+#include "mpu.h"
+#include "mltypes.h"
+#include "timerirq.h"
+
+/* function which gets timer data and sends it to TIMER */
+struct timerirq_data {
+	int pid;
+	int data_ready;
+	int run;
+	int timeout;
+	unsigned long period;
+	struct mpuirq_data data;
+	struct completion timer_done;
+	wait_queue_head_t timerirq_wait;
+	struct timer_list timer;
+	struct miscdevice *dev;
+};
+
+static struct miscdevice *timerirq_dev_data;
+
+static void timerirq_handler(unsigned long arg)
+{
+	struct timerirq_data *data = (struct timerirq_data *)arg;
+	struct timeval irqtime;
+
+	data->data.interruptcount++;
+
+	data->data_ready = 1;
+
+	do_gettimeofday(&irqtime);
+	data->data.irqtime = (((long long) irqtime.tv_sec) << 32);
+	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)
+		mod_timer(&data->timer,
+			jiffies + msecs_to_jiffies(data->period));
+	else
+		complete(&data->timer_done);
+}
+
+static int start_timerirq(struct timerirq_data *data)
+{
+	dev_dbg(data->dev->this_device,
+		"%s current->pid %d\n", __func__, current->pid);
+
+	/* Timer already running... success */
+	if (data->run)
+		return 0;
+
+	/* Don't allow a period of 0 since this would fire constantly */
+	if (!data->period)
+		return -EINVAL;
+
+	data->run = TRUE;
+	data->data_ready = FALSE;
+
+	init_completion(&data->timer_done);
+	setup_timer(&data->timer, timerirq_handler, (unsigned long)data);
+
+	return mod_timer(&data->timer,
+			jiffies + msecs_to_jiffies(data->period));
+}
+
+static int stop_timerirq(struct timerirq_data *data)
+{
+	dev_dbg(data->dev->this_device,
+		"%s current->pid %lx\n", __func__, (unsigned long)data);
+
+	if (data->run) {
+		data->run = FALSE;
+		mod_timer(&data->timer, jiffies + 1);
+		wait_for_completion(&data->timer_done);
+	}
+	return 0;
+}
+
+/* The following depends on patch fa1f68db6ca7ebb6fc4487ac215bffba06c01c28
+ * drivers: misc: pass miscdevice pointer via file private data
+ */
+static int timerirq_open(struct inode *inode, struct file *file)
+{
+	/* Device node is availabe in the file->private_data, this is
+	 * exactly what we want so we leave it there */
+	struct miscdevice *dev_data = file->private_data;
+	struct timerirq_data *data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->dev = dev_data;
+	file->private_data = data;
+	data->pid = current->pid;
+	init_waitqueue_head(&data->timerirq_wait);
+
+	dev_dbg(data->dev->this_device,
+		"%s current->pid %d\n", __func__, current->pid);
+	return 0;
+}
+
+static int timerirq_release(struct inode *inode, struct file *file)
+{
+	struct timerirq_data *data = file->private_data;
+	dev_dbg(data->dev->this_device, "timerirq_release\n");
+	if (data->run)
+		stop_timerirq(data);
+	kfree(data);
+	return 0;
+}
+
+/* read function called when from /dev/timerirq is read */
+static ssize_t timerirq_read(struct file *file,
+			   char *buf, size_t count, loff_t *ppos)
+{
+	int len, err;
+	struct timerirq_data *data = file->private_data;
+
+	if (!data->data_ready &&
+		data->timeout &&
+		!(file->f_flags & O_NONBLOCK)) {
+		wait_event_interruptible_timeout(data->timerirq_wait,
+						 data->data_ready,
+						 data->timeout);
+	}
+
+	if (data->data_ready && NULL != buf
+	    && count >= sizeof(data->data)) {
+		err = copy_to_user(buf, &data->data, sizeof(data->data));
+		data->data.data_type = 0;
+	} else {
+		return 0;
+	}
+	if (err != 0) {
+		dev_err(data->dev->this_device,
+			"Copy to user returned %d\n", err);
+		return -EFAULT;
+	}
+	data->data_ready = 0;
+	len = sizeof(data->data);
+	return len;
+}
+
+static unsigned int timerirq_poll(struct file *file,
+				struct poll_table_struct *poll)
+{
+	int mask = 0;
+	struct timerirq_data *data = file->private_data;
+
+	poll_wait(file, &data->timerirq_wait, poll);
+	if (data->data_ready)
+		mask |= POLLIN | POLLRDNORM;
+	return mask;
+}
+
+/* ioctl - I/O control */
+static long timerirq_ioctl(struct file *file,
+			   unsigned int cmd, unsigned long arg)
+{
+	int retval = 0;
+	int tmp;
+	struct timerirq_data *data = file->private_data;
+
+	dev_dbg(data->dev->this_device,
+		"%s current->pid %d, %d, %ld\n",
+		__func__, current->pid, cmd, arg);
+
+	if (!data)
+		return -EFAULT;
+
+	switch (cmd) {
+	case TIMERIRQ_SET_TIMEOUT:
+		data->timeout = arg;
+		break;
+	case TIMERIRQ_GET_INTERRUPT_CNT:
+		tmp = data->data.interruptcount - 1;
+		if (data->data.interruptcount > 1)
+			data->data.interruptcount = 1;
+
+		if (copy_to_user((int *) arg, &tmp, sizeof(int)))
+			return -EFAULT;
+		break;
+	case TIMERIRQ_START:
+		data->period = arg;
+		retval = start_timerirq(data);
+		break;
+	case TIMERIRQ_STOP:
+		retval = stop_timerirq(data);
+		break;
+	default:
+		retval = -EINVAL;
+	}
+	return retval;
+}
+
+/* define which file operations are supported */
+static const struct file_operations timerirq_fops = {
+	.owner = THIS_MODULE,
+	.read = timerirq_read,
+	.poll = timerirq_poll,
+
+#if HAVE_COMPAT_IOCTL
+	.compat_ioctl = timerirq_ioctl,
+#endif
+#if HAVE_UNLOCKED_IOCTL
+	.unlocked_ioctl = timerirq_ioctl,
+#endif
+	.open = timerirq_open,
+	.release = timerirq_release,
+};
+
+static int __init timerirq_init(void)
+{
+
+	int res;
+	static struct miscdevice *data;
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+	timerirq_dev_data = data;
+	data->minor = MISC_DYNAMIC_MINOR;
+	data->name = "timerirq";
+	data->fops = &timerirq_fops;
+
+	res = misc_register(data);
+	if (res < 0) {
+		dev_err(data->this_device,
+			"misc_register returned %d\n",
+			res);
+		return res;
+	}
+
+	return res;
+}
+module_init(timerirq_init);
+
+static void __exit timerirq_exit(void)
+{
+	struct miscdevice *data = timerirq_dev_data;
+
+	dev_info(data->this_device, "Unregistering %s\n",
+		 data->name);
+
+	misc_deregister(data);
+	kfree(data);
+
+	timerirq_dev_data = NULL;
+}
+module_exit(timerirq_exit);
+
+MODULE_AUTHOR("Invensense Corporation");
+MODULE_DESCRIPTION("Timer IRQ device driver.");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("timerirq");
diff --git a/drivers/misc/mpu3050/timerirq.h b/drivers/misc/mpu3050/timerirq.h
new file mode 100755
index 000000000000..ec2c1e29f080
--- /dev/null
+++ b/drivers/misc/mpu3050/timerirq.h
@@ -0,0 +1,30 @@
+/*
+ $License:
+    Copyright (C) 2010 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 __TIMERIRQ__
+#define __TIMERIRQ__
+
+#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
old mode 100644
new mode 100755
index da1c6bc1aea0..d66d9e76b9af
--- a/include/linux/mpu.h
+++ b/include/linux/mpu.h
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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_
@@ -9,6 +22,9 @@
 
 #ifdef __KERNEL__
 #include <linux/types.h>
+#include <linux/ioctl.h>
+#elif defined LINUX
+#include <sys/ioctl.h>
 #endif
 
 #ifdef M_HW
@@ -22,94 +38,110 @@
 #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_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;
 };
 
-struct irq_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;
 	int data_type;
 	int data_size;
 	void *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_NUM_CONFIG_KEYS,
+	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_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_ACCEL
  * MPU_CONFIG_COMPASS
  * MPU_CONFIG_PRESSURE
+ * MPU_GET_CONFIG_ACCEL
+ * MPU_GET_CONFIG_COMPASS
+ * MPU_GET_CONFIG_PRESSURE
  */
 struct ext_slave_config {
 	int key;
 	int len;
+	int apply;
 	void *data;
 };
 
@@ -126,22 +158,26 @@ enum ext_slave_id {
 
 	ACCEL_ID_LIS331,
 	ACCEL_ID_LSM303,
+	ACCEL_ID_LIS3DH,
 	ACCEL_ID_KXSD9,
 	ACCEL_ID_KXTF9,
 	ACCEL_ID_BMA150,
 	ACCEL_ID_BMA222,
 	ACCEL_ID_ADI346,
 	ACCEL_ID_MMA8450,
-	ACCEL_ID_MMA8451,
+	ACCEL_ID_MMA845X,
 	ACCEL_ID_MPU6000,
 
 	COMPASS_ID_AKM,
 	COMPASS_ID_AMI30X,
+	COMPASS_ID_AMI306,
 	COMPASS_ID_YAS529,
+	COMPASS_ID_YAS530,
 	COMPASS_ID_HMC5883,
 	COMPASS_ID_LSM303,
 	COMPASS_ID_MMC314X,
-	COMPASS_ID_HSCDTD00XX,
+	COMPASS_ID_HSCDTD002B,
+	COMPASS_ID_HSCDTD004A,
 
 	PRESSURE_ID_BMA085,
 };
@@ -205,6 +241,7 @@ struct tFixPntRange {
  *  @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
@@ -238,6 +275,10 @@ struct ext_slave_descr {
 		       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;
 	unsigned char type;
@@ -278,65 +319,73 @@ struct mpu3050_platform_data {
 */
 #define get_accel_slave_descr NULL
 
-#ifdef CONFIG_SENSORS_ADXL346	/* ADI accelerometer */
+#ifdef CONFIG_MPU_SENSORS_ADXL346	/* ADI accelerometer */
 struct ext_slave_descr *adxl346_get_slave_descr(void);
 #undef get_accel_slave_descr
 #define get_accel_slave_descr adxl346_get_slave_descr
 #endif
 
-#ifdef CONFIG_SENSORS_BMA150	/* Bosch accelerometer */
+#ifdef CONFIG_MPU_SENSORS_BMA150	/* Bosch accelerometer */
 struct ext_slave_descr *bma150_get_slave_descr(void);
 #undef get_accel_slave_descr
 #define get_accel_slave_descr bma150_get_slave_descr
 #endif
 
-#ifdef CONFIG_SENSORS_BMA222	/* Bosch 222 accelerometer */
+#ifdef CONFIG_MPU_SENSORS_BMA222	/* Bosch 222 accelerometer */
 struct ext_slave_descr *bma222_get_slave_descr(void);
 #undef get_accel_slave_descr
 #define get_accel_slave_descr bma222_get_slave_descr
 #endif
 
-#ifdef CONFIG_SENSORS_KXSD9	/* Kionix accelerometer */
+#ifdef CONFIG_MPU_SENSORS_KXSD9	/* Kionix accelerometer */
 struct ext_slave_descr *kxsd9_get_slave_descr(void);
 #undef get_accel_slave_descr
 #define get_accel_slave_descr kxsd9_get_slave_descr
 #endif
 
-#ifdef CONFIG_SENSORS_KXTF9	/* Kionix accelerometer */
+#ifdef CONFIG_MPU_SENSORS_KXTF9	/* Kionix accelerometer */
 struct ext_slave_descr *kxtf9_get_slave_descr(void);
 #undef get_accel_slave_descr
 #define get_accel_slave_descr kxtf9_get_slave_descr
 #endif
 
-#ifdef CONFIG_SENSORS_LIS331DLH	/* ST accelerometer */
+#ifdef CONFIG_MPU_SENSORS_LIS331DLH	/* ST accelerometer */
 struct ext_slave_descr *lis331dlh_get_slave_descr(void);
 #undef get_accel_slave_descr
 #define get_accel_slave_descr lis331dlh_get_slave_descr
 #endif
 
-#ifdef CONFIG_SENSORS_LSM303DLHA	/* ST accelerometer */
+
+#ifdef CONFIG_MPU_SENSORS_LIS3DH	/* ST accelerometer */
+struct ext_slave_descr *lis3dh_get_slave_descr(void);
+#undef get_accel_slave_descr
+#define get_accel_slave_descr lis3dh_get_slave_descr
+#endif
+
+#ifdef CONFIG_MPU_SENSORS_LSM303DLHA	/* ST accelerometer */
 struct ext_slave_descr *lsm303dlha_get_slave_descr(void);
 #undef get_accel_slave_descr
 #define get_accel_slave_descr lsm303dlha_get_slave_descr
 #endif
 
 /* MPU6000 Accel */
-#if defined(CONFIG_SENSORS_MPU6000) || defined(CONFIG_SENSORS_MPU6000_MODULE)
+#if defined(CONFIG_MPU_SENSORS_MPU6000) || \
+    defined(CONFIG_MPU_SENSORS_MPU6000_MODULE)
 struct ext_slave_descr *mantis_get_slave_descr(void);
 #undef get_accel_slave_descr
 #define get_accel_slave_descr mantis_get_slave_descr
 #endif
 
-#ifdef CONFIG_SENSORS_MMA8450	/* Freescale accelerometer */
+#ifdef CONFIG_MPU_SENSORS_MMA8450	/* Freescale accelerometer */
 struct ext_slave_descr *mma8450_get_slave_descr(void);
 #undef get_accel_slave_descr
 #define get_accel_slave_descr mma8450_get_slave_descr
 #endif
 
-#ifdef CONFIG_SENSORS_MMA8451	/* Freescale accelerometer */
-struct ext_slave_descr *mma8451_get_slave_descr(void);
+#ifdef CONFIG_MPU_SENSORS_MMA845X	/* Freescale accelerometer */
+struct ext_slave_descr *mma845x_get_slave_descr(void);
 #undef get_accel_slave_descr
-#define get_accel_slave_descr mma8451_get_slave_descr
+#define get_accel_slave_descr mma845x_get_slave_descr
 #endif
 
 
@@ -345,54 +394,71 @@ struct ext_slave_descr *mma8451_get_slave_descr(void);
 */
 #define get_compass_slave_descr NULL
 
-#ifdef CONFIG_SENSORS_AK8975	/* AKM compass */
+#ifdef CONFIG_MPU_SENSORS_AK8975	/* AKM compass */
 struct ext_slave_descr *ak8975_get_slave_descr(void);
 #undef get_compass_slave_descr
 #define get_compass_slave_descr ak8975_get_slave_descr
 #endif
 
-#ifdef CONFIG_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_SENSORS_HMC5883	/* Honeywell compass */
+#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
 #define get_compass_slave_descr hmc5883_get_slave_descr
 #endif
 
-#ifdef CONFIG_SENSORS_MMC314X	/* MEMSIC compass */
+#ifdef CONFIG_MPU_SENSORS_MMC314X	/* MEMSIC compass */
 struct ext_slave_descr *mmc314x_get_slave_descr(void);
 #undef get_compass_slave_descr
 #define get_compass_slave_descr mmc314x_get_slave_descr
 #endif
 
-#ifdef CONFIG_SENSORS_LSM303DLHM	/* ST compass */
+#ifdef CONFIG_MPU_SENSORS_LSM303DLHM	/* ST compass */
 struct ext_slave_descr *lsm303dlhm_get_slave_descr(void);
 #undef get_compass_slave_descr
 #define get_compass_slave_descr lsm303dlhm_get_slave_descr
 #endif
 
-#ifdef CONFIG_SENSORS_YAS529	/* Yamaha compass */
+#ifdef CONFIG_MPU_SENSORS_YAS529	/* Yamaha compass */
 struct ext_slave_descr *yas529_get_slave_descr(void);
 #undef get_compass_slave_descr
 #define get_compass_slave_descr yas529_get_slave_descr
 #endif
 
-#ifdef CONFIG_SENSORS_HSCDTD00XX	/* Alps compass */
-struct ext_slave_descr *hscdtd00xx_get_slave_descr(void);
+#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 hscdtd00xx_get_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
+#define get_compass_slave_descr hscdtd002b_get_slave_descr
+#endif
+
+#ifdef CONFIG_MPU_SENSORS_HSCDTD004A	/* Alps HSCDTD004A compass */
+struct ext_slave_descr *hscdtd004a_get_slave_descr(void);
+#undef get_compass_slave_descr
+#define get_compass_slave_descr hscdtd004a_get_slave_descr
+#endif
 /*
     Pressure
 */
 #define get_pressure_slave_descr NULL
 
-#ifdef CONFIG_SENSORS_BMA085	/* BMA pressure */
+#ifdef CONFIG_MPU_SENSORS_BMA085	/* BMA pressure */
 struct ext_slave_descr *bma085_get_slave_descr(void);
 #undef get_pressure_slave_descr
 #define get_pressure_slave_descr bma085_get_slave_descr
diff --git a/include/linux/mpu3050.h b/include/linux/mpu3050.h
old mode 100644
new mode 100755
index e2578239b76a..a8dcd5a9473f
--- a/include/linux/mpu3050.h
+++ b/include/linux/mpu3050.h
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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 __MPU3050_H_
@@ -17,7 +30,7 @@
 
 #define MPU_NAME "mpu3050"
 #define DEFAULT_MPU_SLAVEADDR       0x68
-#include "mpu.h"
+
 /*==== MPU REGISTER SET ====*/
 enum mpu_register {
 	MPUREG_WHO_AM_I = 0,	/* 00 0x00 */
diff --git a/include/linux/mpu6000.h b/include/linux/mpu6000.h
old mode 100644
new mode 100755
index c02859a8bd49..5a63c8f07b70
--- a/include/linux/mpu6000.h
+++ b/include/linux/mpu6000.h
@@ -1,7 +1,20 @@
 /*
  $License:
     Copyright (C) 2010 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/>.
+  $
  */
 
 /**
@@ -21,122 +34,122 @@
 
 /*==== M_HW REGISTER SET ====*/
 enum {
-	MPUREG_XG_OFFS_TC = 0,
-	MPUREG_YG_OFFS_TC,
-	MPUREG_ZG_OFFS_TC,
-	MPUREG_X_FINE_GAIN,
-	MPUREG_Y_FINE_GAIN,
-	MPUREG_Z_FINE_GAIN,
-	MPUREG_XA_OFFS_H,
-	MPUREG_XA_OFFS_L_TC,
-	MPUREG_YA_OFFS_H,
-	MPUREG_YA_OFFS_L_TC,
-	MPUREG_ZA_OFFS_H,
+	MPUREG_XG_OFFS_TC = 0,			/* 0x00 */
+	MPUREG_YG_OFFS_TC,			/* 0x00 */
+	MPUREG_ZG_OFFS_TC,			/* 0x00 */
+	MPUREG_X_FINE_GAIN,			/* 0x00 */
+	MPUREG_Y_FINE_GAIN,			/* 0x00 */
+	MPUREG_Z_FINE_GAIN,			/* 0x00 */
+	MPUREG_XA_OFFS_H,			/* 0x00 */
+	MPUREG_XA_OFFS_L_TC,			/* 0x00 */
+	MPUREG_YA_OFFS_H,			/* 0x00 */
+	MPUREG_YA_OFFS_L_TC,			/* 0x00 */
+	MPUREG_ZA_OFFS_H,			/* 0x00 */
 	MPUREG_ZA_OFFS_L_TC,	/* 0xB */
-	MPUREG_0C_RSVD,
-	MPUREG_0D_RSVD,
-	MPUREG_0E_RSVD,
-	MPUREG_0F_RSVD,
-	MPUREG_10_RSVD,
-	MPUREG_11_RSVD,
-	MPUREG_12_RSVD,
-	MPUREG_XG_OFFS_USRH,
-	MPUREG_XG_OFFS_USRL,
-	MPUREG_YG_OFFS_USRH,
-	MPUREG_YG_OFFS_USRL,
-	MPUREG_ZG_OFFS_USRH,
-	MPUREG_ZG_OFFS_USRL,
+	MPUREG_0C_RSVD,			/* 0x00 */
+	MPUREG_0D_RSVD,			/* 0x00 */
+	MPUREG_0E_RSVD,			/* 0x00 */
+	MPUREG_0F_RSVD,			/* 0x00 */
+	MPUREG_10_RSVD,			/* 0x00 */
+	MPUREG_11_RSVD,			/* 0x00 */
+	MPUREG_12_RSVD,			/* 0x00 */
+	MPUREG_XG_OFFS_USRH,			/* 0x00 */
+	MPUREG_XG_OFFS_USRL,			/* 0x00 */
+	MPUREG_YG_OFFS_USRH,			/* 0x00 */
+	MPUREG_YG_OFFS_USRL,			/* 0x00 */
+	MPUREG_ZG_OFFS_USRH,			/* 0x00 */
+	MPUREG_ZG_OFFS_USRL,			/* 0x00 */
 	MPUREG_SMPLRT_DIV,	/* 0x19 */
 	MPUREG_CONFIG,		/* 0x1A ==> DLPF_FS_SYNC */
-	MPUREG_GYRO_CONFIG,
-	MPUREG_ACCEL_CONFIG,
-	MPUREG_ACCEL_FF_THR,
-	MPUREG_ACCEL_FF_DUR,
-	MPUREG_ACCEL_MOT_THR,
-	MPUREG_ACCEL_MOT_DUR,
-	MPUREG_ACCEL_ZRMOT_THR,
-	MPUREG_ACCEL_ZRMOT_DUR,
+	MPUREG_GYRO_CONFIG,			/* 0x00 */
+	MPUREG_ACCEL_CONFIG,			/* 0x00 */
+	MPUREG_ACCEL_FF_THR,			/* 0x00 */
+	MPUREG_ACCEL_FF_DUR,			/* 0x00 */
+	MPUREG_ACCEL_MOT_THR,			/* 0x00 */
+	MPUREG_ACCEL_MOT_DUR,			/* 0x00 */
+	MPUREG_ACCEL_ZRMOT_THR,			/* 0x00 */
+	MPUREG_ACCEL_ZRMOT_DUR,			/* 0x00 */
 	MPUREG_FIFO_EN,		/* 0x23 */
-	MPUREG_I2C_MST_CTRL,
+	MPUREG_I2C_MST_CTRL,			/* 0x00 */
 	MPUREG_I2C_SLV0_ADDR,	/* 0x25 */
-	MPUREG_I2C_SLV0_REG,
-	MPUREG_I2C_SLV0_CTRL,
+	MPUREG_I2C_SLV0_REG,			/* 0x00 */
+	MPUREG_I2C_SLV0_CTRL,			/* 0x00 */
 	MPUREG_I2C_SLV1_ADDR,	/* 0x28 */
-	MPUREG_I2C_SLV1_REG_PASSWORD,
-	MPUREG_I2C_SLV1_CTRL,
+	MPUREG_I2C_SLV1_REG_PASSWORD,			/* 0x00 */
+	MPUREG_I2C_SLV1_CTRL,			/* 0x00 */
 	MPUREG_I2C_SLV2_ADDR,	/* 0x2B */
-	MPUREG_I2C_SLV2_REG,
-	MPUREG_I2C_SLV2_CTRL,
+	MPUREG_I2C_SLV2_REG,			/* 0x00 */
+	MPUREG_I2C_SLV2_CTRL,			/* 0x00 */
 	MPUREG_I2C_SLV3_ADDR,	/* 0x2E */
-	MPUREG_I2C_SLV3_REG,
-	MPUREG_I2C_SLV3_CTRL,
+	MPUREG_I2C_SLV3_REG,			/* 0x00 */
+	MPUREG_I2C_SLV3_CTRL,			/* 0x00 */
 	MPUREG_I2C_SLV4_ADDR,	/* 0x31 */
-	MPUREG_I2C_SLV4_REG,
-	MPUREG_I2C_SLV4_DO,
-	MPUREG_I2C_SLV4_CTRL,
-	MPUREG_I2C_SLV4_DI,
+	MPUREG_I2C_SLV4_REG,			/* 0x00 */
+	MPUREG_I2C_SLV4_DO,			/* 0x00 */
+	MPUREG_I2C_SLV4_CTRL,			/* 0x00 */
+	MPUREG_I2C_SLV4_DI,			/* 0x00 */
 	MPUREG_I2C_MST_STATUS,	/* 0x36 */
 	MPUREG_INT_PIN_CFG,	/* 0x37 ==> -* INT_CFG */
 	MPUREG_INT_ENABLE,	/* 0x38 ==> / */
 	MPUREG_DMP_INT_STATUS,	/* 0x39 */
 	MPUREG_INT_STATUS,	/* 0x3A */
 	MPUREG_ACCEL_XOUT_H,	/* 0x3B */
-	MPUREG_ACCEL_XOUT_L,
-	MPUREG_ACCEL_YOUT_H,
-	MPUREG_ACCEL_YOUT_L,
-	MPUREG_ACCEL_ZOUT_H,
-	MPUREG_ACCEL_ZOUT_L,
+	MPUREG_ACCEL_XOUT_L,			/* 0x00 */
+	MPUREG_ACCEL_YOUT_H,			/* 0x00 */
+	MPUREG_ACCEL_YOUT_L,			/* 0x00 */
+	MPUREG_ACCEL_ZOUT_H,			/* 0x00 */
+	MPUREG_ACCEL_ZOUT_L,			/* 0x00 */
 	MPUREG_TEMP_OUT_H,	/* 0x41 */
-	MPUREG_TEMP_OUT_L,
+	MPUREG_TEMP_OUT_L,			/* 0x00 */
 	MPUREG_GYRO_XOUT_H,	/* 0x43 */
-	MPUREG_GYRO_XOUT_L,
-	MPUREG_GYRO_YOUT_H,
-	MPUREG_GYRO_YOUT_L,
-	MPUREG_GYRO_ZOUT_H,
-	MPUREG_GYRO_ZOUT_L,
+	MPUREG_GYRO_XOUT_L,			/* 0x00 */
+	MPUREG_GYRO_YOUT_H,			/* 0x00 */
+	MPUREG_GYRO_YOUT_L,			/* 0x00 */
+	MPUREG_GYRO_ZOUT_H,			/* 0x00 */
+	MPUREG_GYRO_ZOUT_L,			/* 0x00 */
 	MPUREG_EXT_SLV_SENS_DATA_00,	/* 0x49 */
-	MPUREG_EXT_SLV_SENS_DATA_01,
-	MPUREG_EXT_SLV_SENS_DATA_02,
-	MPUREG_EXT_SLV_SENS_DATA_03,
-	MPUREG_EXT_SLV_SENS_DATA_04,
-	MPUREG_EXT_SLV_SENS_DATA_05,
+	MPUREG_EXT_SLV_SENS_DATA_01,			/* 0x00 */
+	MPUREG_EXT_SLV_SENS_DATA_02,			/* 0x00 */
+	MPUREG_EXT_SLV_SENS_DATA_03,			/* 0x00 */
+	MPUREG_EXT_SLV_SENS_DATA_04,			/* 0x00 */
+	MPUREG_EXT_SLV_SENS_DATA_05,			/* 0x00 */
 	MPUREG_EXT_SLV_SENS_DATA_06,	/* 0x4F */
-	MPUREG_EXT_SLV_SENS_DATA_07,
-	MPUREG_EXT_SLV_SENS_DATA_08,
-	MPUREG_EXT_SLV_SENS_DATA_09,
-	MPUREG_EXT_SLV_SENS_DATA_10,
-	MPUREG_EXT_SLV_SENS_DATA_11,
+	MPUREG_EXT_SLV_SENS_DATA_07,			/* 0x00 */
+	MPUREG_EXT_SLV_SENS_DATA_08,			/* 0x00 */
+	MPUREG_EXT_SLV_SENS_DATA_09,			/* 0x00 */
+	MPUREG_EXT_SLV_SENS_DATA_10,			/* 0x00 */
+	MPUREG_EXT_SLV_SENS_DATA_11,			/* 0x00 */
 	MPUREG_EXT_SLV_SENS_DATA_12,	/* 0x55 */
-	MPUREG_EXT_SLV_SENS_DATA_13,
-	MPUREG_EXT_SLV_SENS_DATA_14,
-	MPUREG_EXT_SLV_SENS_DATA_15,
-	MPUREG_EXT_SLV_SENS_DATA_16,
-	MPUREG_EXT_SLV_SENS_DATA_17,
+	MPUREG_EXT_SLV_SENS_DATA_13,			/* 0x00 */
+	MPUREG_EXT_SLV_SENS_DATA_14,			/* 0x00 */
+	MPUREG_EXT_SLV_SENS_DATA_15,			/* 0x00 */
+	MPUREG_EXT_SLV_SENS_DATA_16,			/* 0x00 */
+	MPUREG_EXT_SLV_SENS_DATA_17,			/* 0x00 */
 	MPUREG_EXT_SLV_SENS_DATA_18,	/* 0x5B */
-	MPUREG_EXT_SLV_SENS_DATA_19,
-	MPUREG_EXT_SLV_SENS_DATA_20,
-	MPUREG_EXT_SLV_SENS_DATA_21,
-	MPUREG_EXT_SLV_SENS_DATA_22,
-	MPUREG_EXT_SLV_SENS_DATA_23,
+	MPUREG_EXT_SLV_SENS_DATA_19,			/* 0x00 */
+	MPUREG_EXT_SLV_SENS_DATA_20,			/* 0x00 */
+	MPUREG_EXT_SLV_SENS_DATA_21,			/* 0x00 */
+	MPUREG_EXT_SLV_SENS_DATA_22,			/* 0x00 */
+	MPUREG_EXT_SLV_SENS_DATA_23,			/* 0x00 */
 	ACCEL_INTEL_STATUS,	/* 0x61 */
-	MPUREG_62_RSVD,
-	MPUREG_63_RSVD,
-	MPUREG_64_RSVD,
-	MPUREG_65_RSVD,
-	MPUREG_66_RSVD,
-	MPUREG_67_RSVD,
+	MPUREG_62_RSVD,			/* 0x00 */
+	MPUREG_63_RSVD,			/* 0x00 */
+	MPUREG_64_RSVD,			/* 0x00 */
+	MPUREG_65_RSVD,			/* 0x00 */
+	MPUREG_66_RSVD,			/* 0x00 */
+	MPUREG_67_RSVD,			/* 0x00 */
 	SIGNAL_PATH_RESET,	/* 0x68 */
 	ACCEL_INTEL_CTRL,	/* 0x69 */
 	MPUREG_USER_CTRL,	/* 0x6A */
 	MPUREG_PWR_MGMT_1,	/* 0x6B */
-	MPUREG_PWR_MGMT_2,
+	MPUREG_PWR_MGMT_2,			/* 0x00 */
 	MPUREG_BANK_SEL,	/* 0x6D */
 	MPUREG_MEM_START_ADDR,	/* 0x6E */
 	MPUREG_MEM_R_W,		/* 0x6F */
-	MPUREG_PRGM_STRT_ADDRH,
-	MPUREG_PRGM_STRT_ADDRL,
+	MPUREG_PRGM_STRT_ADDRH,			/* 0x00 */
+	MPUREG_PRGM_STRT_ADDRL,			/* 0x00 */
 	MPUREG_FIFO_COUNTH,	/* 0x72 */
-	MPUREG_FIFO_COUNTL,
+	MPUREG_FIFO_COUNTL,			/* 0x00 */
 	MPUREG_FIFO_R_W,	/* 0x74 */
 	MPUREG_WHOAMI,		/* 0x75,117 */
 
@@ -296,7 +309,12 @@ enum MPU_MEMORY_BANKS {
 #define	BIT_STBY_ZG				0x01
 
 /* although it has 6, this refers to the gyros */
-#define MPU_NUM_AXES (3)
+#define MPU_NUM_AXES     (3)
+
+#define ACCEL_MOT_THR_LSB (32) /* mg */
+#define ACCEL_MOT_DUR_LSB (1)
+#define ACCEL_ZRMOT_THR_LSB_CONVERSION(mg) ((mg *1000)/255)
+#define ACCEL_ZRMOT_DUR_LSB (64)
 
 /*----------------------------------------------------------------------------*/
 /*---- Alternative names to take care of conflicts with current mpu3050.h ----*/