Update MPU3050 kernel driver

1. Update MPU3050 drivers to Invensense MPU code update v3.3.4 ported from:
   https://android.googlesource.com/kernel/msm.git/+/android-msm-sony-cm-jb-3.0
2. Enable LSM303DLHA and LSM303DLHM as MPU3050 slaves instead of fake BMA150 and AK8975
3. Proper LSM303DLHA and LSM303DLHM power management when acting as MPU3050 slaves
4. Gyro axis configuration changed
5. Updates to sensor setup by John Newby
diff --git a/arch/arm/configs/cyanogenmod_tenderloin_defconfig b/arch/arm/configs/cyanogenmod_tenderloin_defconfig
index 203c040..4bffb1d 100644
--- a/arch/arm/configs/cyanogenmod_tenderloin_defconfig
+++ b/arch/arm/configs/cyanogenmod_tenderloin_defconfig
@@ -1686,23 +1686,23 @@
 CONFIG_MPU_SENSORS_MPU3050=y
 # CONFIG_MPU_SENSORS_ACCELEROMETER_NONE is not set
 # CONFIG_MPU_SENSORS_ADXL346 is not set
-CONFIG_MPU_SENSORS_BMA150=y
+# CONFIG_MPU_SENSORS_BMA150 is not set
 # CONFIG_MPU_SENSORS_BMA250 is not set
 # CONFIG_MPU_SENSORS_BMA222 is not set
 # CONFIG_MPU_SENSORS_KXSD9 is not set
 # CONFIG_MPU_SENSORS_KXTF9 is not set
 # CONFIG_MPU_SENSORS_LIS331DLH is not set
 # CONFIG_MPU_SENSORS_LIS3DH is not set
-# CONFIG_MPU_SENSORS_LSM303DLHA is not set
+CONFIG_MPU_SENSORS_LSM303DLHA=y
 # CONFIG_MPU_SENSORS_MMA8450 is not set
 # CONFIG_MPU_SENSORS_MMA845X is not set
 # CONFIG_MPU_SENSORS_COMPASS_NONE is not set
-CONFIG_MPU_SENSORS_AK8975=y
+# CONFIG_MPU_SENSORS_AK8975 is not set
 # CONFIG_MPU_SENSORS_AK8963 is not set
 # CONFIG_MPU_SENSORS_MMC314X is not set
 # CONFIG_MPU_SENSORS_AMI30X is not set
 # CONFIG_MPU_SENSORS_HMC5883 is not set
-# CONFIG_MPU_SENSORS_LSM303DLHM is not set
+CONFIG_MPU_SENSORS_LSM303DLHM=y
 # CONFIG_MPU_SENSORS_YAS529 is not set
 # CONFIG_MPU_SENSORS_HSCDTD002B is not set
 # CONFIG_MPU_SENSORS_HSCDTD004A is not set
diff --git a/arch/arm/mach-msm/hp/tenderloin/board-tenderloin.c b/arch/arm/mach-msm/hp/tenderloin/board-tenderloin.c
index 2dd64a5..856eb2f 100644
--- a/arch/arm/mach-msm/hp/tenderloin/board-tenderloin.c
+++ b/arch/arm/mach-msm/hp/tenderloin/board-tenderloin.c
@@ -281,6 +281,8 @@
 	return ret;
 }
 
+#define MPU3050_GPIO_IRQ 125
+#define MPU3050_GPIO_FSYNC 119
 
 #ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
 static void (*sdc2_status_notify_cb)(int card_present, void *dev_id);
@@ -2417,8 +2419,8 @@
 };
 
 static struct lsm303dlh_acc_platform_data lsm303dlh_acc_pdata = {
-	.poll_interval = 200,
-	.min_interval = 10,
+	.poll_interval = 100,
+	.min_interval = LSM303DLH_ACC_MIN_POLL_PERIOD_MS,
 	.g_range = LSM303DLH_ACC_G_2G,
 	.axis_map_x = 1,
 	.axis_map_y = 0,
@@ -2426,14 +2428,14 @@
 	.negate_x = 1,
 	.negate_y = 0,
 	.negate_z = 0,
-	.gpio_int1 = -1,
-	.gpio_int2 = -1,
+	.gpio_int1 = LSM303DLH_ACC_DEFAULT_INT1_GPIO,
+	.gpio_int2 = LSM303DLH_ACC_DEFAULT_INT2_GPIO,
 };
 
 static struct lsm303dlh_mag_platform_data lsm303dlh_mag_pdata = {
-	.poll_interval = 200,
-	.min_interval = 10,
-	.h_range = LSM303DLH_MAG_H_4_0G,
+	.poll_interval = 100,
+	.min_interval = LSM303DLH_MAG_MIN_POLL_PERIOD_MS,
+	.h_range = LSM303DLH_MAG_H_8_1G,
 	.axis_map_x = 1,
 	.axis_map_y = 0,
 	.axis_map_z = 2,
@@ -2444,18 +2446,26 @@
 
 static struct mpu3050_platform_data mpu3050_data = {
 	.int_config = 0x10,
-	.orientation = { -1, 0, 0,
-					0, 1, 0,
-					0, 0, -1 },
+	.orientation = {   1,  0,  0,
+			   0,  1,  0,
+			   0,  0,  1 },
 	.accel = {
 		.get_slave_descr = get_accel_slave_descr,
-		.adapt_num = 0,
-		.bus = EXT_SLAVE_BUS_SECONDARY,
-		.address = 0x18,
-			.orientation = { -1, 0, 0,
-							0, 1, 0,
-							0, 0, -11 },
-
+		.adapt_num   = 0,
+		.bus         = EXT_SLAVE_BUS_SECONDARY,
+		.address     = 0x18,
+		.orientation = {   1,  0,  0,
+				   0,  1,  0,
+				   0,  0,  1 },
+	},
+	.compass = {
+		.get_slave_descr = get_compass_slave_descr,
+		.adapt_num   = 0,
+		.bus         = EXT_SLAVE_BUS_PRIMARY,
+		.address     = 0x1E,
+		.orientation = {  1,  0,  0,
+				  0,  1,  0,
+				  0,  0,  1 },
 	},
 };
 
@@ -2489,6 +2499,25 @@
     },
 };
 
+// MPU3050
+static uint32_t tenderloin_mpu3050_cfgs[] = {
+	GPIO_CFG(MPU3050_GPIO_IRQ,   0, GPIO_CFG_INPUT,  GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
+	GPIO_CFG(MPU3050_GPIO_FSYNC, 0, GPIO_CFG_OUTPUT,  GPIO_CFG_NO_PULL, GPIO_CFG_2MA)
+};
+
+static void __init tenderloin_init_mpu3050(void)
+{
+	unsigned n;
+	for (n = 0; n < ARRAY_SIZE(tenderloin_mpu3050_cfgs); ++n)
+		gpio_tlmm_config(tenderloin_mpu3050_cfgs[n], 0);
+
+	if (gpio_request(MPU3050_GPIO_FSYNC, "MPU3050_FSYNC")) {
+		pr_err("%s: MPU3050_GPIO_FSYNC request failed\n", __func__);
+		return;
+	}
+	gpio_direction_output(MPU3050_GPIO_FSYNC, 0);
+}
+
 #ifdef CONFIG_MFD_WM8994
 
 #define WM8958_I2C_SLAVE_ADDR 0x1a
@@ -2820,14 +2849,20 @@
   //	else
   //		pm8901_vreg_init_pdata[PM8901_VREG_ID_MPP0].active_high = 1;
 
-#ifdef CONFIG_INPUT_LSM303DLH
 	if (machine_is_tenderloin() && boardtype_is_3g()) {
-		lsm303dlh_acc_pdata.negate_y = 1;
+#ifdef CONFIG_INPUT_LSM303DLH
+		lsm303dlh_acc_pdata.negate_x = 1;
 		lsm303dlh_acc_pdata.negate_z = 1;
-		lsm303dlh_mag_pdata.negate_y = 1;
+		lsm303dlh_mag_pdata.negate_x = 1;
 		lsm303dlh_mag_pdata.negate_z = 1;
-	}
 #endif
+		mpu3050_data.orientation[0] = -mpu3050_data.orientation[0];
+		mpu3050_data.orientation[8] = -mpu3050_data.orientation[8];
+		mpu3050_data.accel.orientation[0] = -mpu3050_data.accel.orientation[0];
+		mpu3050_data.accel.orientation[8] = -mpu3050_data.accel.orientation[8];
+		mpu3050_data.compass.orientation[0] = -mpu3050_data.compass.orientation[0];
+		mpu3050_data.compass.orientation[8] = -mpu3050_data.compass.orientation[8];
+	}
 #endif
 }
 
@@ -3089,6 +3124,8 @@
 	msm8x60_init_uart12dm();
 	msm8x60_init_mmc();
 
+	tenderloin_init_mpu3050();
+
         tenderloin_init_ts();
 #ifdef CONFIG_MSM_CAMERA
         msm8x60_init_cam();
diff --git a/drivers/input/misc/lsm303dlh_acc_sysfs.c b/drivers/input/misc/lsm303dlh_acc_sysfs.c
index f3aa67c..e63661d 100644
--- a/drivers/input/misc/lsm303dlh_acc_sysfs.c
+++ b/drivers/input/misc/lsm303dlh_acc_sysfs.c
@@ -56,8 +56,6 @@
 
 #include <linux/i2c/lsm303dlh.h>
 
-#define	DEBUG	1
-
 #define G_MAX		8000
 
 #define SENSITIVITY_2G		1	/**	mg/LSB	*/
@@ -109,24 +107,6 @@
 #define I2C_RETRIES		5
 #define I2C_AUTO_INCREMENT	0x80
 
-/* RESUME STATE INDICES */
-#define	RES_CTRL_REG1		0
-#define	RES_CTRL_REG2		1
-#define	RES_CTRL_REG3		2
-#define	RES_CTRL_REG4		3
-#define	RES_CTRL_REG5		4
-#define	RES_REFERENCE		5
-
-#define	RES_INT_CFG1		6
-#define	RES_INT_THS1		7
-#define	RES_INT_DUR1		8
-#define	RES_INT_CFG2		9
-#define	RES_INT_THS2		10
-#define	RES_INT_DUR2		11
-
-#define	RESUME_ENTRIES		12
-/* end RESUME STATE INDICES */
-
 
 static struct {
 	unsigned int cutoff_ms;
@@ -144,39 +124,11 @@
 	{2000, LSM303DLH_ACC_ODRHALF | LSM303DLH_ACC_ODR1000 },
 };
 
-struct lsm303dlh_acc_data {
-	struct i2c_client *client;
-	struct lsm303dlh_acc_platform_data *pdata;
-
-	struct mutex lock;
-	struct delayed_work input_work;
-
-	struct input_dev *input_dev;
-
-	int hw_initialized;
-	/* hw_working=-1 means not tested yet */
-	int hw_working;
-	int selftest_enabled;
-
-	atomic_t enabled;
-	int on_before_suspend;
-
-	u8 sensitivity;
-
-	u8 resume_state[RESUME_ENTRIES];
-
-	int irq1;
-	struct work_struct irq1_work;
-	struct workqueue_struct *irq1_work_queue;
-	int irq2;
-	struct work_struct irq2_work;
-	struct workqueue_struct *irq2_work_queue;
-
-#ifdef DEBUG
-	u8 reg_addr;
-#endif
-};
-
+/*
+ * Because i2c devices can not carry a pointer from driver register to
+ * open, we keep this global.  This limits the driver to a single instance.
+ */
+static struct lsm303dlh_acc_data *lsm303dlh_acc_misc_data = NULL;
 
 static int lsm303dlh_acc_i2c_read(struct lsm303dlh_acc_data *acc,
 				  u8 *buf, int len)
@@ -359,7 +311,9 @@
 			enable_irq(acc->irq2);
 	}
 
-	if (!acc->hw_initialized) {
+	//When power on ACC, we need to know whether this action comes from Gyro or native ACC,
+	//if from Gyro, we should not do HW init, otherwise I2C error will occur
+	if (!acc->hw_initialized && !acc->ext_adap_enabled) {
 		err = lsm303dlh_acc_hw_init(acc);
 		if (acc->hw_working == 1 && err < 0) {
 			lsm303dlh_acc_device_power_off(acc);
@@ -408,6 +362,7 @@
 	;
 	/*  */
 	printk(KERN_INFO "%s: IRQ1 triggered\n", LSM303DLH_ACC_DEV_NAME);
+//exit:
 	enable_irq(acc->irq1);
 }
 
@@ -422,6 +377,7 @@
 	/*  */
 
 	printk(KERN_INFO "%s: IRQ2 triggered\n", LSM303DLH_ACC_DEV_NAME);
+//exit:
 	enable_irq(acc->irq2);
 }
 
@@ -452,7 +408,7 @@
 		return -EINVAL;
 	}
 
-	if (atomic_read(&acc->enabled)) {
+	//if (atomic_read(&acc->enabled)) {
 		/* Set configuration register 4, which contains g range setting
 		 *  NOTE: this is a straight overwrite because this driver does
 		 *  not use any of the other configuration bits in this
@@ -474,7 +430,7 @@
 			goto error;
 		acc->resume_state[RES_CTRL_REG4] = updated_val;
 		acc->sensitivity = sensitivity;
-	}
+	//}
 
 
 	return err;
@@ -506,13 +462,13 @@
 
 	/* If device is currently enabled, we need to write new
 	 *  configuration out to it */
-	if (atomic_read(&acc->enabled)) {
+	//if (atomic_read(&acc->enabled)) {
 		config[0] = CTRL_REG1;
 		err = lsm303dlh_acc_i2c_write(acc, config, 1);
 		if (err < 0)
 			goto error;
 		acc->resume_state[RES_CTRL_REG1] = config[1];
-	}
+	//}
 
 	return err;
 
@@ -655,8 +611,13 @@
 			atomic_set(&acc->enabled, 0);
 			return err;
 		}
-		schedule_delayed_work(&acc->input_work,
-			msecs_to_jiffies(acc->pdata->poll_interval));
+		if (!acc->ext_adap_enabled) {
+			schedule_delayed_work(&acc->input_work,
+				msecs_to_jiffies(acc->pdata->poll_interval));
+		}
+		else {
+			cancel_delayed_work_sync(&acc->input_work);
+		}
 	}
 
 	return 0;
@@ -668,10 +629,48 @@
 		cancel_delayed_work_sync(&acc->input_work);
 		lsm303dlh_acc_device_power_off(acc);
 	}
+	else {
+		//if enable acc from gyro request, we need to re-initial acc
+		if (!acc->ext_adap_enabled) {
+			lsm303dlh_acc_hw_init(acc);
+			schedule_delayed_work(&acc->input_work,
+				msecs_to_jiffies(acc->pdata->poll_interval));
+		}
+	}
 
 	return 0;
 }
 
+int lsm303dlh_acc_enable_ext(struct lsm303dlh_acc_data *acc)
+{
+	int err=0;
+	if (!acc->ext_adap_enabled)
+	{
+		acc->ext_adap_enabled = 1;
+		err = lsm303dlh_acc_enable(acc);
+	}
+	return err;
+}
+EXPORT_SYMBOL(lsm303dlh_acc_enable_ext);
+
+int lsm303dlh_acc_disable_ext(struct lsm303dlh_acc_data *acc)
+{
+	int err=0;
+	if (acc->ext_adap_enabled)
+	{
+		acc->ext_adap_enabled = 0;
+		err = lsm303dlh_acc_disable(acc);
+	}
+	return err;
+}
+EXPORT_SYMBOL(lsm303dlh_acc_disable_ext);
+
+struct lsm303dlh_acc_data * lsm303dlh_acc_get_instance_ext(void)
+{
+	return lsm303dlh_acc_misc_data;
+}
+EXPORT_SYMBOL(lsm303dlh_acc_get_instance_ext);
+
 
 static ssize_t read_single_reg(struct device *dev, char *buf, u8 reg)
 {
@@ -1134,7 +1133,7 @@
 static int lsm303dlh_acc_probe(struct i2c_client *client,
 			   const struct i2c_device_id *id)
 {
-	struct lsm303dlh_acc_data *acc;
+	struct lsm303dlh_acc_data *acc = lsm303dlh_acc_misc_data;
 	int err = -1;
 	//int tempvalue;
 
@@ -1171,16 +1170,6 @@
 	}
 	*/
 
-	acc = kzalloc(sizeof(struct lsm303dlh_acc_data), GFP_KERNEL);
-	if (acc == NULL) {
-		err = -ENOMEM;
-		dev_err(&client->dev,
-				"failed to allocate memory for module data: "
-					"%d\n", err);
-		goto exit_check_functionality_failed;
-	}
-
-
 	mutex_init(&acc->lock);
 	mutex_lock(&acc->lock);
 
@@ -1251,7 +1240,7 @@
 		goto err_pdata_init;
 	}
 
-	atomic_set(&acc->enabled, 1);
+	//atomic_set(&acc->enabled, 1);
 
 	err = lsm303dlh_acc_update_g_range(acc, acc->pdata->g_range);
 	if (err < 0) {
@@ -1284,7 +1273,7 @@
 	lsm303dlh_acc_device_power_off(acc);
 
 	/* As default, do not report information */
-	atomic_set(&acc->enabled, 0);
+	//atomic_set(&acc->enabled, 0);
 
 	if(acc->pdata->gpio_int1 >= 0){
 		INIT_WORK(&acc->irq1_work, lsm303dlh_acc_irq1_work_func);
@@ -1392,9 +1381,19 @@
 static int lsm303dlh_acc_resume(struct i2c_client *client)
 {
 	struct lsm303dlh_acc_data *acc = i2c_get_clientdata(client);
-
-	if (acc->on_before_suspend)
-		return lsm303dlh_acc_enable(acc);
+	int err;
+	if (acc->on_before_suspend) {
+		err = lsm303dlh_acc_device_power_on(acc);
+		if (err>=0) {
+			if (!acc->ext_adap_enabled) {
+				schedule_delayed_work(&acc->input_work,
+					msecs_to_jiffies(acc->pdata->poll_interval));
+			}
+			else {
+				cancel_delayed_work_sync(&acc->input_work);
+			}
+		}
+	}
 	return 0;
 }
 
@@ -1403,7 +1402,9 @@
 	struct lsm303dlh_acc_data *acc = i2c_get_clientdata(client);
 
 	acc->on_before_suspend = atomic_read(&acc->enabled);
-	return lsm303dlh_acc_disable(acc);
+	cancel_delayed_work_sync(&acc->input_work);
+	lsm303dlh_acc_device_power_off(acc);
+	return 0;
 }
 #else
 #define lis3dh_acc_suspend	NULL
@@ -1429,14 +1430,25 @@
 
 static int __init lsm303dlh_acc_init(void)
 {
+	struct lsm303dlh_acc_data *acc;
+
 	printk(KERN_DEBUG "%s accelerometer driver: init\n",
 						LSM303DLH_ACC_DEV_NAME);
+
+	acc = kzalloc(sizeof(struct lsm303dlh_acc_data), GFP_KERNEL);
+	if (acc == NULL) {
+		pr_err("failed to allocate memory for module data\n");
+		return -ENOMEM;
+	}
+
+	lsm303dlh_acc_misc_data = acc;
+
 	return i2c_add_driver(&lsm303dlh_acc_driver);
 }
 
 static void __exit lsm303dlh_acc_exit(void)
 {
-	#if DEBUG
+	#ifdef DEBUG
 	printk(KERN_DEBUG "%s accelerometer driver exit\n",
 						LSM303DLH_ACC_DEV_NAME);
 	#endif
diff --git a/drivers/input/misc/lsm303dlh_mag_sysfs.c b/drivers/input/misc/lsm303dlh_mag_sysfs.c
index 89283a2..9626119 100644
--- a/drivers/input/misc/lsm303dlh_mag_sysfs.c
+++ b/drivers/input/misc/lsm303dlh_mag_sysfs.c
@@ -33,14 +33,13 @@
 #include <linux/mutex.h>
 #include <linux/input-polldev.h>
 #include <linux/delay.h>
-#include <linux/module.h>
 
 #include <linux/slab.h>
 #include <linux/mm.h>
+#include <linux/module.h>
 
 #include <linux/i2c/lsm303dlh.h>
 
-
 /** Maximum polled-device-reported g value */
 #define H_MAX			8100
 
@@ -115,25 +114,11 @@
 	{	1334,	LSM303DLH_MAG_ODR_75},
 };
 
-struct lsm303dlh_mag_data {
-	struct i2c_client *client;
-	struct lsm303dlh_mag_platform_data *pdata;
-
-	struct mutex lock;
-
-	struct input_polled_dev *input_poll_dev;
-
-	int hw_initialized;
-	atomic_t enabled;
-	atomic_t self_test_enabled;
-
-	u16 xy_sensitivity;
-	u16 z_sensitivity;
-
-	u8 resume_state[3];
-
-	u8 reg_addr;
-};
+/*
+ * Because i2c devices can not carry a pointer from driver register to
+ * open, we keep this global.  This limits the driver to a single instance.
+ */
+struct lsm303dlh_mag_data *lsm303dlh_mag_misc_data = NULL;
 
 static int lsm303dlh_mag_i2c_read(struct lsm303dlh_mag_data *mag,
 				  u8 *buf, int len)
@@ -264,7 +249,7 @@
 		return -EINVAL;
 	}
 
-	if (atomic_read(&mag->enabled)) {
+	//if (atomic_read(&mag->enabled)) {
 
 		buf[0] = CRB_REG_M;
 		buf[1] = new_h_range;
@@ -272,7 +257,7 @@
 		if (err < 0)
 			return err;
 		mag->resume_state[RES_CRB_REG_M] = new_h_range;
-	}
+	//}
 
 	return 0;
 }
@@ -292,15 +277,13 @@
 	config[1] = odr_table[i].mask;
 	config[1] |= NORMAL_MODE;
 
-	if (atomic_read(&mag->enabled)) {
+	//if (atomic_read(&mag->enabled)) {
 		config[0] = CRA_REG_M;
 		err = lsm303dlh_mag_i2c_write(mag, config, 1);
 		if (err < 0)
 			return err;
 		mag->resume_state[RES_CRA_REG_M] = config[1];
-	}
-
-
+	//}
 
 	return 0;
 }
@@ -497,32 +480,86 @@
 static int lsm303dlh_mag_enable(struct lsm303dlh_mag_data *mag)
 {
 	int err;
+	int cur_count;
 
-	if (!atomic_cmpxchg(&mag->enabled, 0, 1)) {
+	cur_count = atomic_read(&mag->enabled);
+	atomic_inc(&mag->enabled);
 
+	if (!cur_count) {
 		err = lsm303dlh_mag_device_power_on(mag);
 		if (err < 0) {
 			atomic_set(&mag->enabled, 0);
 			return err;
 		}
+	}
+	
+	if (!mag->ext_adap_enabled) {
 		schedule_delayed_work(&mag->input_poll_dev->work,
 				      msecs_to_jiffies(mag->
 						       pdata->poll_interval));
 	}
+	else {
+		cancel_delayed_work_sync(&mag->input_poll_dev->work);
+	}
 
 	return 0;
 }
 
 static int lsm303dlh_mag_disable(struct lsm303dlh_mag_data *mag)
 {
-	if (atomic_cmpxchg(&mag->enabled, 1, 0)) {
+	#define atomic_decrement_if_positive(v) atomic_add_unless((v), -1, 0) /* CHECKME */
+	int cur_count;
+
+	atomic_decrement_if_positive(&mag->enabled);
+	cur_count = atomic_read(&mag->enabled);
+
+	if (!cur_count) {
 		cancel_delayed_work_sync(&mag->input_poll_dev->work);
 		lsm303dlh_mag_device_power_off(mag);
 	}
+	else  {
+		//if enable mag from gyro request, we need to re-initial mag
+		if (!mag->ext_adap_enabled) {
+			lsm303dlh_mag_hw_init(mag);
+			schedule_delayed_work(&mag->input_poll_dev->work,
+				msecs_to_jiffies(mag->pdata->poll_interval));
+		}
+	}
 
 	return 0;
 }
 
+int lsm303dlh_mag_enable_ext(struct lsm303dlh_mag_data *mag)
+{
+	int err = 0;
+	if (!mag->ext_adap_enabled)
+	{
+		mag->ext_adap_enabled = 1;
+		err = lsm303dlh_mag_enable(mag);
+	}
+	return err;
+}
+EXPORT_SYMBOL(lsm303dlh_mag_enable_ext);
+
+int lsm303dlh_mag_disable_ext(struct lsm303dlh_mag_data *mag)
+{
+	int err=0;
+	if (mag->ext_adap_enabled)
+	{
+		mag->ext_adap_enabled = 0;
+		err = lsm303dlh_mag_disable(mag);
+	}
+	return err;
+}
+EXPORT_SYMBOL(lsm303dlh_mag_disable_ext);
+
+struct lsm303dlh_mag_data * lsm303dlh_mag_get_instance_ext(void)
+{
+	return lsm303dlh_mag_misc_data;
+}
+EXPORT_SYMBOL(lsm303dlh_mag_get_instance_ext);
+
+
 static ssize_t attr_get_polling_rate(struct device *dev,
 				     struct device_attribute *attr,
 				     char *buf)
@@ -904,7 +941,7 @@
 		goto err2;
 	}
 
-	atomic_set(&mag->enabled, 1);
+	//atomic_set(&mag->enabled, 1);
 
 	err = lsm303dlh_mag_update_h_range(mag, mag->pdata->h_range);
 	if (err < 0) {
@@ -922,6 +959,8 @@
 	if (err < 0)
 		goto err3;
 
+	lsm303dlh_mag_misc_data = mag;
+
 	err = create_sysfs_interfaces(&client->dev);
 	if (err < 0) {
 		dev_err(&client->dev, "%s register failed\n",
@@ -931,7 +970,7 @@
 
 	lsm303dlh_mag_device_power_off(mag);
 
-	atomic_set(&mag->enabled, 0);
+	//atomic_set(&mag->enabled, 0);
 
 	mutex_unlock(&mag->lock);
 
@@ -974,10 +1013,17 @@
 static int lsm303dlh_mag_suspend(struct device *dev)
 {
 	#ifdef CONFIG_SUSPEND
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lsm303dlh_mag_data *mag = i2c_get_clientdata(client);
 	#ifdef DEBUG
 	pr_info(KERN_INFO "lsm303dlh_suspend\n");
 	#endif
-	/* TO DO */
+
+	mag->on_before_suspend = atomic_read(&mag->enabled);
+
+	cancel_delayed_work_sync(&mag->input_poll_dev->work);
+	lsm303dlh_mag_device_power_off(mag);
+
 	#endif
 	return 0;
 }
@@ -985,10 +1031,26 @@
 static int lsm303dlh_mag_resume(struct device *dev)
 {
 	#ifdef CONFIG_SUSPEND
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lsm303dlh_mag_data *mag = i2c_get_clientdata(client);
+	int err;
 	#ifdef DEBUG
 	pr_info(KERN_INFO "lsm303dlh_resume\n");
 	#endif
-	/* TO DO */
+
+	if (mag->on_before_suspend) {
+		err = lsm303dlh_mag_device_power_on(mag);
+		if (err>=0) {
+			if (!mag->ext_adap_enabled) {
+				schedule_delayed_work(&mag->input_poll_dev->work,
+					msecs_to_jiffies(mag->pdata->poll_interval));
+			}
+			else {
+				cancel_delayed_work_sync(&mag->input_poll_dev->work);
+			}
+		}
+	}
+
 	#endif
 	return 0;
 }
diff --git a/drivers/input/misc/mpu3050/accel/lsm303a.c b/drivers/input/misc/mpu3050/accel/lsm303a.c
new file mode 100644
index 0000000..7c393c3
--- /dev/null
+++ b/drivers/input/misc/mpu3050/accel/lsm303a.c
@@ -0,0 +1,195 @@
+/*
+ $License:
+    Copyright (C) 2010 InvenSense Corporation, All Rights Reserved.
+ $
+ */
+
+/**
+ *  @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   lsm303a.c
+ *      @brief  Accelerometer setup and handling methods for ST LSM303
+ */
+
+/* ------------------ */
+/* - Include Files. - */
+/* ------------------ */
+
+#ifdef __KERNEL__
+#include <linux/module.h>
+#endif
+
+#include "mpu.h"
+#include "mlsl.h"
+#include "mlos.h"
+
+#include <linux/i2c/lsm303dlh.h>
+#include <linux/i2c.h>
+
+#include <log.h>
+#undef MPL_LOG_TAG
+#define MPL_LOG_TAG "MPL-acc"
+
+#define ACCEL_ST_SLEEP_REG          (0x20)
+#define ACCEL_ST_SLEEP_MASK         (0x20)
+
+/* --------------------- */
+/* -    Variables.     - */
+/* --------------------- */
+
+/*****************************************
+    Accelerometer Initialization Functions
+*****************************************/
+
+#ifdef CONFIG_INPUT_LSM303DLH
+static struct lsm303dlh_acc_data* lsm303dlh_acc_misc_data=NULL;
+
+extern struct lsm303dlh_acc_data * lsm303dlh_acc_get_instance_ext(void);
+extern int lsm303dlh_acc_enable_ext(struct lsm303dlh_acc_data *acc);
+extern int lsm303dlh_acc_disable_ext(struct lsm303dlh_acc_data *acc);
+#endif
+
+int lsm303dlha_suspend(void *mlsl_handle,
+		       struct ext_slave_descr *slave,
+		       struct ext_slave_platform_data *pdata)
+{
+	int result = ML_SUCCESS;
+#ifndef CONFIG_INPUT_LSM303DLH
+	unsigned char reg;
+
+	result =
+	    MLSLSerialRead(mlsl_handle, pdata->address, ACCEL_ST_SLEEP_REG,
+			   1, &reg);
+	ERROR_CHECK(result);
+	reg &= ~(0x27);
+	result =
+	    MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				  ACCEL_ST_SLEEP_REG, reg);
+	ERROR_CHECK(result);
+#endif
+	return result;
+}
+
+/* full scale setting - register & mask */
+#define ACCEL_ST_CTRL_REG          (0x23)
+#define ACCEL_ST_CTRL_MASK         (0x30)
+
+int lsm303dlha_resume(void *mlsl_handle,
+		      struct ext_slave_descr *slave,
+		      struct ext_slave_platform_data *pdata)
+{
+	int result = ML_SUCCESS;
+	unsigned char reg;
+
+#ifdef CONFIG_INPUT_LSM303DLH
+	if (!lsm303dlh_acc_misc_data)
+	{
+		lsm303dlh_acc_misc_data = lsm303dlh_acc_get_instance_ext();
+		//lsm303dlh_acc_misc_data->send_cb = MLSLSerialWrite;
+	}
+	if (lsm303dlh_acc_misc_data)
+	{
+		lsm303dlh_acc_misc_data->ext_handle=mlsl_handle;
+		result = lsm303dlh_acc_enable_ext(lsm303dlh_acc_misc_data);
+		//pr_err(" ##### Wade %s: result:%d\n", __func__, result);
+		MLOSSleep(50);
+	}
+	else
+	{
+		pr_err("%s: lsm303dlh_acc_misc_data is NULL\n", __func__);
+	}
+#endif
+
+	result =
+	    MLSLSerialRead(mlsl_handle, pdata->address, ACCEL_ST_SLEEP_REG,
+			   1, &reg);
+	ERROR_CHECK(result);
+	reg |= 0x27;
+	/*wake up if sleeping */
+	result =
+	    MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				  ACCEL_ST_SLEEP_REG, reg);
+	ERROR_CHECK(result);
+
+	result =
+	    MLSLSerialWriteSingle(mlsl_handle, pdata->address, 0x20, 0x37);
+	ERROR_CHECK(result);
+	MLOSSleep(500);
+
+	reg = 0x40;
+
+	/* Full Scale */
+	reg &= ~ACCEL_ST_CTRL_MASK;
+	if (slave->range.mantissa == 2
+	    && slave->range.fraction == 480) {
+		reg |= 0x00;
+	} else if (slave->range.mantissa == 4
+		   && slave->range.fraction == 960) {
+		reg |= 0x10;
+	} else if (slave->range.mantissa == 8
+		   && slave->range.fraction == 1920) {
+		reg |= 0x30;
+	}
+	result =
+	    MLSLSerialWriteSingle(mlsl_handle, pdata->address, 0x23, reg);
+	ERROR_CHECK(result);
+
+	/* Configure high pass filter */
+	result =
+	    MLSLSerialWriteSingle(mlsl_handle, pdata->address, 0x21, 0x0F);
+	ERROR_CHECK(result);
+	result =
+	    MLSLSerialWriteSingle(mlsl_handle, pdata->address, 0x32, 0x00);
+	ERROR_CHECK(result);
+	/* Configure INT1_DURATION */
+	result =
+	    MLSLSerialWriteSingle(mlsl_handle, pdata->address, 0x33, 0x7F);
+	ERROR_CHECK(result);
+	/* Configure INT1_CFG */
+	result =
+	    MLSLSerialWriteSingle(mlsl_handle, pdata->address, 0x30, 0x95);
+	ERROR_CHECK(result);
+	MLOSSleep(50);
+	return result;
+}
+
+int lsm303dlha_read(void *mlsl_handle,
+		    struct ext_slave_descr *slave,
+		    struct ext_slave_platform_data *pdata,
+		    unsigned char *data)
+{
+	int result;
+	result = MLSLSerialRead(mlsl_handle, pdata->address,
+				slave->reg, slave->len, data);
+	return result;
+}
+
+struct ext_slave_descr lsm303dlha_descr = {
+	/*.init             = */ NULL,
+	/*.exit             = */ NULL,
+	/*.suspend          = */ lsm303dlha_suspend,
+	/*.resume           = */ lsm303dlha_resume,
+	/*.read             = */ lsm303dlha_read,
+	/*.config           = */ NULL,
+	/*.get_config       = */ NULL,
+	/*.name             = */ "lsm303dlha",
+	/*.type             = */ EXT_SLAVE_TYPE_ACCELEROMETER,
+	/*.id               = */ ACCEL_ID_LSM303,
+	/*.reg              = */ (0x28 | 0x80), /* 0x80 for burst reads */
+	/*.len              = */ 6,
+	/*.endian           = */ EXT_SLAVE_BIG_ENDIAN,
+	/*.range            = */ {2, 480},
+};
+
+struct ext_slave_descr *lsm303dlha_get_slave_descr(void)
+{
+	return &lsm303dlha_descr;
+}
+EXPORT_SYMBOL(lsm303dlha_get_slave_descr);
+
+/**
+ *  @}
+**/
diff --git a/drivers/input/misc/mpu3050/compass/lsm303m.c b/drivers/input/misc/mpu3050/compass/lsm303m.c
new file mode 100644
index 0000000..50436ff
--- /dev/null
+++ b/drivers/input/misc/mpu3050/compass/lsm303m.c
@@ -0,0 +1,237 @@
+/*
+ $License:
+    Copyright (C) 2010 InvenSense Corporation, All Rights Reserved.
+ $
+ */
+
+/**
+ *  @brief      Provides the interface to setup and handle a compass
+ *              connected to the primary I2C interface of the gyroscope.
+ *
+ *  @{
+ *      @file   lsm303m.c
+ *      @brief  Magnetometer setup and handling methods for ST LSM303.
+ */
+
+/* ------------------ */
+/* - Include Files. - */
+/* ------------------ */
+
+#ifdef __KERNEL__
+#include <linux/module.h>
+#endif
+
+#include "mpu.h"
+#include "mlsl.h"
+#include "mlos.h"
+
+#include <linux/i2c/lsm303dlh.h>
+
+#include <log.h>
+#undef MPL_LOG_TAG
+#define MPL_LOG_TAG "MPL-compass"
+
+/*----- ST LSM303 Registers ------*/
+enum LSM_REG {
+	LSM_REG_CONF_A = 0x0,
+	LSM_REG_CONF_B = 0x1,
+	LSM_REG_MODE = 0x2,
+	LSM_REG_X_M = 0x3,
+	LSM_REG_X_L = 0x4,
+	LSM_REG_Z_M = 0x5,
+	LSM_REG_Z_L = 0x6,
+	LSM_REG_Y_M = 0x7,
+	LSM_REG_Y_L = 0x8,
+	LSM_REG_STATUS = 0x9,
+	LSM_REG_ID_A = 0xA,
+	LSM_REG_ID_B = 0xB,
+	LSM_REG_ID_C = 0xC
+};
+
+enum LSM_CONF_A {
+	LSM_CONF_A_DRATE_MASK = 0x1C,
+	LSM_CONF_A_DRATE_0_75 = 0x00,
+	LSM_CONF_A_DRATE_1_5 = 0x04,
+	LSM_CONF_A_DRATE_3 = 0x08,
+	LSM_CONF_A_DRATE_7_5 = 0x0C,
+	LSM_CONF_A_DRATE_15 = 0x10,
+	LSM_CONF_A_DRATE_30 = 0x14,
+	LSM_CONF_A_DRATE_75 = 0x18,
+	LSM_CONF_A_MEAS_MASK = 0x3,
+	LSM_CONF_A_MEAS_NORM = 0x0,
+	LSM_CONF_A_MEAS_POS = 0x1,
+	LSM_CONF_A_MEAS_NEG = 0x2
+};
+
+enum LSM_CONF_B {
+	LSM_CONF_B_GAIN_MASK = 0xE0,
+	LSM_CONF_B_GAIN_0_9 = 0x00,
+	LSM_CONF_B_GAIN_1_2 = 0x20,
+	LSM_CONF_B_GAIN_1_9 = 0x40,
+	LSM_CONF_B_GAIN_2_5 = 0x60,
+	LSM_CONF_B_GAIN_4_0 = 0x80,
+	LSM_CONF_B_GAIN_4_6 = 0xA0,
+	LSM_CONF_B_GAIN_5_5 = 0xC0,
+	LSM_CONF_B_GAIN_7_9 = 0xE0
+};
+
+enum LSM_MODE {
+	LSM_MODE_MASK = 0x3,
+	LSM_MODE_CONT = 0x0,
+	LSM_MODE_SINGLE = 0x1,
+	LSM_MODE_IDLE = 0x2,
+	LSM_MODE_SLEEP = 0x3
+};
+
+/* --------------------- */
+/* -    Variables.     - */
+/* --------------------- */
+
+/*****************************************
+    Accelerometer Initialization Functions
+*****************************************/
+
+#ifdef CONFIG_INPUT_LSM303DLH
+static struct lsm303dlh_mag_data* lsm303dlh_mag_misc_data = NULL;
+
+extern struct lsm303dlh_mag_data * lsm303dlh_mag_get_instance_ext(void);
+extern int lsm303dlh_mag_enable_ext(struct lsm303dlh_mag_data *mag);
+extern int lsm303dlh_mag_disable_ext(struct lsm303dlh_mag_data *mag);
+#endif
+
+int lsm303dlhm_suspend(void *mlsl_handle,
+		       struct ext_slave_descr *slave,
+		       struct ext_slave_platform_data *pdata)
+{
+	int result = ML_SUCCESS;
+#ifdef CONFIG_INPUT_LSM303DLH
+	result =
+	    MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				  LSM_REG_MODE, LSM_MODE_SLEEP);
+	ERROR_CHECK(result);
+	MLOSSleep(3);
+#endif
+	return result;
+}
+
+int lsm303dlhm_resume(void *mlsl_handle,
+		      struct ext_slave_descr *slave,
+		      struct ext_slave_platform_data *pdata)
+{
+	int result = ML_SUCCESS;
+
+#ifdef CONFIG_INPUT_LSM303DLH
+	if (!lsm303dlh_mag_misc_data)
+	{
+		lsm303dlh_mag_misc_data = lsm303dlh_mag_get_instance_ext();
+	}
+	if (lsm303dlh_mag_misc_data)
+	{
+		lsm303dlh_mag_misc_data->ext_handle=mlsl_handle;
+		result = lsm303dlh_mag_enable_ext(lsm303dlh_mag_misc_data);
+		MLOSSleep(50);
+	}
+	else
+	{
+		pr_err("%s: lsm303dlh_mag_misc_data is NULL\n", __func__);
+	}
+#endif
+
+	/* Use single measurement mode. Start at sleep state. */
+	result =
+	    MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				  LSM_REG_MODE, LSM_MODE_SLEEP);
+	ERROR_CHECK(result);
+	/* Config normal measurement */
+	result =
+	    MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				  LSM_REG_CONF_A, 0);
+	ERROR_CHECK(result);
+	/* Adjust gain to 320 LSB/Gauss */
+	result =
+	    MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+				  LSM_REG_CONF_B, LSM_CONF_B_GAIN_5_5);
+	ERROR_CHECK(result);
+
+	return result;
+}
+
+int lsm303dlhm_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;
+	short zAxisfixed;
+
+	/* Read status reg. to check if data is ready */
+	result =
+	    MLSLSerialRead(mlsl_handle, pdata->address, LSM_REG_STATUS, 1,
+			   &stat);
+	ERROR_CHECK(result);
+	if (stat & 0x01) {
+		result =
+		    MLSLSerialRead(mlsl_handle, pdata->address,
+				   LSM_REG_X_M, 6, (unsigned char *) data);
+		ERROR_CHECK(result);
+
+		/*drop data if overflows */
+		if ((data[0] == 0xf0) || (data[2] == 0xf0)
+		    || (data[4] == 0xf0)) {
+			return ML_ERROR_COMPASS_DATA_OVERFLOW;
+		}
+		/* convert to fixed point and apply sensitivity correction for
+		   Z-axis */
+		zAxisfixed =
+		    (short) ((unsigned short) data[5] +
+			     (unsigned short) data[4] * 256);
+		/* scale up by 1.122 (320/285) */
+		zAxisfixed = (short) (zAxisfixed * 9) >> 3;
+		data[4] = zAxisfixed >> 8;
+		data[5] = zAxisfixed & 0xFF;
+
+		/* trigger next measurement read */
+		result =
+		    MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					  LSM_REG_MODE, LSM_MODE_SINGLE);
+		ERROR_CHECK(result);
+
+		return ML_SUCCESS;
+	} else {
+		/* trigger next measurement read */
+		result =
+		    MLSLSerialWriteSingle(mlsl_handle, pdata->address,
+					  LSM_REG_MODE, LSM_MODE_SINGLE);
+		ERROR_CHECK(result);
+
+		return ML_ERROR_COMPASS_DATA_NOT_READY;
+	}
+}
+
+struct ext_slave_descr lsm303dlhm_descr = {
+	/*.init             = */ NULL,
+	/*.exit             = */ NULL,
+	/*.suspend          = */ lsm303dlhm_suspend,
+	/*.resume           = */ lsm303dlhm_resume,
+	/*.read             = */ lsm303dlhm_read,
+	/*.config           = */ NULL,
+	/*.get_config       = */ NULL,
+	/*.name             = */ "lsm303dlhm",
+	/*.type             = */ EXT_SLAVE_TYPE_COMPASS,
+	/*.id               = */ COMPASS_ID_LSM303,
+	/*.reg              = */ 0x06,
+	/*.len              = */ 6,
+	/*.endian           = */ EXT_SLAVE_BIG_ENDIAN,
+	/*.range            = */ {10240, 0},
+};
+
+struct ext_slave_descr *lsm303dlhm_get_slave_descr(void)
+{
+	return &lsm303dlhm_descr;
+}
+EXPORT_SYMBOL(lsm303dlhm_get_slave_descr);
+
+/**
+ *  @}
+**/
diff --git a/drivers/input/misc/mpu3050/log.h b/drivers/input/misc/mpu3050/log.h
index 7b24aca..d57c661 100644
--- a/drivers/input/misc/mpu3050/log.h
+++ b/drivers/input/misc/mpu3050/log.h
@@ -1,37 +1,55 @@
 /*
- * Copyright (C) 2010 InvenSense Inc
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ $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/>.
+  $
  */
 
+/*
+ * C/C++ logging functions.  See the logging documentation for API details.
+ *
+ * We'd like these to be available from C code (in case we import some from
+ * somewhere), so this has a C interface.
+ *
+ * The output will be correct when the log file is shared between multiple
+ * threads and/or multiple processes so long as the operating system
+ * supports O_APPEND.  These calls have mutex-protected data structures
+ * and so are NOT reentrant.  Do not use MPL_LOG in a signal handler.
+ */
 #ifndef _LIBS_CUTILS_MPL_LOG_H
 #define _LIBS_CUTILS_MPL_LOG_H
 
 #include <stdarg.h>
 
 #ifdef ANDROID
-#include <utils/Log.h>		
+#include <utils/Log.h>		/* For the LOG macro */
 #endif
 
-#ifdef __KERNEL__
 #include <linux/kernel.h>
-#endif
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/* --------------------------------------------------------------------- */
 
+/*
+ * Normally we strip MPL_LOGV (VERBOSE messages) from release builds.
+ * You can modify this (for example with "#define MPL_LOG_NDEBUG 0"
+ * at the top of your source file) to change that behavior.
+ */
 #ifndef MPL_LOG_NDEBUG
 #ifdef NDEBUG
 #define MPL_LOG_NDEBUG 1
@@ -40,7 +58,6 @@
 #endif
 #endif
 
-#ifdef __KERNEL__
 #define MPL_LOG_UNKNOWN MPL_LOG_VERBOSE
 #define MPL_LOG_DEFAULT KERN_DEFAULT
 #define MPL_LOG_VERBOSE KERN_CONT
@@ -50,32 +67,30 @@
 #define MPL_LOG_ERROR   KERN_ERR
 #define MPL_LOG_SILENT  MPL_LOG_VERBOSE
 
-#else
-#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
 
-
+/*
+ * This is the local tag used for the following simplified
+ * logging macros.  You can change this preprocessor definition
+ * before using the other macros to change the tag.
+ */
 #ifndef MPL_LOG_TAG
-#ifdef __KERNEL__
 #define MPL_LOG_TAG
-#else
-#define MPL_LOG_TAG NULL
-#endif
 #endif
 
+/* --------------------------------------------------------------------- */
 
+/*
+ * Simplified macro to send a verbose log message using the current MPL_LOG_TAG.
+ */
 #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
 
@@ -85,125 +100,182 @@
 
 #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
 
+/*
+ * 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
 
+/*
+ * 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
 
+/*
+ * 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__))
+#define MPL_LOGW(fmt, ...) printk(KERN_WARNING MPL_LOG_TAG fmt, ##__VA_ARGS__)
 #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
 
+/*
+ * 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__))
+#define MPL_LOGE(fmt, ...) printk(KERN_ERR MPL_LOG_TAG fmt, ##__VA_ARGS__)
 #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
 
+/* --------------------------------------------------------------------- */
 
-#define MPL_LOG_ALWAYS_FATAL_IF(cond, ...) \
+/*
+ * Log a fatal error.  If the given condition fails, this stops program
+ * execution like a normal assertion, but also generating the given message.
+ * 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, 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
 
-#define MPL_LOG_ASSERT(cond, ...) MPL_LOG_FATAL_IF(!(cond), __VA_ARGS__)
+/*
+ * 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, fmt, ...)			\
+	MPL_LOG_FATAL_IF(!(cond), fmt, ##__VA_ARGS__)
 
+/* --------------------------------------------------------------------- */
 
+/*
+ * Basic log message macro.
+ *
+ * Example:
+ *  MPL_LOG(MPL_LOG_WARN, NULL, "Failed with error %d", errno);
+ *
+ * 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
 
+/*
+ * Log macro that allows you to specify a number for the priority.
+ */
 #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
 
+/*
+ * Log macro that allows you to pass in a varargs ("args" is a va_list).
+ */
 #ifndef MPL_LOG_PRI_VA
 #ifdef ANDROID
 #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)
 #endif
 #endif
 
+/* --------------------------------------------------------------------- */
 
+/*
+ * ===========================================================================
+ *
+ * The stuff in the rest of this file should not be used directly.
+ */
 
 #ifndef ANDROID
 	int _MLPrintLog(int priority, const char *tag, const char *fmt,
 			...);
 	int _MLPrintVaLog(int priority, const char *tag, const char *fmt,
 			  va_list args);
+/* Final implementation of actual writing to a character device */
 	int _MLWriteLog(const char *buf, int buflen);
 #endif
 
 #ifdef __cplusplus
 }
 #endif
-#endif				
+#endif				/* _LIBS_CUTILS_MPL_LOG_H */
diff --git a/drivers/input/misc/mpu3050/mldl_cfg.c b/drivers/input/misc/mpu3050/mldl_cfg.c
index b21d0fa..4b99695 100644
--- a/drivers/input/misc/mpu3050/mldl_cfg.c
+++ b/drivers/input/misc/mpu3050/mldl_cfg.c
@@ -17,12 +17,22 @@
   $
  */
 
+/**
+ *  @addtogroup MLDL
+ *
+ *  @{
+ *      @file   mldl_cfg.c
+ *      @brief  The Motion Library Driver Layer.
+ */
 
+/* ------------------ */
+/* - Include Files. - */
+/* ------------------ */
 
 #include <stddef.h>
 
 #include "mldl_cfg.h"
-#include "mpu.h"
+#include <linux/mpu.h>
 
 #include "mlsl.h"
 #include "mlos.h"
@@ -31,27 +41,31 @@
 #undef MPL_LOG_TAG
 #define MPL_LOG_TAG "mldl_cfg:"
 
-#ifdef M_HW
-#define SLEEP   0
-#define WAKE_UP 7
-#define RESET   1
-#define STANDBY 1
-#else
+/* --------------------- */
+/* -    Variables.     - */
+/* --------------------- */
+/* licteral significance of all parameters used in MLDLPowerMgmtMPU */
 #define SLEEP   1
 #define WAKE_UP 0
 #define RESET   1
 #define STANDBY 1
-#endif
 
-#define D(x...) printk(KERN_DEBUG "[GYRO][MPU3050] " x)
-#define I(x...) printk(KERN_INFO "[GYRO][MPU3050] " x)
-#define E(x...) printk(KERN_ERR "[GYRO][MPU3050 ERROR] " x)
+#define READ_BYPASS_STATE 0
+#define SAVE_BYPASS_STATE 1
 
+unsigned char gyro_power = 0;
 
+/*---------------------*/
+/*-    Prototypes.    -*/
+/*---------------------*/
+
+/*----------------------*/
+/*-  Static Functions. -*/
+/*----------------------*/
 
 static int dmp_stop(struct mldl_cfg *mldl_cfg, void *gyro_handle)
 {
-	unsigned char userCtrlReg = 0;
+	unsigned char userCtrlReg;
 	int result;
 
 	if (!mldl_cfg->dmp_is_running)
@@ -71,9 +85,14 @@
 	return result;
 
 }
+/**
+ * @brief Starts the DMP running
+ *
+ * @return ML_SUCCESS or non-zero error code
+ */
 static int dmp_start(struct mldl_cfg *pdata, void *mlsl_handle)
 {
-	unsigned char userCtrlReg = 0;
+	unsigned char userCtrlReg;
 	int result;
 
 	if (pdata->dmp_is_running == pdata->dmp_enable)
@@ -117,57 +136,92 @@
 	return result;
 }
 
+DEFINE_MUTEX(mutex_fifo_reading_access_lock);
+
+/**
+ *  @brief  enables/disables the I2C bypass to an external device
+ *          connected to MPU's secondary I2C bus.
+ *  @param  enable
+ *              Non-zero to enable pass through.
+ *  @return ML_SUCCESS if successful, a non-zero error code otherwise.
+ */
 static int MLDLSetI2CBypass(struct mldl_cfg *mldl_cfg,
 			    void *mlsl_handle,
 			    unsigned char enable)
 {
-	unsigned char b = 0;
+	unsigned char b, userctl;
 	int result;
 
 	if ((mldl_cfg->gyro_is_bypassed && enable) ||
 	    (!mldl_cfg->gyro_is_bypassed && !enable))
 		return ML_SUCCESS;
 
-	
+	/*---- get current 'USER_CTRL' into b ----*/
 	result = MLSLSerialRead(mlsl_handle, mldl_cfg->addr,
 				MPUREG_USER_CTRL, 1, &b);
 	ERROR_CHECK(result);
 
 	b &= ~BIT_AUX_IF_EN;
 
+	mutex_lock(&mutex_fifo_reading_access_lock);
 	if (!enable) {
 		result = MLSLSerialWriteSingle(mlsl_handle, mldl_cfg->addr,
 					       MPUREG_USER_CTRL,
 					       (b | BIT_AUX_IF_EN));
-		ERROR_CHECK(result);
+		ERROR_CHECK_MUTEX(result, mutex_fifo_reading_access_lock);
+		if (mldl_cfg->pdata->accel.bypass_state) {
+			userctl = (b | BIT_AUX_IF_EN);
+			mldl_cfg->pdata->accel.bypass_state(
+				SAVE_BYPASS_STATE, &userctl);
+		}
 	} else {
+		/* Coming out of I2C is tricky due to several erratta.  Do not
+		 * modify this algorithm
+		 */
+		/*
+		 * 1) wait for the right time and send the command to change
+		 * the aux i2c slave address to an invalid address that will
+		 * get nack'ed
+		 *
+		 * 0x00 is broadcast.  0x7F is unlikely to be used by any aux.
+		 */
 		result = MLSLSerialWriteSingle(mlsl_handle, mldl_cfg->addr,
 					       MPUREG_AUX_SLV_ADDR, 0x7F);
-		ERROR_CHECK(result);
+		ERROR_CHECK_MUTEX(result, mutex_fifo_reading_access_lock);
+		/*
+		 * 2) wait enough time for a nack to occur, then go into
+		 *    bypass mode:
+		 */
 		MLOSSleep(2);
 		result = MLSLSerialWriteSingle(mlsl_handle, mldl_cfg->addr,
 					       MPUREG_USER_CTRL, (b));
-		ERROR_CHECK(result);
+		ERROR_CHECK_MUTEX(result, mutex_fifo_reading_access_lock);
+		if (mldl_cfg->pdata->accel.bypass_state) {
+			userctl = b;
+			mldl_cfg->pdata->accel.bypass_state(
+				SAVE_BYPASS_STATE, &userctl);
+		}
+		/*
+		 * 3) wait for up to one MPU cycle then restore the slave
+		 *    address
+		 */
 		MLOSSleep(SAMPLING_PERIOD_US(mldl_cfg) / 1000);
 		result = MLSLSerialWriteSingle(mlsl_handle, mldl_cfg->addr,
 					       MPUREG_AUX_SLV_ADDR,
 					       mldl_cfg->pdata->
 					       accel.address);
-		ERROR_CHECK(result);
+		ERROR_CHECK_MUTEX(result, mutex_fifo_reading_access_lock);
 
-#ifdef M_HW
-		result = MLSLSerialWriteSingle(mlsl_handle, mldl_cfg->addr,
-					       MPUREG_USER_CTRL,
-					       (b | BIT_I2C_MST_RST));
-
-#else
+		/*
+		 * 4) reset the ime interface
+		 */
 		result = MLSLSerialWriteSingle(mlsl_handle, mldl_cfg->addr,
 					       MPUREG_USER_CTRL,
 					       (b | BIT_AUX_IF_RST));
-#endif
-		ERROR_CHECK(result);
+		ERROR_CHECK_MUTEX(result, mutex_fifo_reading_access_lock);
 		MLOSSleep(2);
 	}
+	mutex_unlock(&mutex_fifo_reading_access_lock);
 	mldl_cfg->gyro_is_bypassed = enable;
 
 	return result;
@@ -180,54 +234,47 @@
 
 #define NUM_OF_PROD_REVS (DIM(prodRevsMap))
 
-#ifdef M_HW
-#define OLDEST_PROD_REV_SUPPORTED 1
-static struct tsProdRevMap prodRevsMap[] = {
-	{0, 0},
-	{MPU_SILICON_REV_A1, 131},	
-	{MPU_SILICON_REV_A1, 131},	
-	{MPU_SILICON_REV_A1, 131},	
-	{MPU_SILICON_REV_A1, 131},	
-	{MPU_SILICON_REV_A1, 131},	
-	{MPU_SILICON_REV_A1, 131},	
-	{MPU_SILICON_REV_A1, 131},	
-	{MPU_SILICON_REV_A1, 131},	
-};
-
-#else				
+/* NOTE : 'npp' is a non production part */
 #define OLDEST_PROD_REV_SUPPORTED 11
 
 static struct tsProdRevMap prodRevsMap[] = {
 	{0, 0},
-	{MPU_SILICON_REV_A4, 131},	
-	{MPU_SILICON_REV_A4, 131},	
-	{MPU_SILICON_REV_A4, 131},	
-	{MPU_SILICON_REV_A4, 131},	
-	{MPU_SILICON_REV_A4, 131},	
-	{MPU_SILICON_REV_A4, 131},	
-	{MPU_SILICON_REV_A4, 131},	
-	{MPU_SILICON_REV_A4, 131},	
-	{MPU_SILICON_REV_A4, 131},	
-	{MPU_SILICON_REV_A4, 131},	
-	{MPU_SILICON_REV_B1, 131},	
-	{MPU_SILICON_REV_B1, 131},	
-	{MPU_SILICON_REV_B1, 131},	
-	{MPU_SILICON_REV_B1, 131},	
-	{MPU_SILICON_REV_B4, 131},	
-	{MPU_SILICON_REV_B4, 131},	
-	{MPU_SILICON_REV_B4, 131},	
-	{MPU_SILICON_REV_B4, 131},	
-	{MPU_SILICON_REV_B4, 115},	
-	{MPU_SILICON_REV_B4, 115},	
-	{MPU_SILICON_REV_B6, 131},	
-	{MPU_SILICON_REV_B4, 115},	
-	{MPU_SILICON_REV_B6, 0},	
-	{MPU_SILICON_REV_B6, 0},	
-	{MPU_SILICON_REV_B6, 0},	
-	{MPU_SILICON_REV_B6, 131},	
+	{MPU_SILICON_REV_A4, 131},	/* 1 A? OBSOLETED */
+	{MPU_SILICON_REV_A4, 131},	/* 2 | */
+	{MPU_SILICON_REV_A4, 131},	/* 3 V */
+	{MPU_SILICON_REV_A4, 131},	/* 4 */
+	{MPU_SILICON_REV_A4, 131},	/* 5 */
+	{MPU_SILICON_REV_A4, 131},	/* 6 */
+	{MPU_SILICON_REV_A4, 131},	/* 7 */
+	{MPU_SILICON_REV_A4, 131},	/* 8 */
+	{MPU_SILICON_REV_A4, 131},	/* 9 */
+	{MPU_SILICON_REV_A4, 131},	/* 10 */
+	{MPU_SILICON_REV_B1, 131},	/* 11 B1 */
+	{MPU_SILICON_REV_B1, 131},	/* 12 | */
+	{MPU_SILICON_REV_B1, 131},	/* 13 V */
+	{MPU_SILICON_REV_B1, 131},	/* 14 B4 */
+	{MPU_SILICON_REV_B4, 131},	/* 15 | */
+	{MPU_SILICON_REV_B4, 131},	/* 16 V */
+	{MPU_SILICON_REV_B4, 131},	/* 17 */
+	{MPU_SILICON_REV_B4, 131},	/* 18 */
+	{MPU_SILICON_REV_B4, 115},	/* 19  */
+	{MPU_SILICON_REV_B4, 115},	/* 20 */
+	{MPU_SILICON_REV_B6, 131},	/* 21 B6 (B6/A9)  */
+	{MPU_SILICON_REV_B4, 115},	/* 22 B4 (B7/A10) */
+	{MPU_SILICON_REV_B6, 0},	/* 23 B6 (npp)    */
+	{MPU_SILICON_REV_B6, 0},	/* 24 |  (npp)    */
+	{MPU_SILICON_REV_B6, 0},	/* 25 V  (npp)    */
+	{MPU_SILICON_REV_B6, 131},	/* 26    (B6/A11) */
 };
-#endif				
 
+/**
+ *  @internal
+ *  @brief  Get the silicon revision ID from OTP.
+ *          The silicon revision number is in read from OTP bank 0,
+ *          ADDR6[7:2].  The corresponding ID is retrieved by lookup
+ *          in a map.
+ *  @return The silicon revision ID (0 on error).
+ */
 static int MLDLGetSiliconRev(struct mldl_cfg *pdata,
 			     void *mlsl_handle)
 {
@@ -239,18 +286,14 @@
 
 	result = MLSLSerialReadMem(mlsl_handle, pdata->addr,
 				   memAddr, 1, &index);
-	ERROR_CHECK(result)
-	if (result)
-		return result;
+	ERROR_CHECK(result);
 	index >>= 2;
 
-	
+	/* clean the prefetch and cfg user bank bits */
 	result =
 	    MLSLSerialWriteSingle(mlsl_handle, pdata->addr,
 				  MPUREG_BANK_SEL, 0);
-	ERROR_CHECK(result)
-	if (result)
-		return result;
+	ERROR_CHECK(result);
 
 	if (index < OLDEST_PROD_REV_SUPPORTED || NUM_OF_PROD_REVS <= index) {
 		pdata->silicon_revision = 0;
@@ -271,23 +314,51 @@
 	return result;
 }
 
+/**
+ *  @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.
+ *
+ *  @pre    Must be called after MLSerialOpen().
+ *  @note   Typically called before MLDmpOpen().
+ *
+ *  @param[in]  enable:
+ *                  0 to run at VDDIO (default),
+ *                  1 to run at VDD.
+ *
+ *  @return ML_SUCCESS if successfull, a non-zero error code otherwise.
+ */
 static int MLDLSetLevelShifterBit(struct mldl_cfg *pdata,
 				  void *mlsl_handle,
 				  unsigned char enable)
 {
-#ifndef M_HW
 	int result;
 	unsigned char reg;
 	unsigned char mask;
-	unsigned char regval = 0;
+	unsigned char regval;
 
 	if (0 == pdata->silicon_revision)
 		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 --*/
 	if ((pdata->silicon_revision & 0xf) < MPU_SILICON_REV_B6) {
 		reg = MPUREG_ACCEL_BURST_ADDR;
 		mask = 0x80;
 	} else {
+		/*-- on B6 parts the VDDIO bit was moved to FIFO_EN2 =>
+		  the mask is always 0x04 --*/
 		reg = MPUREG_FIFO_EN2;
 		mask = 0x04;
 	}
@@ -305,106 +376,46 @@
 	    MLSLSerialWriteSingle(mlsl_handle, pdata->addr, reg, regval);
 
 	return result;
-#else
-	return ML_SUCCESS;
-#endif
 }
 
 
-#ifdef M_HW
-static tMLError mpu60xx_pwr_mgmt(struct mldl_cfg *pdata,
-				 void *mlsl_handle,
-				 unsigned char reset,
-				 unsigned char powerselection)
-{
-	unsigned char b;
-	tMLError result;
-
-	if (powerselection < 0 || powerselection > 7)
-		return ML_ERROR_INVALID_PARAMETER;
-
-	result =
-	    MLSLSerialRead(mlsl_handle, pdata->addr, MPUREG_PWR_MGMT_1, 1,
-			   &b);
-	ERROR_CHECK(result);
-
-	b &= ~(BITS_PWRSEL);
-
-	if (reset) {
-		result = MLSLSerialWriteSingle(mlsl_handle, pdata->addr,
-					       MPUREG_PWR_MGM, b | BIT_H_RESET);
-#define M_HW_RESET_ERRATTA
-#ifndef M_HW_RESET_ERRATTA
-		ERROR_CHECK(result);
-#else
-		MLOSSleep(50);
-#endif
-	}
-
-	b |= (powerselection << 4);
-
-	if (b & BITS_PWRSEL)
-		pdata->gyro_is_suspended = FALSE;
-	else
-		pdata->gyro_is_suspended = TRUE;
-
-	result = MLSLSerialWriteSingle(mlsl_handle, pdata->addr,
-				       MPUREG_PWR_MGM, b);
-	ERROR_CHECK(result);
-
-	return ML_SUCCESS;
-}
-
-static tMLError MLDLStandByGyros(struct mldl_cfg *pdata,
-				 void *mlsl_handle,
-				 unsigned char disable_gx,
-				 unsigned char disable_gy,
-				 unsigned char disable_gz)
-{
-	unsigned char b;
-	tMLError result;
-
-	result =
-	    MLSLSerialRead(mlsl_handle, pdata->addr, MPUREG_PWR_MGMT_2, 1,
-			   &b);
-	ERROR_CHECK(result);
-
-	b &= ~(BIT_STBY_XG | BIT_STBY_YG | BIT_STBY_ZG);
-	b |= (disable_gx << 2 | disable_gy << 1 | disable_gz);
-
-	result = MLSLSerialWriteSingle(mlsl_handle, pdata->addr,
-				       MPUREG_PWR_MGMT_2, b);
-	ERROR_CHECK(result);
-
-	return ML_SUCCESS;
-}
-
-static tMLError MLDLStandByAccels(struct mldl_cfg *pdata,
-				  void *mlsl_handle,
-				  unsigned char disable_ax,
-				  unsigned char disable_ay,
-				  unsigned char disable_az)
-{
-	unsigned char b;
-	tMLError result;
-
-	result =
-	    MLSLSerialRead(mlsl_handle, pdata->addr, MPUREG_PWR_MGMT_2, 1,
-			   &b);
-	ERROR_CHECK(result);
-
-	b &= ~(BIT_STBY_XA | BIT_STBY_YA | BIT_STBY_ZA);
-	b |= (disable_ax << 2 | disable_ay << 1 | disable_az);
-
-	result = MLSLSerialWriteSingle(mlsl_handle, pdata->addr,
-				       MPUREG_PWR_MGMT_2, b);
-	ERROR_CHECK(result);
-
-	return ML_SUCCESS;
-}
-
-#else				
-
+/**
+ * @internal
+ * @brief   This function controls the power management on the MPU device.
+ *          The entire chip can be put to low power sleep mode, or individual
+ *          gyros can be turned on/off.
+ *
+ *          Putting the device into sleep mode depending upon the changing needs
+ *          of the associated applications is a recommended method for reducing
+ *          power consuption.  It is a safe opearation in that sleep/wake up of
+ *          gyros while running will not result in any interruption of data.
+ *
+ *          Although it is entirely allowed to put the device into full sleep
+ *          while running the DMP, it is not recomended because it will disrupt
+ *          the ongoing calculations carried on inside the DMP and consequently
+ *          the sensor fusion algorithm. Furthermore, while in sleep mode
+ *          read & write operation from the app processor on both registers and
+ *          memory are disabled and can only regained by restoring the MPU in
+ *          normal power mode.
+ *          Disabling any of the gyro axis will reduce the associated power
+ *          consuption from the PLL but will not stop the DMP from running
+ *          state.
+ *
+ * @param   reset
+ *              Non-zero to reset the device. Note that this setting
+ *              is volatile and the corresponding register bit will
+ *              clear itself right after being applied.
+ * @param   sleep
+ *              Non-zero to put device into full sleep.
+ * @param   disable_gx
+ *              Non-zero to disable gyro X.
+ * @param   disable_gy
+ *              Non-zero to disable gyro Y.
+ * @param   disable_gz
+ *              Non-zero to disable gyro Z.
+ *
+ * @return  ML_SUCCESS if successfull; a non-zero error code otherwise.
+ */
 static int MLDLPowerMgmtMPU(struct mldl_cfg *pdata,
 			    void *mlsl_handle,
 			    unsigned char reset,
@@ -413,7 +424,7 @@
 			    unsigned char disable_gy,
 			    unsigned char disable_gz)
 {
-	unsigned char b = 0;
+	unsigned char b;
 	int result;
 
 	result =
@@ -421,15 +432,15 @@
 			   &b);
 	ERROR_CHECK(result);
 
-	
+	/* If we are awake, we need to put it in bypass before resetting */
 	if ((!(b & BIT_SLEEP)) && reset)
 		result = MLDLSetI2CBypass(pdata, mlsl_handle, 1);
 
-	
+	/* If we are awake, we need stop the dmp sleeping */
 	if ((!(b & BIT_SLEEP)) && sleep)
 		dmp_stop(pdata, mlsl_handle);
 
-	
+	/* Reset if requested */
 	if (reset) {
 		MPL_LOGV("Reset MPU3050\n");
 		result = MLSLSerialWriteSingle(mlsl_handle, pdata->addr,
@@ -437,18 +448,20 @@
 		ERROR_CHECK(result);
 		MLOSSleep(5);
 		pdata->gyro_needs_reset = FALSE;
+		/* Some chips are awake after reset and some are asleep,
+		 * check the status */
 		result = MLSLSerialRead(mlsl_handle, pdata->addr,
 					MPUREG_PWR_MGM, 1, &b);
 		ERROR_CHECK(result);
 	}
 
-	
+	/* Update the suspended state just in case we return early */
 	if (b & BIT_SLEEP)
 		pdata->gyro_is_suspended = TRUE;
 	else
 		pdata->gyro_is_suspended = FALSE;
 
-	
+	/* if power status match requested, nothing else's left to do */
 	if ((b & (BIT_SLEEP | BIT_STBY_XG | BIT_STBY_YG | BIT_STBY_ZG)) ==
 		(((sleep != 0) * BIT_SLEEP) |
 		((disable_gx != 0) * BIT_STBY_XG) |
@@ -457,6 +470,13 @@
 		return ML_SUCCESS;
 	}
 
+	/*
+	 * This specific transition between states needs to be reinterpreted:
+	 *    (1,1,1,1) -> (0,1,1,1) has to become
+	 *    (1,1,1,1) -> (1,0,0,0) -> (0,1,1,1)
+	 * where
+	 *    (1,1,1,1) is (sleep=1,disable_gx=1,disable_gy=1,disable_gz=1)
+	 */
 	if ((b & (BIT_SLEEP | BIT_STBY_XG | BIT_STBY_YG | BIT_STBY_ZG)) ==
 		 (BIT_SLEEP | BIT_STBY_XG | BIT_STBY_YG | BIT_STBY_ZG)
 		&& ((!sleep) && disable_gx && disable_gy && disable_gz)) {
@@ -487,6 +507,10 @@
 			MLOSSleep(5);
 		}
 	}
+	/*---
+	  WORKAROUND FOR PUTTING GYRO AXIS in STAND-BY MODE
+	  1) put one axis at a time in stand-by
+	  ---*/
 	if ((b & BIT_STBY_XG) != ((disable_gx != 0) * BIT_STBY_XG)) {
 		b ^= BIT_STBY_XG;
 		result = MLSLSerialWriteSingle(mlsl_handle, pdata->addr,
@@ -508,7 +532,6 @@
 
 	return ML_SUCCESS;
 }
-#endif				
 
 
 void mpu_print_cfg(struct mldl_cfg *mldl_cfg)
@@ -692,7 +715,7 @@
 		struct ext_slave_platform_data *slave_pdata)
 {
 	int result;
-	unsigned char reg = 0;
+	unsigned char reg;
 	unsigned char slave_reg;
 	unsigned char slave_len;
 	unsigned char slave_endian;
@@ -712,13 +735,13 @@
 		slave_address = slave_pdata->address;
 	}
 
-	
+	/* Address */
 	result = MLSLSerialWriteSingle(gyro_handle,
 				mldl_cfg->addr,
 				MPUREG_AUX_SLV_ADDR,
 				slave_address);
 	ERROR_CHECK(result);
-	
+	/* Register */
 	result = MLSLSerialRead(gyro_handle, mldl_cfg->addr,
 				MPUREG_ACCEL_BURST_ADDR, 1,
 				&reg);
@@ -730,26 +753,7 @@
 				reg);
 	ERROR_CHECK(result);
 
-#ifdef M_HW
-	
-	if (slave_len > BITS_SLV_LENG) {
-		MPL_LOGW("Limiting slave burst read length to "
-			"the allowed maximum (15B, req. %d)\n",
-			slave_len);
-		slave_len = BITS_SLV_LENG;
-	}
-	reg = slave_len;
-	if (slave_endian == EXT_SLAVE_LITTLE_ENDIAN)
-		reg |= BIT_SLV_BYTE_SW;
-	reg |= BIT_SLV_GRP;
-	reg |= BIT_SLV_ENABLE;
-
-	result = MLSLSerialWriteSingle(gyro_handle,
-				mldl_cfg->addr,
-				MPUREG_I2C_SLV0_CTRL,
-				reg);
-#else
-	
+	/* Length */
 	result = MLSLSerialRead(gyro_handle, mldl_cfg->addr,
 				MPUREG_USER_CTRL, 1, &reg);
 	ERROR_CHECK(result);
@@ -758,7 +762,6 @@
 				mldl_cfg->addr,
 				MPUREG_USER_CTRL, reg);
 	ERROR_CHECK(result);
-#endif
 
 	if (slave_address) {
 		result = MLDLSetI2CBypass(mldl_cfg, gyro_handle, FALSE);
@@ -767,10 +770,19 @@
 	return result;
 }
 
+/**
+ * Check to see if the gyro was reset by testing a couple of registers known
+ * to change on reset.
+ *
+ * @param mldl_cfg mldl configuration structure
+ * @param gyro_handle handle used to communicate with the gyro
+ *
+ * @return ML_SUCCESS or non-zero error code
+ */
 static int mpu_was_reset(struct mldl_cfg *mldl_cfg, void *gyro_handle)
 {
 	int result = ML_SUCCESS;
-	unsigned char reg = 0;
+	unsigned char reg;
 
 	result = MLSLSerialRead(gyro_handle, mldl_cfg->addr,
 				MPUREG_DMP_CFG_2, 1, &reg);
@@ -791,7 +803,7 @@
 	if (0 != mldl_cfg->divider)
 		return FALSE;
 
-	
+	/* Inconclusive assume it was reset */
 	return TRUE;
 }
 
@@ -800,32 +812,14 @@
 	int result;
 	int ii;
 	int jj;
-	unsigned char reg = 0;
+	unsigned char reg;
 	unsigned char regs[7];
 
-	
-#ifdef M_HW
-	result = mpu60xx_pwr_mgmt(mldl_cfg, gyro_handle, RESET,
-				WAKE_UP);
-	ERROR_CHECK(result);
-
-	
-	result = MLDLSetI2CBypass(mldl_cfg, gyro_handle, 1);
-	ERROR_CHECK(result);
-	result = MLSLSerialWriteSingle(gyro_handle, mldl_cfg->addr,
-				MPUREG_INT_PIN_CFG,
-				(mldl_cfg->pdata->int_config |
-					BIT_BYPASS_EN));
-	ERROR_CHECK(result);
-	result = MLSLSerialWriteSingle(gyro_handle, mldl_cfg->addr,
-				MPUREG_INT_ENABLE,
-				(mldl_cfg->int_config));
-	ERROR_CHECK(result);
-#else
+	/* Wake up the part */
 	result = MLDLPowerMgmtMPU(mldl_cfg, gyro_handle, 0, 0,
-				mldl_cfg->gyro_power & BIT_STBY_XG,
-				mldl_cfg->gyro_power & BIT_STBY_YG,
-				mldl_cfg->gyro_power & BIT_STBY_ZG);
+				gyro_power & BIT_STBY_XG,
+				gyro_power & BIT_STBY_YG,
+				gyro_power & BIT_STBY_ZG);
 
 	if (!mldl_cfg->gyro_needs_reset &&
 	    !mpu_was_reset(mldl_cfg, gyro_handle)) {
@@ -833,16 +827,15 @@
 	}
 
 	result = MLDLPowerMgmtMPU(mldl_cfg, gyro_handle, 1, 0,
-				mldl_cfg->gyro_power & BIT_STBY_XG,
-				mldl_cfg->gyro_power & BIT_STBY_YG,
-				mldl_cfg->gyro_power & BIT_STBY_ZG);
+				gyro_power & BIT_STBY_XG,
+				gyro_power & BIT_STBY_YG,
+				gyro_power & BIT_STBY_ZG);
 	ERROR_CHECK(result);
 	result = MLSLSerialWriteSingle(gyro_handle, mldl_cfg->addr,
 				MPUREG_INT_CFG,
 				(mldl_cfg->int_config |
 					mldl_cfg->pdata->int_config));
 	ERROR_CHECK(result);
-#endif
 
 	result = MLSLSerialRead(gyro_handle, mldl_cfg->addr,
 				MPUREG_PWR_MGM, 1, &reg);
@@ -857,19 +850,10 @@
 				mldl_cfg->divider);
 	ERROR_CHECK(result);
 
-#ifdef M_HW
-	reg = DLPF_FS_SYNC_VALUE(0, mldl_cfg->full_scale, 0);
-	result = MLSLSerialWriteSingle(gyro_handle, mldl_cfg->addr,
-				MPUREG_GYRO_CONFIG, reg);
-	reg = DLPF_FS_SYNC_VALUE(mldl_cfg->ext_sync, 0, mldl_cfg->lpf);
-	result = MLSLSerialWriteSingle(gyro_handle, mldl_cfg->addr,
-				MPUREG_CONFIG, reg);
-#else
 	reg = DLPF_FS_SYNC_VALUE(mldl_cfg->ext_sync,
 				mldl_cfg->full_scale, mldl_cfg->lpf);
 	result = MLSLSerialWriteSingle(gyro_handle, mldl_cfg->addr,
 				MPUREG_DLPF_FS_SYNC, reg);
-#endif
 	ERROR_CHECK(result);
 	result = MLSLSerialWriteSingle(gyro_handle, mldl_cfg->addr,
 				MPUREG_DMP_CFG_1,
@@ -880,9 +864,9 @@
 				mldl_cfg->dmp_cfg2);
 	ERROR_CHECK(result);
 
-	
+	/* Write and verify memory */
 	for (ii = 0; ii < MPU_MEM_NUM_RAM_BANKS; ii++) {
-		unsigned char read[MPU_MEM_BANK_SIZE] = {0};
+		unsigned char read[MPU_MEM_BANK_SIZE];
 
 		result = MLSLSerialWriteMem(gyro_handle,
 					mldl_cfg->addr,
@@ -895,13 +879,10 @@
 					MPU_MEM_BANK_SIZE, read);
 		ERROR_CHECK(result);
 
-#ifdef M_HW
-#define ML_SKIP_CHECK 38
-#else
 #define ML_SKIP_CHECK 20
-#endif
+
 		for (jj = 0; jj < MPU_MEM_BANK_SIZE; jj++) {
-			
+			/* skip the register memory locations */
 			if (ii == 0 && jj < ML_SKIP_CHECK)
 				continue;
 			if (mldl_cfg->ram[ii][jj] != read[jj]) {
@@ -936,22 +917,40 @@
 	result = MLSLSerialWrite(gyro_handle, mldl_cfg->addr, 7, regs);
 	ERROR_CHECK(result);
 
-	
+	/* Configure slaves */
 	result = MLDLSetLevelShifterBit(mldl_cfg, gyro_handle,
 					mldl_cfg->pdata->level_shifter);
 	ERROR_CHECK(result);
 	return result;
 }
+/*******************************************************************************
+ *******************************************************************************
+ * Exported functions
+ *******************************************************************************
+ ******************************************************************************/
 
+/**
+ * Initializes the pdata structure to defaults.
+ *
+ * Opens the device to read silicon revision, product id and whoami.
+ *
+ * @param mldl_cfg
+ *          The internal device configuration data structure.
+ * @param mlsl_handle
+ *          The serial communication handle.
+ *
+ * @return ML_SUCCESS if silicon revision, product id and woami are supported
+ *         by this software.
+ */
 int mpu3050_open(struct mldl_cfg *mldl_cfg,
 		 void *mlsl_handle,
 		 void *accel_handle,
 		 void *compass_handle,
-		 void *pressure_handle
-		 )
+		 void *pressure_handle)
 {
 	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;
@@ -962,7 +961,7 @@
 	mldl_cfg->ext_sync = 0;
 	mldl_cfg->dmp_cfg1 = 0;
 	mldl_cfg->dmp_cfg2 = 0;
-	mldl_cfg->gyro_power = 0;
+	gyro_power = 0;
 	mldl_cfg->gyro_is_bypassed = TRUE;
 	mldl_cfg->dmp_is_running = FALSE;
 	mldl_cfg->gyro_is_suspended = TRUE;
@@ -970,32 +969,26 @@
 	mldl_cfg->compass_is_suspended = TRUE;
 	mldl_cfg->pressure_is_suspended = TRUE;
 	mldl_cfg->gyro_needs_reset = FALSE;
-	if (mldl_cfg->addr == 0) {
-#ifdef __KERNEL__
+	if (mldl_cfg->addr == 0)
 		return ML_ERROR_INVALID_PARAMETER;
-#else
-		mldl_cfg->addr = 0x68;
-#endif
-	}
 
-#ifdef M_HW
-	result = mpu60xx_pwr_mgmt(mldl_cfg, mlsl_handle,
-				  RESET, WAKE_UP);
-#else
+	/*
+	 * Reset,
+	 * Take the DMP out of sleep, and
+	 * read the product_id, sillicon rev and whoami
+	 */
 	result = MLDLPowerMgmtMPU(mldl_cfg, mlsl_handle, RESET, 0, 0, 0, 0);
-#endif
 	ERROR_CHECK(result);
 
 	result = MLDLGetSiliconRev(mldl_cfg, mlsl_handle);
 	ERROR_CHECK(result);
-#ifndef M_HW
+
 	result = MLSLSerialRead(mlsl_handle, mldl_cfg->addr,
 				MPUREG_PRODUCT_ID, 1,
 				&mldl_cfg->product_id);
 	ERROR_CHECK(result);
-#endif
 
-	
+	/* Get the factory temperature compensation offsets */
 	result = MLSLSerialRead(mlsl_handle, mldl_cfg->addr,
 				MPUREG_XG_OFFS_TC, 1,
 				&mldl_cfg->offset_tc[0]);
@@ -1009,38 +1002,23 @@
 				&mldl_cfg->offset_tc[2]);
 	ERROR_CHECK(result);
 
-	
-#ifdef M_HW
-	result = mpu60xx_pwr_mgmt(mldl_cfg, mlsl_handle,
-				  FALSE, SLEEP);
-#else
+	/* Configure the MPU */
 	result =
 	    MLDLPowerMgmtMPU(mldl_cfg, mlsl_handle, 0, SLEEP, 0, 0, 0);
-#endif
+
 	ERROR_CHECK(result);
 
 	if (mldl_cfg->accel && mldl_cfg->accel->init) {
 		result = mldl_cfg->accel->init(accel_handle,
 					       mldl_cfg->accel,
-#ifdef CONFIG_CIR_ALWAYS_READY
-					       &mldl_cfg->pdata->accel,
-					       mldl_cfg->pdata->power_LPM);
-#else
 					       &mldl_cfg->pdata->accel);
-#endif
-
 		ERROR_CHECK(result);
 	}
 
 	if (mldl_cfg->compass && mldl_cfg->compass->init) {
 		result = mldl_cfg->compass->init(compass_handle,
 						 mldl_cfg->compass,
-#ifdef CONFIG_CIR_ALWAYS_READY
-						 &mldl_cfg->pdata->compass,
-						 NULL);
-#else
 						 &mldl_cfg->pdata->compass);
-#endif
 		if (ML_SUCCESS != result) {
 			MPL_LOGE("mldl_cfg->compass->init returned %d\n",
 				result);
@@ -1050,12 +1028,7 @@
 	if (mldl_cfg->pressure && mldl_cfg->pressure->init) {
 		result = mldl_cfg->pressure->init(pressure_handle,
 						  mldl_cfg->pressure,
-#ifdef CONFIG_CIR_ALWAYS_READY
-						  &mldl_cfg->pdata->pressure,
-						  NULL);
-#else
 						  &mldl_cfg->pdata->pressure);
-#endif
 		if (ML_SUCCESS != result) {
 			MPL_LOGE("mldl_cfg->pressure->init returned %d\n",
 				result);
@@ -1076,12 +1049,12 @@
 	return result;
 
 out_compass:
-	if (mldl_cfg->compass->init)
+	if (mldl_cfg->compass && mldl_cfg->compass->init)
 		mldl_cfg->compass->exit(compass_handle,
 				mldl_cfg->compass,
 				&mldl_cfg->pdata->compass);
 out_accel:
-	if (mldl_cfg->accel->init)
+	if (mldl_cfg->accel && mldl_cfg->accel->init)
 		mldl_cfg->accel->exit(accel_handle,
 				mldl_cfg->accel,
 				&mldl_cfg->pdata->accel);
@@ -1089,6 +1062,14 @@
 
 }
 
+/**
+ * Close the mpu3050 interface
+ *
+ * @param mldl_cfg pointer to the configuration structure
+ * @param mlsl_handle pointer to the serial layer handle
+ *
+ * @return ML_SUCCESS or non-zero error code
+ */
 int mpu3050_close(struct mldl_cfg *mldl_cfg,
 		  void *mlsl_handle,
 		  void *accel_handle,
@@ -1132,6 +1113,47 @@
 	return ret_result;
 }
 
+/**
+ *  @brief  resume the MPU3050 device and all the other sensor
+ *          devices from their low power state.
+ *
+ *  @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
+ *              onto a separate bus. Can match mlsl_handle if
+ *              the accelerometer device operates on the same
+ *              primary bus of MPU.
+ *  @param  compass_handle
+ *              an handle to the compass device, if sitting
+ *              onto a separate bus. Can match mlsl_handle if
+ *              the compass device operates on the same
+ *              primary bus of MPU.
+ *  @param  pressure_handle
+ *              an handle to the pressure sensor device, if sitting
+ *              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
+ *              mode of some sort).
+ *  @param  resume_compass
+ *              whether resuming the compass device is
+ *              actually needed (if the device supports low power
+ *              mode of some sort).
+ *  @param  resume_pressure
+ *              whether resuming the pressure sensor device is
+ *              actually needed (if the device supports low power
+ *              mode of some sort).
+ *  @return  ML_SUCCESS or a non-zero error code.
+ */
 int mpu3050_resume(struct mldl_cfg *mldl_cfg,
 		   void *gyro_handle,
 		   void *accel_handle,
@@ -1231,7 +1253,7 @@
 		ERROR_CHECK(result);
 	}
 
-	
+	/* Now start */
 	if (resume_gyro) {
 		result = dmp_start(mldl_cfg, gyro_handle);
 		ERROR_CHECK(result);
@@ -1240,6 +1262,40 @@
 	return result;
 }
 
+/**
+ *  @brief  suspend the MPU3050 device and all the other sensor
+ *          devices into their low power state.
+ *  @param  gyro_handle
+ *              the main file handle to the MPU3050 device.
+ *  @param  accel_handle
+ *              an handle to the accelerometer device, if sitting
+ *              onto a separate bus. Can match gyro_handle if
+ *              the accelerometer device operates on the same
+ *              primary bus of MPU.
+ *  @param  compass_handle
+ *              an handle to the compass device, if sitting
+ *              onto a separate bus. Can match gyro_handle if
+ *              the compass device operates on the same
+ *              primary bus of MPU.
+ *  @param  pressure_handle
+ *              an handle to the pressure sensor device, if sitting
+ *              onto a separate bus. Can match gyro_handle if
+ *              the pressure sensor device operates on the same
+ *              primary bus of MPU.
+ *  @param  accel
+ *              whether suspending the accelerometer device is
+ *              actually needed (if the device supports low power
+ *              mode of some sort).
+ *  @param  compass
+ *              whether suspending the compass device is
+ *              actually needed (if the device supports low power
+ *              mode of some sort).
+ *  @param  pressure
+ *              whether suspending the pressure sensor device is
+ *              actually needed (if the device supports low power
+ *              mode of some sort).
+ *  @return  ML_SUCCESS or a non-zero error code.
+ */
 int mpu3050_suspend(struct mldl_cfg *mldl_cfg,
 		    void *gyro_handle,
 		    void *accel_handle,
@@ -1253,16 +1309,8 @@
 	int result = ML_SUCCESS;
 
 	if (suspend_gyro && !mldl_cfg->gyro_is_suspended) {
-#ifdef M_HW
-		return ML_SUCCESS;
-		
-		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);
-#endif
 		ERROR_CHECK(result);
 	}
 
@@ -1316,6 +1364,17 @@
 }
 
 
+/**
+ *  @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.
+ */
 int mpu3050_read_accel(struct mldl_cfg *mldl_cfg,
 		       void *accel_handle, unsigned char *data)
 {
@@ -1332,6 +1391,17 @@
 		return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
 }
 
+/**
+ *  @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.
+ */
 int mpu3050_read_compass(struct mldl_cfg *mldl_cfg,
 			 void *compass_handle, unsigned char *data)
 {
@@ -1348,6 +1418,17 @@
 		return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
 }
 
+/**
+ *  @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.
+ */
 int mpu3050_read_pressure(struct mldl_cfg *mldl_cfg,
 			 void *pressure_handle, unsigned char *data)
 {
@@ -1447,5 +1528,3 @@
 	else
 		return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
 }
-
-
diff --git a/drivers/input/misc/mpu3050/mldl_cfg.h b/drivers/input/misc/mpu3050/mldl_cfg.h
index f838565..3c3cc9a 100644
--- a/drivers/input/misc/mpu3050/mldl_cfg.h
+++ b/drivers/input/misc/mpu3050/mldl_cfg.h
@@ -17,18 +17,31 @@
   $
  */
 
+/**
+ *  @addtogroup MLDL
+ *
+ *  @{
+ *      @file   mldl_cfg.h
+ *      @brief  The Motion Library Driver Layer Configuration header file.
+ */
 
 #ifndef __MLDL_CFG_H__
 #define __MLDL_CFG_H__
 
+/* ------------------ */
+/* - Include Files. - */
+/* ------------------ */
 
 #include "mlsl.h"
-#include "mpu.h"
+#include <linux/mpu.h>
 
+/* --------------------- */
+/* -    Defines.       - */
+/* --------------------- */
 
-    
-    
-    
+/*************************************************************************/
+/*  Sensors                                                              */
+/*************************************************************************/
 
 #define ML_X_GYRO			(0x0001)
 #define ML_Y_GYRO			(0x0002)
@@ -72,10 +85,25 @@
 	(((((mldl_cfg)->lpf) == 0) || (((mldl_cfg)->lpf) == 7))		\
 		? (8000)						\
 		: (1000)))
+/* --------------------- */
+/* -    Variables.     - */
+/* --------------------- */
 
+/* Compat version of mpu3050_platform_data struct */
+struct mpu_compat_platform_data {
+	unsigned char int_config;
+	signed char orientation[GYRO_NUM_AXES * GYRO_NUM_AXES];
+	unsigned char level_shifter;
+	struct ext_slave_platform_data accel;
+	struct ext_slave_platform_data compass;
+	struct ext_slave_platform_data pressure;
+};
+
+/* Platform data for the MPU */
 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;
@@ -87,18 +115,19 @@
 	unsigned char fifo_enable;
 	unsigned char dmp_cfg1;
 	unsigned char dmp_cfg2;
-	unsigned char gyro_power;
-	unsigned char offset_tc[MPU_NUM_AXES];
-	unsigned short offset[MPU_NUM_AXES];
+	unsigned char offset_tc[GYRO_NUM_AXES];
+	unsigned short offset[GYRO_NUM_AXES];
 	unsigned char ram[MPU_MEM_NUM_RAM_BANKS][MPU_MEM_BANK_SIZE];
 
-	
+	/* MPU Related stored status and info */
+	unsigned char product_revision;
 	unsigned char silicon_revision;
 	unsigned char product_id;
 	unsigned short trim;
 
-	
+	/* Driver/Kernel related state information */
 	int gyro_is_bypassed;
+	int i2c_slaves_enabled;
 	int dmp_is_running;
 	int gyro_is_suspended;
 	int accel_is_suspended;
@@ -106,12 +135,12 @@
 	int pressure_is_suspended;
 	int gyro_needs_reset;
 
-	
+	/* Slave related information */
 	struct ext_slave_descr *accel;
 	struct ext_slave_descr *compass;
 	struct ext_slave_descr *pressure;
 
-	
+	/* Platform Data */
 	struct mpu3050_platform_data *pdata;
 };
 
@@ -173,6 +202,7 @@
 				void *pressure_handle,
 				struct ext_slave_config *data);
 
+extern struct mutex mutex_fifo_reading_access_lock;
 
-#endif				
+#endif				/* __MLDL_CFG_H__ */
 
diff --git a/drivers/input/misc/mpu3050/mlos-kernel.c b/drivers/input/misc/mpu3050/mlos-kernel.c
index 109957b..3d6cb7f 100644
--- a/drivers/input/misc/mpu3050/mlos-kernel.c
+++ b/drivers/input/misc/mpu3050/mlos-kernel.c
@@ -16,6 +16,16 @@
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
   $
  */
+/**
+ * @defgroup
+ * @brief
+ *
+ * @{
+ * @file     mlos-kernel.c
+ * @brief
+ *
+ *
+ */
 
 #include "mlos.h"
 #include <linux/delay.h>
@@ -26,45 +36,45 @@
 	return kmalloc(numBytes, GFP_KERNEL);
 }
 
-tMLError MLOSFree(void *ptr)
+unchar MLOSFree(void *ptr)
 {
 	kfree(ptr);
 	return ML_SUCCESS;
 }
 
-tMLError MLOSCreateMutex(HANDLE *mutex)
+unchar MLOSCreateMutex(uint *mutex)
 {
-	
+	/* @todo implement if needed */
 	return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
 }
 
-tMLError MLOSLockMutex(HANDLE mutex)
+unchar MLOSLockMutex(uint mutex)
 {
-	
+	/* @todo implement if needed */
 	return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
 }
 
-tMLError MLOSUnlockMutex(HANDLE mutex)
+unchar MLOSUnlockMutex(uint mutex)
 {
-	
+	/* @todo implement if needed */
 	return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
 }
 
-tMLError MLOSDestroyMutex(HANDLE handle)
+unchar MLOSDestroyMutex(uint handle)
 {
-	
+	/* @todo implement if needed */
 	return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
 }
 
-FILE *MLOSFOpen(char *filename)
+uint *MLOSFOpen(char *filename)
 {
-	
+	/* @todo implement if needed */
 	return NULL;
 }
 
-void MLOSFClose(FILE *fp)
+void MLOSFClose(uint *fp)
 {
-	
+	/* @todo implement if needed */
 }
 
 void MLOSSleep(int mSecs)
@@ -74,6 +84,6 @@
 
 unsigned long MLOSGetTickCount(void)
 {
-	
+	/* @todo implement if needed */
 	return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
 }
diff --git a/drivers/input/misc/mpu3050/mlos.h b/drivers/input/misc/mpu3050/mlos.h
index c0668574..ce9bf10 100644
--- a/drivers/input/misc/mpu3050/mlos.h
+++ b/drivers/input/misc/mpu3050/mlos.h
@@ -20,21 +20,17 @@
 #ifndef _MLOS_H
 #define _MLOS_H
 
-#ifndef __KERNEL__
-#include <stdio.h>
-#endif
-
 #include "mltypes.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-	
-	
-	
+/* ------------ */
+/* - Defines. - */
+/* ------------ */
 
-	
+/* - MLOSCreateFile defines. - */
 
 #define MLOS_GENERIC_READ         ((unsigned int)0x80000000)
 #define MLOS_GENERIC_WRITE        ((unsigned int)0x40000000)
@@ -42,32 +38,32 @@
 #define MLOS_FILE_SHARE_WRITE     ((unsigned int)0x00000002)
 #define MLOS_OPEN_EXISTING        ((unsigned int)0x00000003)
 
-	
-	
-	
+/* ---------- */
+/* - Enums. - */
+/* ---------- */
 
-	
-	
-	
+/* --------------- */
+/* - Structures. - */
+/* --------------- */
 
-	
-	
-	
+/* --------------------- */
+/* - Function p-types. - */
+/* --------------------- */
 
-	void *MLOSMalloc(unsigned int numBytes);
-	tMLError MLOSFree(void *ptr);
-	tMLError MLOSCreateMutex(HANDLE *mutex);
-	tMLError MLOSLockMutex(HANDLE mutex);
-	tMLError MLOSUnlockMutex(HANDLE mutex);
-	FILE *MLOSFOpen(char *filename);
-	void MLOSFClose(FILE *fp);
+void *MLOSMalloc(unsigned int numBytes);
+unchar MLOSFree(void *ptr);
+unchar MLOSCreateMutex(uint *mutex);
+unchar MLOSLockMutex(uint mutex);
+unchar MLOSUnlockMutex(uint mutex);
+uint *MLOSFOpen(char *filename);
+void MLOSFClose(uint *fp);
 
-	tMLError MLOSDestroyMutex(HANDLE handle);
+unchar MLOSDestroyMutex(uint handle);
 
-	void MLOSSleep(int mSecs);
-	unsigned long MLOSGetTickCount(void);
+void MLOSSleep(int mSecs);
+unsigned long MLOSGetTickCount(void);
 
 #ifdef __cplusplus
 }
 #endif
-#endif				
+#endif				/* _MLOS_H */
diff --git a/drivers/input/misc/mpu3050/mlsl-kernel.c b/drivers/input/misc/mpu3050/mlsl-kernel.c
index d5bc256..c0bb886 100644
--- a/drivers/input/misc/mpu3050/mlsl-kernel.c
+++ b/drivers/input/misc/mpu3050/mlsl-kernel.c
@@ -20,39 +20,86 @@
 #include "mlsl.h"
 #include "mpu-i2c.h"
 
+/* ------------ */
+/* - Defines. - */
+/* ------------ */
 
+/* ---------------------- */
+/* - Types definitions. - */
+/* ---------------------- */
 
+/* --------------------- */
+/* - Function p-types. - */
+/* --------------------- */
 
-tMLError MLSLSerialOpen(char const *port, void **sl_handle)
+/**
+ *  @brief  used to open the I2C or SPI serial port.
+ *          This port is used to send and receive data to the MPU device.
+ *  @param  portNum
+ *              The COM port number associated with the device in use.
+ *  @return ML_SUCCESS if successful, a non-zero error code otherwise.
+ */
+unchar MLSLSerialOpen(char const *port, void **sl_handle)
 {
 	return ML_SUCCESS;
 }
 
-tMLError MLSLSerialReset(void *sl_handle)
+/**
+ *  @brief  used to reset any buffering the driver may be doing
+ *  @return ML_SUCCESS if successful, a non-zero error code otherwise.
+ */
+unchar MLSLSerialReset(void *sl_handle)
 {
 	return ML_SUCCESS;
 }
 
-tMLError MLSLSerialClose(void *sl_handle)
+/**
+ *  @brief  used to close the I2C or SPI serial port.
+ *          This port is used to send and receive data to the MPU device.
+ *  @return ML_SUCCESS if successful, a non-zero error code otherwise.
+ */
+unchar MLSLSerialClose(void *sl_handle)
 {
 	return ML_SUCCESS;
 }
 
-tMLError MLSLSerialWriteSingle(void *sl_handle,
+/**
+ *  @brief  used to read a single byte of data.
+ *          This should be sent by I2C or SPI.
+ *
+ *  @param  slaveAddr       I2C slave address of device.
+ *  @param  registerAddr    Register address to read.
+ *  @param  data            Single byte of data to read.
+ *
+ *  @return ML_SUCCESS if the command is successful, an error code otherwise.
+ */
+unchar MLSLSerialWriteSingle(void *sl_handle,
 			       unsigned char slaveAddr,
 			       unsigned char registerAddr,
 			       unsigned char data)
 {
 	return sensor_i2c_write_register((struct i2c_adapter *) sl_handle,
-					 slaveAddr, registerAddr, data);
+				slaveAddr, registerAddr, data);
 }
 
 
-tMLError MLSLSerialWrite(void *sl_handle,
+/**
+ *  @brief  used to write multiple bytes of data from registers.
+ *          This should be sent by I2C.
+ *
+ *  @param  slaveAddr       I2C slave address of device.
+ *  @param  registerAddr    Register address to write.
+ *  @param  length          Length of burst of data.
+ *  @param  data            Pointer to block of data.
+ *
+ *  @return ML_SUCCESS if successful, a non-zero error code otherwise.
+ */
+unchar MLSLSerialWrite(void *sl_handle,
 			 unsigned char slaveAddr,
-			 unsigned short length, unsigned char const *data)
+			 unsigned short length,
+			 unsigned char const *data)
 {
-	tMLError result;
+	unchar result;
 	const unsigned short dataLength = length - 1;
 	const unsigned char startRegAddr = data[0];
 	unsigned char i2cWrite[SERIAL_MAX_TRANSFER_SIZE + 1];
@@ -66,7 +113,7 @@
 						  sl_handle, slaveAddr,
 						  1 + thisLen, data);
 		} else {
-			
+			/* manually increment register addr between chunks */
 			i2cWrite[0] = startRegAddr + bytesWritten;
 			memcpy(&i2cWrite[1], &data[1 + bytesWritten],
 			       thisLen);
@@ -82,12 +129,23 @@
 }
 
 
-tMLError MLSLSerialRead(void *sl_handle,
+/**
+ *  @brief  used to read multiple bytes of data from registers.
+ *          This should be sent by I2C.
+ *
+ *  @param  slaveAddr       I2C slave address of device.
+ *  @param  registerAddr    Register address to read.
+ *  @param  length          Length of burst of data.
+ *  @param  data            Pointer to block of data.
+ *
+ *  @return Zero if successful; an error code otherwise
+ */
+unchar MLSLSerialRead(void *sl_handle,
 			unsigned char slaveAddr,
 			unsigned char registerAddr,
 			unsigned short length, unsigned char *data)
 {
-	tMLError result;
+	unchar result;
 	unsigned short bytesRead = 0;
 
 	if (registerAddr == MPUREG_FIFO_R_W
@@ -109,20 +167,30 @@
 }
 
 
-tMLError MLSLSerialWriteMem(void *sl_handle,
+/**
+ *  @brief  used to write multiple bytes of data to the memory.
+ *          This should be sent by I2C.
+ *
+ *  @param  slaveAddr       I2C slave address of device.
+ *  @param  memAddr         The location in the memory to write to.
+ *  @param  length          Length of burst data.
+ *  @param  data            Pointer to block of data.
+ *
+ *  @return Zero if successful; an error code otherwise
+ */
+unchar MLSLSerialWriteMem(void *sl_handle,
 			    unsigned char slaveAddr,
 			    unsigned short memAddr,
 			    unsigned short length,
 			    unsigned char const *data)
 {
-	tMLError result;
+	unchar result;
 	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) {
@@ -140,12 +208,23 @@
 }
 
 
-tMLError MLSLSerialReadMem(void *sl_handle,
+/**
+ *  @brief  used to read multiple bytes of data from the memory.
+ *          This should be sent by I2C.
+ *
+ *  @param  slaveAddr       I2C slave address of device.
+ *  @param  memAddr         The location in the memory to read from.
+ *  @param  length          Length of burst data.
+ *  @param  data            Pointer to block of data.
+ *
+ *  @return Zero if successful; an error code otherwise
+ */
+unchar MLSLSerialReadMem(void *sl_handle,
 			   unsigned char slaveAddr,
 			   unsigned short memAddr,
 			   unsigned short length, unsigned char *data)
 {
-	tMLError result;
+	unchar result;
 	unsigned short bytesRead = 0;
 
 	if ((memAddr & 0xFF) + length > MPU_MEM_BANK_SIZE) {
@@ -170,12 +249,22 @@
 }
 
 
-tMLError MLSLSerialWriteFifo(void *sl_handle,
+/**
+ *  @brief  used to write multiple bytes of data to the fifo.
+ *          This should be sent by I2C.
+ *
+ *  @param  slaveAddr       I2C slave address of device.
+ *  @param  length          Length of burst of data.
+ *  @param  data            Pointer to block of data.
+ *
+ *  @return Zero if successful; an error code otherwise
+ */
+unchar MLSLSerialWriteFifo(void *sl_handle,
 			     unsigned char slaveAddr,
 			     unsigned short length,
 			     unsigned char const *data)
 {
-	tMLError result;
+	unchar result;
 	unsigned char i2cWrite[SERIAL_MAX_TRANSFER_SIZE + 1];
 	unsigned short bytesWritten = 0;
 
@@ -200,11 +289,21 @@
 }
 
 
-tMLError MLSLSerialReadFifo(void *sl_handle,
+/**
+ *  @brief  used to read multiple bytes of data from the fifo.
+ *          This should be sent by I2C.
+ *
+ *  @param  slaveAddr       I2C slave address of device.
+ *  @param  length          Length of burst of data.
+ *  @param  data            Pointer to block of data.
+ *
+ *  @return Zero if successful; an error code otherwise
+ */
+unchar MLSLSerialReadFifo(void *sl_handle,
 			    unsigned char slaveAddr,
 			    unsigned short length, unsigned char *data)
 {
-	tMLError result;
+	unchar result;
 	unsigned short bytesRead = 0;
 
 	if (length > FIFO_HW_SIZE) {
@@ -226,4 +325,3 @@
 
 	return ML_SUCCESS;
 }
-
diff --git a/drivers/input/misc/mpu3050/mlsl.h b/drivers/input/misc/mpu3050/mlsl.h
index e1e796c..3b6550e 100644
--- a/drivers/input/misc/mpu3050/mlsl.h
+++ b/drivers/input/misc/mpu3050/mlsl.h
@@ -21,66 +21,79 @@
 #define __MSSL_H__
 
 #include "mltypes.h"
-#include "mpu.h"
+#include <linux/mpu.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/* ------------ */
+/* - Defines. - */
+/* ------------ */
 
+/*
+ * NOTE : to properly support Yamaha compass reads,
+ * the max transfer size should be at least 9 B.
+ * Length in bytes, typically a power of 2 >= 2
+ */
 #define SERIAL_MAX_TRANSFER_SIZE 128
 
+/* ---------------------- */
+/* - Types definitions. - */
+/* ---------------------- */
 
+/* --------------------- */
+/* - Function p-types. - */
+/* --------------------- */
 
-	tMLError MLSLSerialOpen(char const *port,
-				void **sl_handle);
-	tMLError MLSLSerialReset(void *sl_handle);
-	tMLError MLSLSerialClose(void *sl_handle);
+unchar MLSLSerialOpen(char const *port,
+			void **sl_handle);
+unchar MLSLSerialReset(void *sl_handle);
+unchar MLSLSerialClose(void *sl_handle);
 
-	tMLError MLSLSerialWriteSingle(void *sl_handle,
-				       unsigned char slaveAddr,
-				       unsigned char registerAddr,
-				       unsigned char data);
+unchar MLSLSerialWriteSingle(void *sl_handle,
+			       unsigned char slaveAddr,
+			       unsigned char registerAddr,
+			       unsigned char data);
 
-	tMLError MLSLSerialRead(void *sl_handle,
-				unsigned char slaveAddr,
-				unsigned char registerAddr,
-				unsigned short length,
-				unsigned char *data);
+unchar MLSLSerialRead(void *sl_handle,
+			unsigned char slaveAddr,
+			unsigned char registerAddr,
+			unsigned short length,
+			unsigned char *data);
 
-	tMLError MLSLSerialWrite(void *sl_handle,
-				 unsigned char slaveAddr,
-				 unsigned short length,
-				 unsigned char const *data);
+unchar MLSLSerialWrite(void *sl_handle,
+			 unsigned char slaveAddr,
+			 unsigned short length,
+			 unsigned char const *data);
 
-	tMLError MLSLSerialReadMem(void *sl_handle,
-				   unsigned char slaveAddr,
-				   unsigned short memAddr,
-				   unsigned short length,
-				   unsigned char *data);
+unchar MLSLSerialReadMem(void *sl_handle,
+			   unsigned char slaveAddr,
+			   unsigned short memAddr,
+			   unsigned short length,
+			   unsigned char *data);
 
-	tMLError MLSLSerialWriteMem(void *sl_handle,
-				    unsigned char slaveAddr,
-				    unsigned short memAddr,
-				    unsigned short length,
-				    unsigned char const *data);
+unchar MLSLSerialWriteMem(void *sl_handle,
+			    unsigned char slaveAddr,
+			    unsigned short memAddr,
+			    unsigned short length,
+			    unsigned char const *data);
 
-	tMLError MLSLSerialReadFifo(void *sl_handle,
-				    unsigned char slaveAddr,
-				    unsigned short length,
-				    unsigned char *data);
+unchar MLSLSerialReadFifo(void *sl_handle,
+			    unsigned char slaveAddr,
+			    unsigned short length,
+			    unsigned char *data);
 
-	tMLError MLSLSerialWriteFifo(void *sl_handle,
-				     unsigned char slaveAddr,
-				     unsigned short length,
-				     unsigned char const *data);
+unchar MLSLSerialWriteFifo(void *sl_handle,
+			     unsigned char slaveAddr,
+			     unsigned short length,
+			     unsigned char const *data);
 
-	tMLError MLSLWriteCal(unsigned char *cal, unsigned int len);
-	tMLError MLSLReadCal(unsigned char *cal, unsigned int len);
-	tMLError MLSLGetCalLength(unsigned int *len);
+unchar MLSLWriteCal(unsigned char *cal, unsigned int len);
+unchar MLSLReadCal(unsigned char *cal, unsigned int len);
+unchar MLSLGetCalLength(unsigned int *len);
 
 #ifdef __cplusplus
 }
 #endif
-
-#endif				
+#endif				/* MLSL_H */
diff --git a/drivers/input/misc/mpu3050/mltypes.h b/drivers/input/misc/mpu3050/mltypes.h
index d3f4acc..1271133 100644
--- a/drivers/input/misc/mpu3050/mltypes.h
+++ b/drivers/input/misc/mpu3050/mltypes.h
@@ -17,6 +17,66 @@
   $
  */
 
+/**
+ *  @defgroup MLERROR
+ *  @brief  Motion Library - Error definitions.
+ *          Definition of the error codes used within the MPL and returned
+ *          to the user.
+ *          Every function tries to return a meaningful error code basing
+ *          on the occuring error condition. The error code is numeric.
+ *
+ *          The available error codes and their associated values are:
+ *          - (0)       ML_SUCCESS
+ *          - (1)       ML_ERROR
+ *          - (2)       ML_ERROR_INVALID_PARAMETER
+ *          - (3)       ML_ERROR_FEATURE_NOT_ENABLED
+ *          - (4)       ML_ERROR_FEATURE_NOT_IMPLEMENTED
+ *          - (6)       ML_ERROR_DMP_NOT_STARTED
+ *          - (7)       ML_ERROR_DMP_STARTED
+ *          - (8)       ML_ERROR_NOT_OPENED
+ *          - (9)       ML_ERROR_OPENED
+ *          - (10)      ML_ERROR_INVALID_MODULE
+ *          - (11)      ML_ERROR_MEMORY_EXAUSTED
+ *          - (12)      ML_ERROR_DIVIDE_BY_ZERO
+ *          - (13)      ML_ERROR_ASSERTION_FAILURE
+ *          - (14)      ML_ERROR_FILE_OPEN
+ *          - (15)      ML_ERROR_FILE_READ
+ *          - (16)      ML_ERROR_FILE_WRITE
+ *          - (20)      ML_ERROR_SERIAL_CLOSED
+ *          - (21)      ML_ERROR_SERIAL_OPEN_ERROR
+ *          - (22)      ML_ERROR_SERIAL_READ
+ *          - (23)      ML_ERROR_SERIAL_WRITE
+ *          - (24)      ML_ERROR_SERIAL_DEVICE_NOT_RECOGNIZED
+ *          - (25)      ML_ERROR_SM_TRANSITION
+ *          - (26)      ML_ERROR_SM_IMPROPER_STATE
+ *          - (30)      ML_ERROR_FIFO_OVERFLOW
+ *          - (31)      ML_ERROR_FIFO_FOOTER
+ *          - (32)      ML_ERROR_FIFO_READ_COUNT
+ *          - (33)      ML_ERROR_FIFO_READ_DATA
+ *          - (40)      ML_ERROR_MEMORY_SET
+ *          - (50)      ML_ERROR_LOG_MEMORY_ERROR
+ *          - (51)      ML_ERROR_LOG_OUTPUT_ERROR
+ *          - (60)      ML_ERROR_OS_BAD_PTR
+ *          - (61)      ML_ERROR_OS_BAD_HANDLE
+ *          - (62)      ML_ERROR_OS_CREATE_FAILED
+ *          - (63)      ML_ERROR_OS_LOCK_FAILED
+ *          - (70)      ML_ERROR_COMPASS_DATA_OVERFLOW
+ *          - (71)      ML_ERROR_COMPASS_DATA_UNDERFLOW
+ *          - (72)      ML_ERROR_COMPASS_DATA_NOT_READY
+ *          - (73)      ML_ERROR_COMPASS_DATA_ERROR
+ *          - (75)      ML_ERROR_CALIBRATION_LOAD
+ *          - (76)      ML_ERROR_CALIBRATION_STORE
+ *          - (77)      ML_ERROR_CALIBRATION_LEN
+ *          - (78)      ML_ERROR_CALIBRATION_CHECKSUM
+ *          - (79)      ML_ERROR_ACCEL_DATA_OVERFLOW
+ *          - (80)      ML_ERROR_ACCEL_DATA_UNDERFLOW
+ *          - (81)      ML_ERROR_ACCEL_DATA_NOT_READY
+ *          - (82)      ML_ERROR_ACCEL_DATA_ERROR
+ *
+ *  @{
+ *      @file mltypes.h
+ *  @}
+ */
 
 #ifndef MLTYPES_H
 #define MLTYPES_H
@@ -28,7 +88,18 @@
 #endif
 #include "log.h"
 
+/*---------------------------
+    ML Types
+---------------------------*/
 
+/**
+ *  @struct tMLError mltypes.h "mltypes"
+ *  @brief  The MPL Error Code return type.
+ *
+ *  @code
+ *      typedef unsigned char tMLError;
+ *  @endcode
+ */
 typedef unsigned char tMLError;
 
 #if defined(LINUX) || defined(__KERNEL__)
@@ -45,6 +116,9 @@
 #endif
 #endif
 
+/*---------------------------
+    ML Defines
+---------------------------*/
 
 #ifndef NULL
 #define NULL 0
@@ -58,10 +132,12 @@
 #define FALSE 0
 #endif
 
+/* Dimension of an array */
 #ifndef DIM
 #define DIM(array) (sizeof(array)/sizeof((array)[0]))
 #endif
 
+/* - ML Errors. - */
 #define ERROR_NAME(x)   (#x)
 #define ERROR_CHECK(x)                                                  \
 	{								\
@@ -72,12 +148,24 @@
 		}							\
 	}
 
+#define ERROR_CHECK_MUTEX(x, y)                                         \
+	do {								\
+		if (ML_SUCCESS != x) {					\
+			MPL_LOGE("%s|%s|%d returning %d\n",		\
+				__FILE__, __func__, __LINE__, x);	\
+			mutex_unlock(&y);				\
+			return x;					\
+		}							\
+	} while (0)
+
 #define ERROR_CHECK_FIRST(first, x)                                     \
 	{ if (ML_SUCCESS == first) first = x; }
 
 #define ML_SUCCESS                       (0)
+/* Generic Error code.  Proprietary Error Codes only */
 #define ML_ERROR                         (1)
 
+/* Compatibility and other generic error codes */
 #define ML_ERROR_INVALID_PARAMETER       (2)
 #define ML_ERROR_FEATURE_NOT_ENABLED     (3)
 #define ML_ERROR_FEATURE_NOT_IMPLEMENTED (4)
@@ -94,45 +182,60 @@
 #define ML_ERROR_FILE_WRITE             (16)
 #define ML_ERROR_INVALID_CONFIGURATION  (17)
 
+/* Serial Communication */
 #define ML_ERROR_SERIAL_CLOSED          (20)
 #define ML_ERROR_SERIAL_OPEN_ERROR      (21)
 #define ML_ERROR_SERIAL_READ            (22)
 #define ML_ERROR_SERIAL_WRITE           (23)
 #define ML_ERROR_SERIAL_DEVICE_NOT_RECOGNIZED  (24)
 
+/* SM = State Machine */
 #define ML_ERROR_SM_TRANSITION          (25)
 #define ML_ERROR_SM_IMPROPER_STATE      (26)
 
+/* Fifo */
 #define ML_ERROR_FIFO_OVERFLOW          (30)
 #define ML_ERROR_FIFO_FOOTER            (31)
 #define ML_ERROR_FIFO_READ_COUNT        (32)
 #define ML_ERROR_FIFO_READ_DATA         (33)
 
+/* Memory & Registers, Set & Get */
 #define ML_ERROR_MEMORY_SET             (40)
 
 #define ML_ERROR_LOG_MEMORY_ERROR       (50)
 #define ML_ERROR_LOG_OUTPUT_ERROR       (51)
 
+/* OS interface errors */
 #define ML_ERROR_OS_BAD_PTR             (60)
 #define ML_ERROR_OS_BAD_HANDLE          (61)
 #define ML_ERROR_OS_CREATE_FAILED       (62)
 #define ML_ERROR_OS_LOCK_FAILED         (63)
 
+/* Compass errors */
 #define ML_ERROR_COMPASS_DATA_OVERFLOW  (70)
 #define ML_ERROR_COMPASS_DATA_UNDERFLOW (71)
 #define ML_ERROR_COMPASS_DATA_NOT_READY (72)
 #define ML_ERROR_COMPASS_DATA_ERROR     (73)
 
+/* Load/Store calibration */
 #define ML_ERROR_CALIBRATION_LOAD       (75)
 #define ML_ERROR_CALIBRATION_STORE      (76)
 #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)
+#endif
 
+/*---------------------------
+    p-Types
+---------------------------*/
 
-#endif				
+#endif				/* MLTYPES_H */
diff --git a/drivers/input/misc/mpu3050/mpu-dev.c b/drivers/input/misc/mpu3050/mpu-dev.c
index 1f246a8..3116d2c 100644
--- a/drivers/input/misc/mpu3050/mpu-dev.c
+++ b/drivers/input/misc/mpu3050/mpu-dev.c
@@ -19,6 +19,8 @@
     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>
 #include <linux/interrupt.h>
@@ -34,7 +36,10 @@
 #include <linux/slab.h>
 #include <linux/version.h>
 #include <linux/pm.h>
-
+#include <linux/mutex.h>
+#include <linux/suspend.h>
+#include <linux/poll.h>
+#include <linux/delay.h>
 #ifdef CONFIG_HAS_EARLYSUSPEND
 #include <linux/earlysuspend.h>
 #endif
@@ -60,38 +65,59 @@
 #define I(x...) printk(KERN_INFO "[GYRO][MPU3050] " x)
 #define E(x...) printk(KERN_ERR "[GYRO][MPU3050 ERROR] " x)
 
+/* Platform data for the MPU */
 struct mpu_private_data {
 	struct mldl_cfg mldl_cfg;
 
 #ifdef CONFIG_HAS_EARLYSUSPEND
 	struct early_suspend early_suspend;
 #endif
+	struct mutex mutex;
+	wait_queue_head_t mpu_event_wait;
+	struct completion completion;
+	struct timer_list timeout;
+	struct notifier_block nb;
+	struct mpuirq_data mpu_pm_event;
+	int response_timeout;	/* In seconds */
+	unsigned long event;
+	int pid;
 };
 
-static int pid;
-
 static struct i2c_client *this_client;
 
 int mpu_debug_flag;
-int mpu_sensors_reset;
-int mpu_lpm_flag;
+
+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_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;
@@ -101,10 +127,11 @@
 
 	if (mldl_cfg->pressure && mldl_cfg->pressure->resume)
 		mldl_cfg->requested_sensors |= ML_THREE_AXIS_PRESSURE;
-
+	mutex_unlock(&mpu->mutex);
 	return 0;
 }
 
+/* close function - called when the "file" /dev/mpu is closed in userspace   */
 static int mpu_release(struct inode *inode, struct file *file)
 {
 	struct i2c_client *client =
@@ -117,16 +144,18 @@
 	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;
 }
@@ -144,6 +173,8 @@
 			   sizeof(rdwr_arg)))
 		return -EFAULT;
 
+	/* 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;
 
@@ -167,6 +198,8 @@
 
 	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;
@@ -180,7 +213,7 @@
 		}
 		if (copy_from_user(rdwr_pa[i].buf, data_ptrs[i],
 				   rdwr_pa[i].len)) {
-			++i;	
+			++i;	/* Needs to be kfreed too */
 			res = -EFAULT;
 			break;
 		}
@@ -208,33 +241,64 @@
 	return res;
 }
 
+/* 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)
 {
-	char *tmp;
-	int ret;
-
+	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;
 
-	if (count > 8192)
-		count = 8192;
+	if (!mpu->event && (!(file->f_flags & O_NONBLOCK)))
+		wait_event_interruptible(mpu->mpu_event_wait, mpu->event);
 
-	tmp = kmalloc(count, GFP_KERNEL);
-	if (tmp == NULL)
-		return -ENOMEM;
+	if (!mpu->event || NULL == buf
+		|| count < sizeof(mpu->mpu_pm_event))
+		return 0;
 
-	pr_debug("i2c-dev: i2c-%d reading %zu bytes.\n",
-		 iminor(file->f_path.dentry->d_inode), count);
-
-	ret = i2c_master_recv(client, tmp, count);
-	if (ret >= 0) {
-		ret = copy_to_user(buf, tmp, count) ? -EFAULT : ret;
-		if (ret)
-			ret = -EFAULT;
+	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;
 	}
-	kfree(tmp);
-	return ret;
+
+	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;
+	}
+	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;
+	}
+	mpu->event = 0;
+	return len;
+}
+
+static unsigned int mpu_poll(struct file *file, struct poll_table_struct *poll)
+{
+	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;
+
+	poll_wait(file, &mpu->mpu_event_wait, poll);
+	if (mpu->event)
+		mask |= POLLIN | POLLRDNORM;
+	return mask;
 }
 
 static int
@@ -291,6 +355,10 @@
 	if (NULL == temp_mldl_cfg)
 		return -ENOMEM;
 
+	/*
+	 * User space is not allowed to modify accel compass pressure or
+	 * pdata structs, as well as silicon_revision product_id or trim
+	 */
 	if (copy_from_user(temp_mldl_cfg, (struct mldl_cfg __user *) arg,
 				offsetof(struct mldl_cfg, silicon_revision))) {
 		result = -EFAULT;
@@ -331,8 +399,8 @@
 		if (mldl_cfg->dmp_cfg2 != temp_mldl_cfg->dmp_cfg2)
 			mldl_cfg->gyro_needs_reset = TRUE;
 
-		if (mldl_cfg->gyro_power != temp_mldl_cfg->gyro_power)
-			mldl_cfg->gyro_needs_reset = TRUE;
+//		if (mldl_cfg->gyro_power != temp_mldl_cfg->gyro_power)
+//			mldl_cfg->gyro_needs_reset = TRUE;
 
 		for (ii = 0; ii < MPU_NUM_AXES; ii++)
 			if (mldl_cfg->offset_tc[ii] !=
@@ -360,6 +428,8 @@
 static int
 mpu_ioctl_get_mpu_config(struct i2c_client *client, unsigned long arg)
 {
+	/* Have to be careful as there are 3 pointers in the mldl_cfg
+	 * structure */
 	struct mpu_private_data *mpu =
 	    (struct mpu_private_data *) i2c_get_clientdata(client);
 	struct mldl_cfg *mldl_cfg = &mpu->mldl_cfg;
@@ -381,7 +451,7 @@
 		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,
@@ -434,7 +504,7 @@
 		}
 	}
 
-	
+	/* 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));
 
@@ -445,6 +515,16 @@
 	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,
@@ -452,40 +532,50 @@
 			struct ext_slave_config __user *usr_config)
 {
 	int retval = ML_SUCCESS;
-	if ((slave) && (slave->config)) {
-		struct ext_slave_config config;
-		retval = copy_from_user(
-			&config,
-			usr_config,
-			sizeof(config));
-		if (retval)
-			return -EFAULT;
+	struct ext_slave_config config;
+	if ((!slave) || (!slave->config))
+		return retval;
 
-		if (config.len && config.data) {
-			int *data;
-			data = kzalloc(config.len, GFP_KERNEL);
-			if (!data)
-				return ML_ERROR_MEMORY_EXAUSTED;
+	config.key = 0;
+	config.len = 0;
+	config.apply = 0;
+	config.data = NULL;
 
-			retval = copy_from_user(data,
-						(void __user *)config.data,
-						config.len);
-			if (retval) {
-				retval = -EFAULT;
-				kfree(data);
-				return retval;
-			}
-			config.data = data;
+	retval = copy_from_user(&config, usr_config, sizeof(config));
+	if (retval)
+		return -EFAULT;
+
+	if (config.len && config.data) {
+		int *data;
+		data = kzalloc(config.len, GFP_KERNEL);
+		if (!data)
+			return ML_ERROR_MEMORY_EXAUSTED;
+
+		retval = copy_from_user(data,
+					(void __user *)config.data,
+					config.len);
+		if (retval) {
+			retval = -EFAULT;
+			kfree(data);
+			return retval;
 		}
-		retval = slave->config(adapter,
-				slave,
-				pdata,
-				&config);
-		kfree(config.data);
+		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,
@@ -493,49 +583,125 @@
 			struct ext_slave_config __user *usr_config)
 {
 	int retval = ML_SUCCESS;
-	if ((slave) && (slave->get_config)) {
-		struct ext_slave_config config;
-		void *user_data;
-		retval = copy_from_user(
-			&config,
-			usr_config,
-			sizeof(config));
-		if (retval)
-			return -EFAULT;
+	struct ext_slave_config config;
+	void *user_data;
+	if (!(slave) || !(slave->get_config))
+		return ML_SUCCESS;
 
-		user_data = config.data;
-		if (config.len && config.data) {
-			int *data;
-			data = kzalloc(config.len, GFP_KERNEL);
-			if (!data)
-				return ML_ERROR_MEMORY_EXAUSTED;
+	config.key = 0;
+	config.len = 0;
+	config.apply = 0;
+	config.data = NULL;
 
-			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);
+	retval = copy_from_user(&config, usr_config, sizeof(config));
+	if (retval)
+		return -EFAULT;
+
+	user_data = config.data;
+	if (config.len && config.data) {
+		int *data;
+		data = kzalloc(config.len, GFP_KERNEL);
+		if (!data)
+			return ML_ERROR_MEMORY_EXAUSTED;
+
+		retval = copy_from_user(data,
+					(void __user *)config.data,
+					config.len);
 		if (retval) {
-			kfree(config.data);
+			retval = -EFAULT;
+			kfree(data);
 			return retval;
 		}
-		retval = copy_to_user((unsigned char __user *) user_data,
-				      config.data,
-				      config.len);
-		kfree(config.data);
+		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;
+
+	msg.address = 0;
+	msg.length = 0;
+	msg.data = NULL;
+
+	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;
+	}
+
+	mutex_lock(&mutex_fifo_reading_access_lock);
+	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;
+	default:
+		dev_err(&this_client->adapter->dev,
+			"%s: Unknown cmd %x\n", __func__, cmd);
+	};
+	mutex_unlock(&mutex_fifo_reading_access_lock);
+	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)
 {
@@ -549,12 +715,22 @@
 	struct i2c_adapter *compass_adapter;
 	struct i2c_adapter *pressure_adapter;
 
+	dev_dbg(&client->adapter->dev, "%s:0x%x\n", __func__, cmd);
+
 	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);
 
+	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);
@@ -569,117 +745,20 @@
 	case MPU_SET_MPU_CONFIG:
 		retval = mpu_ioctl_set_mpu_config(client, arg);
 		break;
-	case MPU_SET_INT_CONFIG:
-		mldl_cfg->int_config = (unsigned char) arg;
-		break;
-	case MPU_SET_EXT_SYNC:
-		mldl_cfg->ext_sync = (enum mpu_ext_sync) arg;
-		break;
-	case MPU_SET_FULL_SCALE:
-		mldl_cfg->full_scale = (enum mpu_fullscale) arg;
-		break;
-	case MPU_SET_LPF:
-		mldl_cfg->lpf = (enum mpu_filter) arg;
-		break;
-	case MPU_SET_CLK_SRC:
-		mldl_cfg->clk_src = (enum mpu_clock_sel) arg;
-		break;
-	case MPU_SET_DIVIDER:
-		mldl_cfg->divider = (unsigned char) arg;
-		break;
-	case MPU_SET_LEVEL_SHIFTER:
-		mldl_cfg->pdata->level_shifter = (unsigned char) arg;
-		break;
-	case MPU_SET_DMP_ENABLE:
-		mldl_cfg->dmp_enable = (unsigned char) arg;
-		break;
-	case MPU_SET_FIFO_ENABLE:
-		mldl_cfg->fifo_enable = (unsigned char) arg;
-		break;
-	case MPU_SET_DMP_CFG1:
-		mldl_cfg->dmp_cfg1 = (unsigned char) arg;
-		break;
-	case MPU_SET_DMP_CFG2:
-		mldl_cfg->dmp_cfg2 = (unsigned char) arg;
-		break;
-	case MPU_SET_OFFSET_TC:
-		retval = copy_from_user(mldl_cfg->offset_tc,
-					(unsigned char __user *) arg,
-					sizeof(mldl_cfg->offset_tc));
-		if (retval)
-			retval = -EFAULT;
-
-		break;
-	case MPU_SET_RAM:
-		retval = copy_from_user(mldl_cfg->ram,
-					(unsigned char __user *) arg,
-					sizeof(mldl_cfg->ram));
-		if (retval)
-			retval = -EFAULT;
-		break;
 	case MPU_SET_PLATFORM_DATA:
 		retval = mpu_ioctl_set_mpu_pdata(client, arg);
 		break;
 	case MPU_GET_MPU_CONFIG:
 		retval = mpu_ioctl_get_mpu_config(client, arg);
 		break;
-	case MPU_GET_INT_CONFIG:
-		retval = put_user(mldl_cfg->int_config,
-				  (unsigned char __user *) arg);
-		break;
-	case MPU_GET_EXT_SYNC:
-		retval = put_user(mldl_cfg->ext_sync,
-				  (unsigned char __user *) arg);
-		break;
-	case MPU_GET_FULL_SCALE:
-		retval = put_user(mldl_cfg->full_scale,
-				  (unsigned char __user *) arg);
-		break;
-	case MPU_GET_LPF:
-		retval = put_user(mldl_cfg->lpf,
-				  (unsigned char __user *) arg);
-		break;
-	case MPU_GET_CLK_SRC:
-		retval = put_user(mldl_cfg->clk_src,
-				  (unsigned char __user *) arg);
-		break;
-	case MPU_GET_DIVIDER:
-		retval = put_user(mldl_cfg->divider,
-				  (unsigned char __user *) arg);
-		break;
-	case MPU_GET_LEVEL_SHIFTER:
-		retval = put_user(mldl_cfg->pdata->level_shifter,
-				  (unsigned char __user *) arg);
-		break;
-	case MPU_GET_DMP_ENABLE:
-		retval = put_user(mldl_cfg->dmp_enable,
-				  (unsigned char __user *) arg);
-		break;
-	case MPU_GET_FIFO_ENABLE:
-		retval = put_user(mldl_cfg->fifo_enable,
-				  (unsigned char __user *) arg);
-		break;
-	case MPU_GET_DMP_CFG1:
-		retval = put_user(mldl_cfg->dmp_cfg1,
-				  (unsigned char __user *) arg);
-		break;
-	case MPU_GET_DMP_CFG2:
-		retval = put_user(mldl_cfg->dmp_cfg2,
-				  (unsigned char __user *) arg);
-		break;
-	case MPU_GET_OFFSET_TC:
-		retval = copy_to_user((unsigned char __user *) arg,
-				      mldl_cfg->offset_tc,
-				      sizeof(mldl_cfg->offset_tc));
-		if (retval)
-			retval = -EFAULT;
-		break;
-	case MPU_GET_RAM:
-		retval = copy_to_user((unsigned char __user *) arg,
-				      mldl_cfg->ram,
-				      sizeof(mldl_cfg->ram));
-		if (retval)
-			retval = -EFAULT;
+	case MPU_READ:
+	case MPU_WRITE:
+	case MPU_READ_MEM:
+	case MPU_WRITE_MEM:
+	case MPU_READ_FIFO:
+	case MPU_WRITE_FIFO:
+		retval = mpu_handle_mlsl(client->adapter, mldl_cfg->addr, cmd,
+					(struct mpu_read_write __user *) arg);
 		break;
 	case MPU_CONFIG_ACCEL:
 		retval = slave_config(accel_adapter, mldl_cfg,
@@ -739,8 +818,6 @@
 	case MPU_RESUME:
 	{
 		unsigned long sensors;
-
-
 		sensors = mldl_cfg->requested_sensors;
 		retval = mpu3050_resume(mldl_cfg,
 					client->adapter,
@@ -753,6 +830,11 @@
 					sensors & ML_THREE_AXIS_PRESSURE);
 	}
 	break;
+	case MPU_PM_EVENT_HANDLED:
+		dev_dbg(&this_client->adapter->dev,
+			"%s: %d\n", __func__, cmd);
+		complete(&mpu->completion);
+		break;
 	case MPU_READ_ACCEL:
 	{
 		unsigned char data[6];
@@ -793,37 +875,14 @@
 			retval = -EFAULT;
 	}
 	break;
-#ifdef HTC_READ_CAL_DATA
-	case MPU_READ_CAL_DATA:
-	{
-		int index;
-		unsigned char mpu_gyro_gsensor_kvalue[37];
-
-		for (index = 0;
-		     index < sizeof(mpu_gyro_gsensor_kvalue);
-		     index++) {
-			mpu_gyro_gsensor_kvalue[index] =
-				gyro_gsensor_kvalue[index];
-			printk(KERN_DEBUG "gyro_gsensor_kvalue[%d] = 0x%x\n",
-			       index, gyro_gsensor_kvalue[index]);
-		}
-
-		retval =
-			copy_to_user((unsigned char *) arg,
-				     mpu_gyro_gsensor_kvalue,
-				     sizeof(mpu_gyro_gsensor_kvalue));
-	}
-	break;
-#endif
-	case MPU_READ_MEMORY:
-	case MPU_WRITE_MEMORY:
 	default:
 		dev_err(&this_client->adapter->dev,
-			"[mpu_err]%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;
 }
 
@@ -847,10 +906,13 @@
 
 	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)
@@ -871,8 +933,9 @@
 	    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,
@@ -882,8 +945,9 @@
 					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);
@@ -905,9 +969,11 @@
 	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__);
 }
 
@@ -919,6 +985,7 @@
 	struct i2c_adapter *accel_adapter;
 	struct i2c_adapter *compass_adapter;
 	struct i2c_adapter *pressure_adapter;
+	struct mpu3050_platform_data *pdata;
 
 	accel_adapter = i2c_get_adapter(mldl_cfg->pdata->accel.adapt_num);
 	compass_adapter =
@@ -926,7 +993,8 @@
 	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);
@@ -940,6 +1008,20 @@
 			mesg.event);
 	}
 
+	pdata = (struct mpu3050_platform_data *) client->dev.platform_data;
+	if (!pdata) {
+		dev_WARN(&client->adapter->dev,
+				"Missing platform data for mpu\n");
+	} else {
+		if (pdata && pdata->setup && pdata->hw_config
+				&& pdata->power_mode) {
+			pdata->setup(&client->dev, 0);
+			pdata->hw_config(0);
+			pdata->power_mode(0);
+		}
+	}
+
+	mutex_unlock(&mpu->mutex);
 	return 0;
 }
 
@@ -951,6 +1033,26 @@
 	struct i2c_adapter *accel_adapter;
 	struct i2c_adapter *compass_adapter;
 	struct i2c_adapter *pressure_adapter;
+	struct mpu3050_platform_data *pdata;
+	int res;
+
+	pdata = (struct mpu3050_platform_data *) client->dev.platform_data;
+	if (!pdata) {
+		dev_WARN(&client->adapter->dev,
+				"Missing platform data for mpu\n");
+		goto exit;
+	} else {
+		if (pdata && pdata->setup && pdata->hw_config
+				&& pdata->power_mode) {
+			pdata->power_mode(1);
+			pdata->hw_config(1);
+			res = pdata->setup(&client->dev, 1);
+			if (res) {
+				pdata->hw_config(0); /* power down */
+				goto exit;
+			}
+		}
+	}
 
 	accel_adapter = i2c_get_adapter(mldl_cfg->pdata->accel.adapt_num);
 	compass_adapter =
@@ -958,7 +1060,8 @@
 	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,
@@ -969,15 +1072,19 @@
 				      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);
+exit:
 	return 0;
 }
 
+/* define which file operations are supported */
 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
@@ -990,14 +1097,17 @@
 
 static unsigned short normal_i2c[] = { I2C_CLIENT_END };
 
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
+I2C_CLIENT_INSMOD;
+#endif
+
 static struct miscdevice i2c_mpu_device = {
 	.minor = MISC_DYNAMIC_MINOR,
-	.name = "mpu", 
+	.name = "mpu", /* Same for both 3050 and 6000 */
 	.fops = &mpu_fops,
 };
 
 void *g_handler;
-int (*g_sensors_reset)(void);
 
 struct class *mpu3050_class;
 struct device *mpu3050_dev;
@@ -1008,22 +1118,11 @@
 	unsigned char b[2] = "";
 	int result;
 
-	unsigned char bma[8] = "";
-
 	result = MLSLSerialRead(g_handler, 0x68,
 				MPUREG_USER_CTRL, 2, b);
 
-	result = MLSLSerialRead(g_handler, 0x18,
-				0x0F, 3, bma);
-
 	result = sprintf(buf, "MPUREG_USER_CTRL = 0x%x, MPUREG_PWR_MGM = "
-			      "0x%x.\n"
-			      "BMA register 0x0F = 0x%x, "
-			      "BMA register 0x10 = 0x%x, "
-			      "BMA register 0x11 = 0x%x\n"
-			      "",
-			      b[0], b[1],
-			      bma[0], bma[1], bma[2]);
+			 "0x%x\n", b[0], b[1]);
 
 	return result;
 }
@@ -1062,80 +1161,6 @@
 static DEVICE_ATTR(mpu_debug_flag, 0664, mpu_debug_flag_show, \
 		mpu_debug_flag_store);
 
-static ssize_t mpu_sensors_reset_show(struct device *dev,
-			struct device_attribute *attr, char *buf)
-{
-	char *s = buf;
-
-	s += sprintf(s, "mpu_sensors_reset = 0x%x\n", mpu_sensors_reset);
-
-	return s - buf;
-}
-
-static ssize_t mpu_sensors_reset_store(struct device *dev,
-				struct device_attribute *attr,
-				const char *buf, size_t count)
-{
-	int rc = 0;
-
-	mpu_sensors_reset = -1;
-	sscanf(buf, "%d", &mpu_sensors_reset);
-
-	D("%s: mpu_sensors_reset = %d\n", __func__, mpu_sensors_reset);
-
-	if ((mpu_sensors_reset == 1) && g_sensors_reset) {
-		rc = g_sensors_reset();
-		if (rc)
-			E("G-Sensor, Compass, Gyro reset error\n");
-	}
-
-	return count;
-}
-
-static DEVICE_ATTR(mpu_sensors_reset, 0664, mpu_sensors_reset_show, \
-		mpu_sensors_reset_store);
-
-
-static ssize_t mpu_lpm_flag_show(struct device *dev,
-			struct device_attribute *attr, char *buf)
-{
-	char *s = buf;
-
-	s += sprintf(s, "%d", mpu_lpm_flag);
-
-	return s - buf;
-}
-#ifdef CONFIG_CIR_ALWAYS_READY
-extern int cir_flag;
-#endif
-static ssize_t mpu_lpm_flag_store(struct device *dev,
-				struct device_attribute *attr,
-				const char *buf, size_t count)
-{
-	struct mpu_private_data *mpu =
-	    (struct mpu_private_data *) i2c_get_clientdata(this_client);
-	struct mldl_cfg *mldl_cfg = &mpu->mldl_cfg;
-
-	mpu_lpm_flag = -1;
-	sscanf(buf, "%d", &mpu_lpm_flag);
-#ifdef CONFIG_CIR_ALWAYS_READY
-	
-	if ((mpu_lpm_flag == 1) && mldl_cfg->pdata->power_LPM && !cir_flag)
-#else
-	if ((mpu_lpm_flag == 1) && mldl_cfg->pdata->power_LPM)
-#endif
-		mldl_cfg->pdata->power_LPM(1);
-	else if (mldl_cfg->pdata->power_LPM)
-		mldl_cfg->pdata->power_LPM(0);
-
-	D("%s: mpu_lpm_flag = %d\n", __func__, mpu_lpm_flag);
-
-	return count;
-}
-
-static DEVICE_ATTR(mpu_lpm_flag, 0664, mpu_lpm_flag_show, \
-		mpu_lpm_flag_store);
-
 
 int mpu3050_probe(struct i2c_client *client,
 		  const struct i2c_device_id *devid)
@@ -1164,14 +1189,32 @@
 	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);
+
 	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;
 
-	g_sensors_reset = pdata->g_sensors_reset;
+	if (pdata && pdata->setup && pdata->hw_config && pdata->power_mode) {
+		pdata->power_mode(1);
+		pdata->hw_config(1);
+		msleep(4); /* by Spec */
+		res = pdata->setup(&client->dev, 1);
+		if (res)
+			goto out_setup_failed;
+	}
 
 #if defined(CONFIG_MPU_SENSORS_MPU3050_MODULE) || \
     defined(CONFIG_MPU_SENSORS_MPU6000_MODULE)
@@ -1193,17 +1236,10 @@
 					"Installing Accel irq using %d\n",
 					pdata->accel.irq);
 				res = slaveirq_init(accel_adapter,
-
-#ifdef CONFIG_CIR_ALWAYS_READY
-						this_client,
-#endif
 						&pdata->accel,
 						"accelirq");
 				if (res)
 					goto out_accelirq_failed;
-			} else {
-				dev_info(&this_client->adapter->dev,
-					"Accel irq not needed\n");
 			}
 		} else {
 			dev_warn(&this_client->adapter->dev,
@@ -1223,16 +1259,13 @@
 					"Installing Compass irq using %d\n",
 					pdata->compass.irq);
 				res = slaveirq_init(compass_adapter,
-#ifdef CONFIG_CIR_ALWAYS_READY
-						NULL,
-#endif
 						&pdata->compass,
 						"compassirq");
 				if (res)
 					goto out_compassirq_failed;
 			} else {
-				dev_info(&this_client->adapter->dev,
-					"Compass irq not needed\n");
+				dev_warn(&this_client->adapter->dev,
+					"WARNING: Compass irq not assigned\n");
 			}
 		} else {
 			dev_warn(&this_client->adapter->dev,
@@ -1253,9 +1286,6 @@
 					"Installing Pressure irq using %d\n",
 					pdata->pressure.irq);
 				res = slaveirq_init(pressure_adapter,
-#ifdef CONFIG_CIR_ALWAYS_READY
-						NULL,
-#endif
 						&pdata->pressure,
 						"pressureirq");
 				if (res)
@@ -1265,7 +1295,7 @@
 					"WARNING: Pressure irq not assigned\n");
 			}
 		} else {
-			dev_info(&this_client->adapter->dev,
+			dev_warn(&this_client->adapter->dev,
 				 "%s: No Pressure Present\n", MPU_NAME);
 		}
 	}
@@ -1276,17 +1306,15 @@
 
 	if (res) {
 		dev_err(&this_client->adapter->dev,
-			"[mpu_err] Unable to open %s %d\n", MPU_NAME, res);
+			"Unable to open %s %d\n", MPU_NAME, res);
 		res = -ENODEV;
 		goto out_whoami_failed;
 	}
 
-	g_handler = client->adapter;
-
 	res = misc_register(&i2c_mpu_device);
 	if (res < 0) {
 		dev_err(&this_client->adapter->dev,
-			"[mpu_err] ERROR: misc_register returned %d\n", res);
+			"ERROR: misc_register returned %d\n", res);
 		goto out_misc_register_failed;
 	}
 
@@ -1297,8 +1325,8 @@
 		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);
 	}
 
 
@@ -1326,46 +1354,24 @@
 		goto err_create_mpu_device;
 	}
 
-	
+	/* register the attributes */
 	res = device_create_file(mpu3050_dev, &dev_attr_pwr_reg);
 	if (res) {
 		E("%s, create mpu3050_device_create_file fail!\n", __func__);
 		goto err_create_mpu_device_file;
 	}
 
-	
+	/* register the attributes */
 	res = device_create_file(mpu3050_dev, &dev_attr_mpu_debug_flag);
 	if (res) {
 		E("%s, create mpu3050_device_create_file fail!\n", __func__);
 		goto err_create_mpu_device_mpu_debug_flag_file;
 	}
 
-	
-	res = device_create_file(mpu3050_dev, &dev_attr_mpu_sensors_reset);
-	if (res) {
-		E("%s, create mpu3050_device_create_file fail!\n", __func__);
-		goto err_create_mpu_device_sensors_reset_flag_file;
-	}
-
-	
-	res = device_create_file(mpu3050_dev, &dev_attr_mpu_lpm_flag);
-	if (res) {
-		E("%s, create mpu3050_device_create_file fail!\n", __func__);
-		goto err_create_mpu_device_mpu_lpm_flag_file;
-	}
-
 	mpu_debug_flag = 0;
-	mpu_sensors_reset = 0;
-	mpu_lpm_flag = 0;
-	D("%s: MPU3050 probe success v02-Fix set ODR G-Sensor issue\n",
-		__func__);
 
 	return res;
 
-err_create_mpu_device_mpu_lpm_flag_file:
-	device_remove_file(mpu3050_dev, &dev_attr_mpu_sensors_reset);
-err_create_mpu_device_sensors_reset_flag_file:
-	device_remove_file(mpu3050_dev, &dev_attr_mpu_debug_flag);
 err_create_mpu_device_mpu_debug_flag_file:
 	device_remove_file(mpu3050_dev, &dev_attr_pwr_reg);
 err_create_mpu_device_file:
@@ -1393,13 +1399,14 @@
 	    pdata->accel.irq)
 		slaveirq_exit(&pdata->accel);
 out_accelirq_failed:
+out_setup_failed:
+	unregister_pm_notifier(&mpu->nb);
 	kfree(mpu);
 out_alloc_data_failed:
 out_check_functionality_failed:
-	dev_err(&this_client->adapter->dev, "[mpu_err]%s failed %d\n", __func__,
+	dev_err(&this_client->adapter->dev, "%s failed %d\n", __func__,
 		res);
 	return res;
-
 }
 
 static int mpu3050_remove(struct i2c_client *client)
@@ -1443,6 +1450,8 @@
 	    pdata->accel.irq)
 		slaveirq_exit(&pdata->accel);
 
+	pdata->power_mode(0);
+
 	misc_deregister(&i2c_mpu_device);
 	kfree(mpu);
 
@@ -1465,17 +1474,21 @@
 		   .owner = THIS_MODULE,
 		   .name = MPU_NAME,
 		   },
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
+	.address_data = &addr_data,
+#else
 	.address_list = normal_i2c,
-	.shutdown = mpu_shutdown,	
-	.suspend = mpu_suspend,	
-	.resume = mpu_resume,	
+#endif
+
+	.shutdown = mpu_shutdown,	/* optional */
+	.suspend = mpu_suspend,	/* optional */
+	.resume = mpu_resume,	/* optional */
 
 };
 
 static int __init mpu_init(void)
 {
 	int res = i2c_add_driver(&mpu3050_driver);
-	pid = 0;
 	printk(KERN_DEBUG "%s\n", __func__);
 	if (res)
 		dev_err(&this_client->adapter->dev, "[mpu_err]%s failed\n",
diff --git a/drivers/input/misc/mpu3050/mpu-i2c.c b/drivers/input/misc/mpu3050/mpu-i2c.c
index 0953e6a..1938a14 100644
--- a/drivers/input/misc/mpu3050/mpu-i2c.c
+++ b/drivers/input/misc/mpu3050/mpu-i2c.c
@@ -17,13 +17,18 @@
   $
  */
 
+/**
+ *  @defgroup
+ *  @brief
+ *
+ *  @{
+ *      @file   mpu-i2c.c
+ *      @brief
+ *
+ */
 
-#include <linux/delay.h>
 #include <linux/i2c.h>
-#include "mpu.h"
-#define MPU_I2C_RETRY_ENABLE 1
-#define MPU_I2C_RETRY_TIMES 10
-#define MPU_I2C_DELAY_TIMES_MS 10
+#include <linux/mpu.h>
 
 int sensor_i2c_write(struct i2c_adapter *i2c_adap,
 		     unsigned char address,
@@ -31,36 +36,20 @@
 {
 	struct i2c_msg msgs[1];
 	int res;
-	int i;
 
 	if (NULL == data || NULL == i2c_adap)
 		return -EINVAL;
 
 	msgs[0].addr = address;
-	msgs[0].flags = 0;	
+	msgs[0].flags = 0;	/* write */
 	msgs[0].buf = (unsigned char *) data;
 	msgs[0].len = len;
 
-#if MPU_I2C_RETRY_ENABLE
-		for (i = 0; i < MPU_I2C_RETRY_TIMES; i++) {
-			res = i2c_transfer(i2c_adap, msgs, 1);
-			if (res < 1) {
-				printk(KERN_ERR "I2c Slave address: %x,\
-				sensor_i2c_write fail,\
-				retry:%d\n", address, i);
-				mdelay(MPU_I2C_DELAY_TIMES_MS);
-			} else
-				return 0;
-
-		}
-		return res;
-#else
 	res = i2c_transfer(i2c_adap, msgs, 1);
 	if (res < 1)
 		return res;
 	else
 		return 0;
-#endif
 }
 
 int sensor_i2c_write_register(struct i2c_adapter *i2c_adap,
@@ -81,13 +70,12 @@
 {
 	struct i2c_msg msgs[2];
 	int res;
-	int i;
 
 	if (NULL == data || NULL == i2c_adap)
 		return -EINVAL;
 
 	msgs[0].addr = address;
-	msgs[0].flags = 0;	
+	msgs[0].flags = 0;	/* write */
 	msgs[0].buf = &reg;
 	msgs[0].len = 1;
 
@@ -96,26 +84,11 @@
 	msgs[1].buf = data;
 	msgs[1].len = len;
 
-#if MPU_I2C_RETRY_ENABLE
-		for (i = 0; i < MPU_I2C_RETRY_TIMES; i++) {
-			res = i2c_transfer(i2c_adap, msgs, 2);
-			if (res < 2) {
-				printk(KERN_ERR "I2c Slave address: %x,\
-				sensor_i2c_read fail,\
-				retry:%d\n", address, i);
-				mdelay(MPU_I2C_DELAY_TIMES_MS);
-			} else
-				return 0;
-
-		}
-		return res;
-#else
 	res = i2c_transfer(i2c_adap, msgs, 2);
 	if (res < 2)
 		return res;
 	else
 		return 0;
-#endif
 }
 
 int mpu_memory_read(struct i2c_adapter *i2c_adap,
@@ -142,7 +115,7 @@
 
 	buf = MPUREG_MEM_R_W;
 
-	
+	/* Write Message */
 	msgs[0].addr = mpu_addr;
 	msgs[0].flags = 0;
 	msgs[0].buf = bank;
@@ -163,26 +136,12 @@
 	msgs[3].buf = data;
 	msgs[3].len = len;
 
-#if MPU_I2C_RETRY_ENABLE
-		for (i = 0; i < MPU_I2C_RETRY_TIMES; i++) {
-			ret = i2c_transfer(i2c_adap, msgs, 4);
-			if (ret != 4) {
-				printk(KERN_ERR "I2c Slave address: %x,\
-				mpu_memory_read,\
-				retry:%d\n", mpu_addr, i);
-				mdelay(MPU_I2C_DELAY_TIMES_MS);
-			} else
-				return 0;
-
-		}
-		return ret;
-#else
-	ret = i2c_transfer(i2c_adap, msgs, 4);
-	if (ret != 4)
-		return ret;
-	else
-		return 0;
-#endif
+	for (i = 0; i < 4; i++) {
+		ret = i2c_transfer(i2c_adap, &msgs[i], 1);
+		if (ret != 1)
+			return ret;
+	}
+	return 0;
 }
 
 int mpu_memory_write(struct i2c_adapter *i2c_adap,
@@ -212,7 +171,7 @@
 	buf[0] = MPUREG_MEM_R_W;
 	memcpy(buf + 1, data, len);
 
-	
+	/* Write Message */
 	msgs[0].addr = mpu_addr;
 	msgs[0].flags = 0;
 	msgs[0].buf = bank;
@@ -228,25 +187,10 @@
 	msgs[2].buf = (unsigned char *) buf;
 	msgs[2].len = len + 1;
 
-#if MPU_I2C_RETRY_ENABLE
-		for (i = 0; i < MPU_I2C_RETRY_TIMES; i++) {
-			ret = i2c_transfer(i2c_adap, msgs, 3);
-			if (ret != 3) {
-				printk(KERN_ERR "I2c Slave address: %x,\
-				mpu_memory_write,\
-				retry:%d\n", mpu_addr, i);
-				mdelay(MPU_I2C_DELAY_TIMES_MS);
-			} else
-				return 0;
-
-		}
-		return ret;
-#else
-	ret = i2c_transfer(i2c_adap, msgs, 3);
-	if (ret != 3)
-		return ret;
-	else
-		return 0;
-#endif
+	for (i = 0; i < 3; i++) {
+		ret = i2c_transfer(i2c_adap, &msgs[i], 1);
+		if (ret != 1)
+			return ret;
+	}
+	return 0;
 }
-
diff --git a/drivers/input/misc/mpu3050/mpu-i2c.h b/drivers/input/misc/mpu3050/mpu-i2c.h
index c26aafb..0bbc8c6 100644
--- a/drivers/input/misc/mpu3050/mpu-i2c.h
+++ b/drivers/input/misc/mpu3050/mpu-i2c.h
@@ -16,6 +16,16 @@
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
   $
  */
+/**
+ * @defgroup
+ * @brief
+ *
+ * @{
+ * @file     mpu-i2c.c
+ * @brief
+ *
+ *
+ */
 
 #ifndef __MPU_I2C_H__
 #define __MPU_I2C_H__
@@ -45,4 +55,4 @@
 		     unsigned short mem_addr,
 		     unsigned int len, unsigned char const *data);
 
-#endif	
+#endif	/* __MPU_I2C_H__ */
diff --git a/drivers/input/misc/mpu3050/mpuirq.c b/drivers/input/misc/mpu3050/mpuirq.c
index 561d6cf..8b13e17 100644
--- a/drivers/input/misc/mpu3050/mpuirq.c
+++ b/drivers/input/misc/mpu3050/mpuirq.c
@@ -15,7 +15,8 @@
     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>
@@ -38,13 +39,14 @@
 #include <linux/uaccess.h>
 #include <linux/io.h>
 
-#include "mpu.h"
+#include <linux/mpu.h>
 #include "mpuirq.h"
 #include "mldl_cfg.h"
 #include "mpu-i2c.h"
 
 #define MPUIRQ_NAME "mpuirq"
 
+/* function which gets accel data and sends it to MPU */
 
 DECLARE_WAIT_QUEUE_HEAD(mpuirq_wait);
 
@@ -71,25 +73,26 @@
 		"%s current->pid %d\n", __func__, current->pid);
 	mpuirq_dev_data.pid = current->pid;
 	file->private_data = &mpuirq_dev_data;
-	
-	
-	
 	return 0;
 }
 
+/* close function - called when the "file" /dev/mpuirq is closed in userspace */
 static int mpuirq_release(struct inode *inode, struct file *file)
 {
 	dev_dbg(mpuirq_dev_data.dev->this_device, "mpuirq_release\n");
 	return 0;
 }
 
+/* read function called when from /dev/mpuirq is read */
 static ssize_t mpuirq_read(struct file *file,
 			   char *buf, size_t count, loff_t *ppos)
 {
 	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,
@@ -100,6 +103,8 @@
 	    && count >= sizeof(mpuirq_data)) {
 		err = copy_to_user(buf, &mpuirq_data, sizeof(mpuirq_data));
 		mpuirq_data.data_type = 0;
+		//dev_dbg(mpuirq_dev_data.dev->this_device,
+		//	"%s:copy_to_user\n", __func__);
 	} else {
 		return 0;
 	}
@@ -116,19 +121,22 @@
 unsigned int mpuirq_poll(struct file *file, struct poll_table_struct *poll)
 {
 	int mask = 0;
-
 	poll_wait(file, &mpuirq_wait, poll);
+	//dev_dbg(mpuirq_dev_data.dev->this_device, "%s\n", __func__);
 	if (mpuirq_dev_data.data_ready)
 		mask |= POLLIN | POLLRDNORM;
 	return mask;
 }
 
+/* ioctl - I/O control */
 static long mpuirq_ioctl(struct file *file,
 			 unsigned int cmd, unsigned long arg)
 {
 	int retval = 0;
 	int data;
 
+	//dev_dbg(mpuirq_dev_data.dev->this_device, "%s:%d\n", __func__, cmd);
+
 	switch (cmd) {
 	case MPUIRQ_SET_TIMEOUT:
 		mpuirq_dev_data.timeout = arg;
@@ -151,10 +159,6 @@
 	case MPUIRQ_SET_FREQUENCY_DIVIDER:
 		mpuirq_dev_data.accel_divider = arg;
 		break;
-	case MPUIRQ_GET_DEBUG_FLAG:
-		if (copy_to_user((int *) arg, &mpu_debug_flag, sizeof(int)))
-			return -EFAULT;
-		break;
 	default:
 		retval = -EINVAL;
 	}
@@ -174,12 +178,14 @@
 	int ii;
 
 	accel_adapter = i2c_get_adapter(mldl_cfg->pdata->accel.adapt_num);
+	//dev_dbg(mpuirq_dev_data->dev->this_device, "%s\n", __func__);
+
 	mldl_cfg->accel->read(accel_adapter,
 			      mldl_cfg->accel,
 			      &mldl_cfg->pdata->accel, rbuff);
 
 
-	
+	/* @todo add other data formats here as well */
 	if (EXT_SLAVE_BIG_ENDIAN == mldl_cfg->accel->endian) {
 		for (ii = 0; ii < 3; ii++) {
 			wbuff[2 * ii + 1] = rbuff[2 * ii + 1];
@@ -190,7 +196,7 @@
 	}
 
 	wbuff[7] = 0;
-	wbuff[8] = 1;		
+	wbuff[8] = 1;		/*set semaphore */
 
 	mpu_memory_write(mpuirq_dev_data->mpu_client->adapter,
 			 mldl_cfg->addr, 0x0108, 8, wbuff);
@@ -204,8 +210,8 @@
 
 	mpuirq_data.interruptcount++;
 
-	
-	
+	/* wake up (unblock) for reading data from userspace */
+	/* and ignore first interrupt generated in module init */
 	mpuirq_dev_data.data_ready = 1;
 
 	do_gettimeofday(&irqtime);
@@ -219,11 +225,13 @@
 	}
 
 	wake_up_interruptible(&mpuirq_wait);
+	//dev_dbg(mpuirq_dev_data.dev->this_device,
+	//	"%s:wake_up_interruptible\n", __func__);
 
 	return IRQ_HANDLED;
-
 }
 
+/* define which file operations are supported */
 const struct file_operations mpuirq_fops = {
 	.owner = THIS_MODULE,
 	.read = mpuirq_read,
@@ -252,7 +260,7 @@
 	struct mldl_cfg *mldl_cfg =
 	    (struct mldl_cfg *) i2c_get_clientdata(mpu_client);
 
-	
+	/* work_struct initialization */
 	INIT_WORK((struct work_struct *) &mpuirq_dev_data,
 		  mpu_accel_data_work_fcn);
 	mpuirq_dev_data.mpu_client = mpu_client;
@@ -284,6 +292,9 @@
 				mpuirq_dev_data.irq);
 		} else {
 			res = misc_register(&mpuirq_device);
+			dev_dbg(mpuirq_dev_data.dev->this_device,
+				 "misc_register(&mpuirq_device):%x\n", res);
+
 			if (res < 0) {
 				dev_err(&mpu_client->adapter->dev,
 					"misc_register returned %d\n",
@@ -296,13 +307,15 @@
 	} else {
 		res = 0;
 	}
+	dev_dbg(mpuirq_dev_data.dev->this_device,
+		"%s :%d\n", __func__, mpu_client->irq);
 
 	return res;
 }
 
 void mpuirq_exit(void)
 {
-	
+	/* Free the IRQ first before flushing the work */
 	if (mpuirq_dev_data.irq > 0)
 		free_irq(mpuirq_dev_data.irq, &mpuirq_dev_data.irq);
 
diff --git a/drivers/input/misc/mpu3050/mpuirq.h b/drivers/input/misc/mpu3050/mpuirq.h
index 54c2e88..5e25d06 100644
--- a/drivers/input/misc/mpu3050/mpuirq.h
+++ b/drivers/input/misc/mpu3050/mpuirq.h
@@ -21,25 +21,20 @@
 #define __MPUIRQ__
 
 #ifdef __KERNEL__
-#include <linux/i2c-dev.h>
+#include <linux/time.h>
+#include <linux/ioctl.h>
+#include "mldl_cfg.h"
+#else
+#include <sys/ioctl.h>
+#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_GET_DEBUG_FLAG        (8)
-
-extern int mpu_debug_flag;
-
-#ifdef __KERNEL__
+#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)
 
 void mpuirq_exit(void);
 int mpuirq_init(struct i2c_client *mpu_client);
 
 #endif
-
-#endif
diff --git a/drivers/input/misc/mpu3050/slaveirq.c b/drivers/input/misc/mpu3050/slaveirq.c
index 8f19d1e..7024dbd 100644
--- a/drivers/input/misc/mpu3050/slaveirq.c
+++ b/drivers/input/misc/mpu3050/slaveirq.c
@@ -16,6 +16,7 @@
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
   $
  */
+
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -38,731 +39,32 @@
 #include <linux/io.h>
 #include <linux/wait.h>
 #include <linux/slab.h>
-#include <linux/input.h>
 
-#include <linux/wakelock.h>
-#include "mpu.h"
+#include <linux/mpu.h>
 #include "slaveirq.h"
 #include "mldl_cfg.h"
 #include "mpu-i2c.h"
 
-#define SENSOR_NAME 			"bma250"
-#define ABSMIN				-512
-#define ABSMAX				512
-#define SLOPE_THRESHOLD_VALUE 		32
-#define SLOPE_DURATION_VALUE 		1
-#define INTERRUPT_LATCH_MODE 		13
-#define INTERRUPT_ENABLE 		1
-#define INTERRUPT_DISABLE 		0
-#define MAP_SLOPE_INTERRUPT 		2
-#define SLOPE_X_INDEX 			5
-#define SLOPE_Y_INDEX 			6
-#define SLOPE_Z_INDEX 			7
-#define BMA250_MAX_DELAY		200
-#define BMA250_CHIP_ID			3
-#define BMA250_RANGE_SET		0
-#define BMA250_BW_SET			4
-
-#define LOW_G_INTERRUPT				REL_Z
-#define HIGH_G_INTERRUPT 			REL_HWHEEL
-#define SLOP_INTERRUPT 				REL_DIAL
-#define DOUBLE_TAP_INTERRUPT 			REL_WHEEL
-#define SINGLE_TAP_INTERRUPT 			REL_MISC
-#define ORIENT_INTERRUPT 			ABS_PRESSURE
-#define FLAT_INTERRUPT 				REL_MISC
-
-
-#define HIGH_G_INTERRUPT_X_HAPPENED			1
-#define HIGH_G_INTERRUPT_Y_HAPPENED 			2
-#define HIGH_G_INTERRUPT_Z_HAPPENED 			3
-#define HIGH_G_INTERRUPT_X_NEGATIVE_HAPPENED 		4
-#define HIGH_G_INTERRUPT_Y_NEGATIVE_HAPPENED		5
-#define HIGH_G_INTERRUPT_Z_NEGATIVE_HAPPENED 		6
-#define SLOPE_INTERRUPT_X_HAPPENED 			7
-#define SLOPE_INTERRUPT_Y_HAPPENED 			8
-#define SLOPE_INTERRUPT_Z_HAPPENED 			9
-#define SLOPE_INTERRUPT_X_NEGATIVE_HAPPENED 		10
-#define SLOPE_INTERRUPT_Y_NEGATIVE_HAPPENED 		11
-#define SLOPE_INTERRUPT_Z_NEGATIVE_HAPPENED 		12
-#define DOUBLE_TAP_INTERRUPT_HAPPENED 			13
-#define SINGLE_TAP_INTERRUPT_HAPPENED 			14
-#define UPWARD_PORTRAIT_UP_INTERRUPT_HAPPENED 		15
-#define UPWARD_PORTRAIT_DOWN_INTERRUPT_HAPPENED	 	16
-#define UPWARD_LANDSCAPE_LEFT_INTERRUPT_HAPPENED 	17
-#define UPWARD_LANDSCAPE_RIGHT_INTERRUPT_HAPPENED	18
-#define DOWNWARD_PORTRAIT_UP_INTERRUPT_HAPPENED 	19
-#define DOWNWARD_PORTRAIT_DOWN_INTERRUPT_HAPPENED 	20
-#define DOWNWARD_LANDSCAPE_LEFT_INTERRUPT_HAPPENED 	21
-#define DOWNWARD_LANDSCAPE_RIGHT_INTERRUPT_HAPPENED 	22
-#define FLAT_INTERRUPT_TURE_HAPPENED			23
-#define FLAT_INTERRUPT_FALSE_HAPPENED			24
-#define LOW_G_INTERRUPT_HAPPENED			25
-
-#define PAD_LOWG					0
-#define PAD_HIGHG					1
-#define PAD_SLOP					2
-#define PAD_DOUBLE_TAP					3
-#define PAD_SINGLE_TAP					4
-#define PAD_ORIENT					5
-#define PAD_FLAT					6
-
-
-#define BMA250_CHIP_ID_REG                      0x00
-#define BMA250_VERSION_REG                      0x01
-#define BMA250_X_AXIS_LSB_REG                   0x02
-#define BMA250_X_AXIS_MSB_REG                   0x03
-#define BMA250_Y_AXIS_LSB_REG                   0x04
-#define BMA250_Y_AXIS_MSB_REG                   0x05
-#define BMA250_Z_AXIS_LSB_REG                   0x06
-#define BMA250_Z_AXIS_MSB_REG                   0x07
-#define BMA250_TEMP_RD_REG                      0x08
-#define BMA250_STATUS1_REG                      0x09
-#define BMA250_STATUS2_REG                      0x0A
-#define BMA250_STATUS_TAP_SLOPE_REG             0x0B
-#define BMA250_STATUS_ORIENT_HIGH_REG           0x0C
-#define BMA250_RANGE_SEL_REG                    0x0F
-#define BMA250_BW_SEL_REG                       0x10
-#define BMA250_MODE_CTRL_REG                    0x11
-#define BMA250_LOW_NOISE_CTRL_REG               0x12
-#define BMA250_DATA_CTRL_REG                    0x13
-#define BMA250_RESET_REG                        0x14
-#define BMA250_INT_ENABLE1_REG                  0x16
-#define BMA250_INT_ENABLE2_REG                  0x17
-#define BMA250_INT1_PAD_SEL_REG                 0x19
-#define BMA250_INT_DATA_SEL_REG                 0x1A
-#define BMA250_INT2_PAD_SEL_REG                 0x1B
-#define BMA250_INT_SRC_REG                      0x1E
-#define BMA250_INT_SET_REG                      0x20
-#define BMA250_INT_CTRL_REG                     0x21
-#define BMA250_LOW_DURN_REG                     0x22
-#define BMA250_LOW_THRES_REG                    0x23
-#define BMA250_LOW_HIGH_HYST_REG                0x24
-#define BMA250_HIGH_DURN_REG                    0x25
-#define BMA250_HIGH_THRES_REG                   0x26
-#define BMA250_SLOPE_DURN_REG                   0x27
-#define BMA250_SLOPE_THRES_REG                  0x28
-#define BMA250_TAP_PARAM_REG                    0x2A
-#define BMA250_TAP_THRES_REG                    0x2B
-#define BMA250_ORIENT_PARAM_REG                 0x2C
-#define BMA250_THETA_BLOCK_REG                  0x2D
-#define BMA250_THETA_FLAT_REG                   0x2E
-#define BMA250_FLAT_HOLD_TIME_REG               0x2F
-#define BMA250_STATUS_LOW_POWER_REG             0x31
-#define BMA250_SELF_TEST_REG                    0x32
-#define BMA250_EEPROM_CTRL_REG                  0x33
-#define BMA250_SERIAL_CTRL_REG                  0x34
-#define BMA250_CTRL_UNLOCK_REG                  0x35
-#define BMA250_OFFSET_CTRL_REG                  0x36
-#define BMA250_OFFSET_PARAMS_REG                0x37
-#define BMA250_OFFSET_FILT_X_REG                0x38
-#define BMA250_OFFSET_FILT_Y_REG                0x39
-#define BMA250_OFFSET_FILT_Z_REG                0x3A
-#define BMA250_OFFSET_UNFILT_X_REG              0x3B
-#define BMA250_OFFSET_UNFILT_Y_REG              0x3C
-#define BMA250_OFFSET_UNFILT_Z_REG              0x3D
-#define BMA250_SPARE_0_REG                      0x3E
-#define BMA250_SPARE_1_REG                      0x3F
-
-#define BMA250_ACC_X_LSB__POS           6
-#define BMA250_ACC_X_LSB__LEN           2
-#define BMA250_ACC_X_LSB__MSK           0xC0
-#define BMA250_ACC_X_LSB__REG           BMA250_X_AXIS_LSB_REG
-
-#define BMA250_ACC_X_MSB__POS           0
-#define BMA250_ACC_X_MSB__LEN           8
-#define BMA250_ACC_X_MSB__MSK           0xFF
-#define BMA250_ACC_X_MSB__REG           BMA250_X_AXIS_MSB_REG
-
-#define BMA250_ACC_Y_LSB__POS           6
-#define BMA250_ACC_Y_LSB__LEN           2
-#define BMA250_ACC_Y_LSB__MSK           0xC0
-#define BMA250_ACC_Y_LSB__REG           BMA250_Y_AXIS_LSB_REG
-
-#define BMA250_ACC_Y_MSB__POS           0
-#define BMA250_ACC_Y_MSB__LEN           8
-#define BMA250_ACC_Y_MSB__MSK           0xFF
-#define BMA250_ACC_Y_MSB__REG           BMA250_Y_AXIS_MSB_REG
-
-#define BMA250_ACC_Z_LSB__POS           6
-#define BMA250_ACC_Z_LSB__LEN           2
-#define BMA250_ACC_Z_LSB__MSK           0xC0
-#define BMA250_ACC_Z_LSB__REG           BMA250_Z_AXIS_LSB_REG
-
-#define BMA250_ACC_Z_MSB__POS           0
-#define BMA250_ACC_Z_MSB__LEN           8
-#define BMA250_ACC_Z_MSB__MSK           0xFF
-#define BMA250_ACC_Z_MSB__REG           BMA250_Z_AXIS_MSB_REG
-
-#define BMA250_RANGE_SEL__POS             0
-#define BMA250_RANGE_SEL__LEN             4
-#define BMA250_RANGE_SEL__MSK             0x0F
-#define BMA250_RANGE_SEL__REG             BMA250_RANGE_SEL_REG
-
-#define BMA250_BANDWIDTH__POS             0
-#define BMA250_BANDWIDTH__LEN             5
-#define BMA250_BANDWIDTH__MSK             0x1F
-#define BMA250_BANDWIDTH__REG             BMA250_BW_SEL_REG
-
-#define BMA250_EN_LOW_POWER__POS          6
-#define BMA250_EN_LOW_POWER__LEN          1
-#define BMA250_EN_LOW_POWER__MSK          0x40
-#define BMA250_EN_LOW_POWER__REG          BMA250_MODE_CTRL_REG
-
-#define BMA250_EN_SUSPEND__POS            7
-#define BMA250_EN_SUSPEND__LEN            1
-#define BMA250_EN_SUSPEND__MSK            0x80
-#define BMA250_EN_SUSPEND__REG            BMA250_MODE_CTRL_REG
-
-#define BMA250_INT_MODE_SEL__POS                0
-#define BMA250_INT_MODE_SEL__LEN                4
-#define BMA250_INT_MODE_SEL__MSK                0x0F
-#define BMA250_INT_MODE_SEL__REG                BMA250_INT_CTRL_REG
-
-#define BMA250_LOWG_INT_S__POS          0
-#define BMA250_LOWG_INT_S__LEN          1
-#define BMA250_LOWG_INT_S__MSK          0x01
-#define BMA250_LOWG_INT_S__REG          BMA250_STATUS1_REG
-
-#define BMA250_HIGHG_INT_S__POS          1
-#define BMA250_HIGHG_INT_S__LEN          1
-#define BMA250_HIGHG_INT_S__MSK          0x02
-#define BMA250_HIGHG_INT_S__REG          BMA250_STATUS1_REG
-
-#define BMA250_SLOPE_INT_S__POS          2
-#define BMA250_SLOPE_INT_S__LEN          1
-#define BMA250_SLOPE_INT_S__MSK          0x04
-#define BMA250_SLOPE_INT_S__REG          BMA250_STATUS1_REG
-
-#define BMA250_DOUBLE_TAP_INT_S__POS     4
-#define BMA250_DOUBLE_TAP_INT_S__LEN     1
-#define BMA250_DOUBLE_TAP_INT_S__MSK     0x10
-#define BMA250_DOUBLE_TAP_INT_S__REG     BMA250_STATUS1_REG
-
-#define BMA250_SINGLE_TAP_INT_S__POS     5
-#define BMA250_SINGLE_TAP_INT_S__LEN     1
-#define BMA250_SINGLE_TAP_INT_S__MSK     0x20
-#define BMA250_SINGLE_TAP_INT_S__REG     BMA250_STATUS1_REG
-
-#define BMA250_ORIENT_INT_S__POS         6
-#define BMA250_ORIENT_INT_S__LEN         1
-#define BMA250_ORIENT_INT_S__MSK         0x40
-#define BMA250_ORIENT_INT_S__REG         BMA250_STATUS1_REG
-
-#define BMA250_FLAT_INT_S__POS           7
-#define BMA250_FLAT_INT_S__LEN           1
-#define BMA250_FLAT_INT_S__MSK           0x80
-#define BMA250_FLAT_INT_S__REG           BMA250_STATUS1_REG
-
-#define BMA250_DATA_INT_S__POS           7
-#define BMA250_DATA_INT_S__LEN           1
-#define BMA250_DATA_INT_S__MSK           0x80
-#define BMA250_DATA_INT_S__REG           BMA250_STATUS2_REG
-
-#define BMA250_SLOPE_FIRST_X__POS        0
-#define BMA250_SLOPE_FIRST_X__LEN        1
-#define BMA250_SLOPE_FIRST_X__MSK        0x01
-#define BMA250_SLOPE_FIRST_X__REG        BMA250_STATUS_TAP_SLOPE_REG
-
-#define BMA250_SLOPE_FIRST_Y__POS        1
-#define BMA250_SLOPE_FIRST_Y__LEN        1
-#define BMA250_SLOPE_FIRST_Y__MSK        0x02
-#define BMA250_SLOPE_FIRST_Y__REG        BMA250_STATUS_TAP_SLOPE_REG
-
-#define BMA250_SLOPE_FIRST_Z__POS        2
-#define BMA250_SLOPE_FIRST_Z__LEN        1
-#define BMA250_SLOPE_FIRST_Z__MSK        0x04
-#define BMA250_SLOPE_FIRST_Z__REG        BMA250_STATUS_TAP_SLOPE_REG
-
-#define BMA250_SLOPE_SIGN_S__POS         3
-#define BMA250_SLOPE_SIGN_S__LEN         1
-#define BMA250_SLOPE_SIGN_S__MSK         0x08
-#define BMA250_SLOPE_SIGN_S__REG         BMA250_STATUS_TAP_SLOPE_REG
-
-#define BMA250_TAP_FIRST_X__POS        4
-#define BMA250_TAP_FIRST_X__LEN        1
-#define BMA250_TAP_FIRST_X__MSK        0x10
-#define BMA250_TAP_FIRST_X__REG        BMA250_STATUS_TAP_SLOPE_REG
-
-#define BMA250_TAP_FIRST_Y__POS        5
-#define BMA250_TAP_FIRST_Y__LEN        1
-#define BMA250_TAP_FIRST_Y__MSK        0x20
-#define BMA250_TAP_FIRST_Y__REG        BMA250_STATUS_TAP_SLOPE_REG
-
-#define BMA250_TAP_FIRST_Z__POS        6
-#define BMA250_TAP_FIRST_Z__LEN        1
-#define BMA250_TAP_FIRST_Z__MSK        0x40
-#define BMA250_TAP_FIRST_Z__REG        BMA250_STATUS_TAP_SLOPE_REG
-
-#define BMA250_TAP_FIRST_XYZ__POS        4
-#define BMA250_TAP_FIRST_XYZ__LEN        3
-#define BMA250_TAP_FIRST_XYZ__MSK        0x70
-#define BMA250_TAP_FIRST_XYZ__REG        BMA250_STATUS_TAP_SLOPE_REG
-
-#define BMA250_TAP_SIGN_S__POS         7
-#define BMA250_TAP_SIGN_S__LEN         1
-#define BMA250_TAP_SIGN_S__MSK         0x80
-#define BMA250_TAP_SIGN_S__REG         BMA250_STATUS_TAP_SLOPE_REG
-
-#define BMA250_HIGHG_FIRST_X__POS        0
-#define BMA250_HIGHG_FIRST_X__LEN        1
-#define BMA250_HIGHG_FIRST_X__MSK        0x01
-#define BMA250_HIGHG_FIRST_X__REG        BMA250_STATUS_ORIENT_HIGH_REG
-
-#define BMA250_HIGHG_FIRST_Y__POS        1
-#define BMA250_HIGHG_FIRST_Y__LEN        1
-#define BMA250_HIGHG_FIRST_Y__MSK        0x02
-#define BMA250_HIGHG_FIRST_Y__REG        BMA250_STATUS_ORIENT_HIGH_REG
-
-#define BMA250_HIGHG_FIRST_Z__POS        2
-#define BMA250_HIGHG_FIRST_Z__LEN        1
-#define BMA250_HIGHG_FIRST_Z__MSK        0x04
-#define BMA250_HIGHG_FIRST_Z__REG        BMA250_STATUS_ORIENT_HIGH_REG
-
-#define BMA250_HIGHG_SIGN_S__POS         3
-#define BMA250_HIGHG_SIGN_S__LEN         1
-#define BMA250_HIGHG_SIGN_S__MSK         0x08
-#define BMA250_HIGHG_SIGN_S__REG         BMA250_STATUS_ORIENT_HIGH_REG
-
-#define BMA250_ORIENT_S__POS             4
-#define BMA250_ORIENT_S__LEN             3
-#define BMA250_ORIENT_S__MSK             0x70
-#define BMA250_ORIENT_S__REG             BMA250_STATUS_ORIENT_HIGH_REG
-
-#define BMA250_FLAT_S__POS               7
-#define BMA250_FLAT_S__LEN               1
-#define BMA250_FLAT_S__MSK               0x80
-#define BMA250_FLAT_S__REG               BMA250_STATUS_ORIENT_HIGH_REG
-
-#define BMA250_EN_SLOPE_X_INT__POS         0
-#define BMA250_EN_SLOPE_X_INT__LEN         1
-#define BMA250_EN_SLOPE_X_INT__MSK         0x01
-#define BMA250_EN_SLOPE_X_INT__REG         BMA250_INT_ENABLE1_REG
-
-#define BMA250_EN_SLOPE_Y_INT__POS         1
-#define BMA250_EN_SLOPE_Y_INT__LEN         1
-#define BMA250_EN_SLOPE_Y_INT__MSK         0x02
-#define BMA250_EN_SLOPE_Y_INT__REG         BMA250_INT_ENABLE1_REG
-
-#define BMA250_EN_SLOPE_Z_INT__POS         2
-#define BMA250_EN_SLOPE_Z_INT__LEN         1
-#define BMA250_EN_SLOPE_Z_INT__MSK         0x04
-#define BMA250_EN_SLOPE_Z_INT__REG         BMA250_INT_ENABLE1_REG
-
-#define BMA250_EN_SLOPE_XYZ_INT__POS         0
-#define BMA250_EN_SLOPE_XYZ_INT__LEN         3
-#define BMA250_EN_SLOPE_XYZ_INT__MSK         0x07
-#define BMA250_EN_SLOPE_XYZ_INT__REG         BMA250_INT_ENABLE1_REG
-
-#define BMA250_EN_DOUBLE_TAP_INT__POS      4
-#define BMA250_EN_DOUBLE_TAP_INT__LEN      1
-#define BMA250_EN_DOUBLE_TAP_INT__MSK      0x10
-#define BMA250_EN_DOUBLE_TAP_INT__REG      BMA250_INT_ENABLE1_REG
-
-#define BMA250_EN_SINGLE_TAP_INT__POS      5
-#define BMA250_EN_SINGLE_TAP_INT__LEN      1
-#define BMA250_EN_SINGLE_TAP_INT__MSK      0x20
-#define BMA250_EN_SINGLE_TAP_INT__REG      BMA250_INT_ENABLE1_REG
-
-#define BMA250_EN_ORIENT_INT__POS          6
-#define BMA250_EN_ORIENT_INT__LEN          1
-#define BMA250_EN_ORIENT_INT__MSK          0x40
-#define BMA250_EN_ORIENT_INT__REG          BMA250_INT_ENABLE1_REG
-
-#define BMA250_EN_FLAT_INT__POS            7
-#define BMA250_EN_FLAT_INT__LEN            1
-#define BMA250_EN_FLAT_INT__MSK            0x80
-#define BMA250_EN_FLAT_INT__REG            BMA250_INT_ENABLE1_REG
-
-#define BMA250_EN_HIGHG_X_INT__POS         0
-#define BMA250_EN_HIGHG_X_INT__LEN         1
-#define BMA250_EN_HIGHG_X_INT__MSK         0x01
-#define BMA250_EN_HIGHG_X_INT__REG         BMA250_INT_ENABLE2_REG
-
-#define BMA250_EN_HIGHG_Y_INT__POS         1
-#define BMA250_EN_HIGHG_Y_INT__LEN         1
-#define BMA250_EN_HIGHG_Y_INT__MSK         0x02
-#define BMA250_EN_HIGHG_Y_INT__REG         BMA250_INT_ENABLE2_REG
-
-#define BMA250_EN_HIGHG_Z_INT__POS         2
-#define BMA250_EN_HIGHG_Z_INT__LEN         1
-#define BMA250_EN_HIGHG_Z_INT__MSK         0x04
-#define BMA250_EN_HIGHG_Z_INT__REG         BMA250_INT_ENABLE2_REG
-
-#define BMA250_EN_HIGHG_XYZ_INT__POS         2
-#define BMA250_EN_HIGHG_XYZ_INT__LEN         1
-#define BMA250_EN_HIGHG_XYZ_INT__MSK         0x04
-#define BMA250_EN_HIGHG_XYZ_INT__REG         BMA250_INT_ENABLE2_REG
-
-#define BMA250_EN_LOWG_INT__POS            3
-#define BMA250_EN_LOWG_INT__LEN            1
-#define BMA250_EN_LOWG_INT__MSK            0x08
-#define BMA250_EN_LOWG_INT__REG            BMA250_INT_ENABLE2_REG
-
-#define BMA250_EN_NEW_DATA_INT__POS        4
-#define BMA250_EN_NEW_DATA_INT__LEN        1
-#define BMA250_EN_NEW_DATA_INT__MSK        0x10
-#define BMA250_EN_NEW_DATA_INT__REG        BMA250_INT_ENABLE2_REG
-
-#define BMA250_EN_INT1_PAD_LOWG__POS        0
-#define BMA250_EN_INT1_PAD_LOWG__LEN        1
-#define BMA250_EN_INT1_PAD_LOWG__MSK        0x01
-#define BMA250_EN_INT1_PAD_LOWG__REG        BMA250_INT1_PAD_SEL_REG
-
-#define BMA250_EN_INT1_PAD_HIGHG__POS       1
-#define BMA250_EN_INT1_PAD_HIGHG__LEN       1
-#define BMA250_EN_INT1_PAD_HIGHG__MSK       0x02
-#define BMA250_EN_INT1_PAD_HIGHG__REG       BMA250_INT1_PAD_SEL_REG
-
-#define BMA250_EN_INT1_PAD_SLOPE__POS       2
-#define BMA250_EN_INT1_PAD_SLOPE__LEN       1
-#define BMA250_EN_INT1_PAD_SLOPE__MSK       0x04
-#define BMA250_EN_INT1_PAD_SLOPE__REG       BMA250_INT1_PAD_SEL_REG
-
-#define BMA250_EN_INT1_PAD_DB_TAP__POS      4
-#define BMA250_EN_INT1_PAD_DB_TAP__LEN      1
-#define BMA250_EN_INT1_PAD_DB_TAP__MSK      0x10
-#define BMA250_EN_INT1_PAD_DB_TAP__REG      BMA250_INT1_PAD_SEL_REG
-
-#define BMA250_EN_INT1_PAD_SNG_TAP__POS     5
-#define BMA250_EN_INT1_PAD_SNG_TAP__LEN     1
-#define BMA250_EN_INT1_PAD_SNG_TAP__MSK     0x20
-#define BMA250_EN_INT1_PAD_SNG_TAP__REG     BMA250_INT1_PAD_SEL_REG
-
-#define BMA250_EN_INT1_PAD_ORIENT__POS      6
-#define BMA250_EN_INT1_PAD_ORIENT__LEN      1
-#define BMA250_EN_INT1_PAD_ORIENT__MSK      0x40
-#define BMA250_EN_INT1_PAD_ORIENT__REG      BMA250_INT1_PAD_SEL_REG
-
-#define BMA250_EN_INT1_PAD_FLAT__POS        7
-#define BMA250_EN_INT1_PAD_FLAT__LEN        1
-#define BMA250_EN_INT1_PAD_FLAT__MSK        0x80
-#define BMA250_EN_INT1_PAD_FLAT__REG        BMA250_INT1_PAD_SEL_REG
-
-#define BMA250_EN_INT2_PAD_LOWG__POS        0
-#define BMA250_EN_INT2_PAD_LOWG__LEN        1
-#define BMA250_EN_INT2_PAD_LOWG__MSK        0x01
-#define BMA250_EN_INT2_PAD_LOWG__REG        BMA250_INT2_PAD_SEL_REG
-
-#define BMA250_EN_INT2_PAD_HIGHG__POS       1
-#define BMA250_EN_INT2_PAD_HIGHG__LEN       1
-#define BMA250_EN_INT2_PAD_HIGHG__MSK       0x02
-#define BMA250_EN_INT2_PAD_HIGHG__REG       BMA250_INT2_PAD_SEL_REG
-
-#define BMA250_EN_INT2_PAD_SLOPE__POS       2
-#define BMA250_EN_INT2_PAD_SLOPE__LEN       1
-#define BMA250_EN_INT2_PAD_SLOPE__MSK       0x04
-#define BMA250_EN_INT2_PAD_SLOPE__REG       BMA250_INT2_PAD_SEL_REG
-
-#define BMA250_EN_INT2_PAD_DB_TAP__POS      4
-#define BMA250_EN_INT2_PAD_DB_TAP__LEN      1
-#define BMA250_EN_INT2_PAD_DB_TAP__MSK      0x10
-#define BMA250_EN_INT2_PAD_DB_TAP__REG      BMA250_INT2_PAD_SEL_REG
-
-#define BMA250_EN_INT2_PAD_SNG_TAP__POS     5
-#define BMA250_EN_INT2_PAD_SNG_TAP__LEN     1
-#define BMA250_EN_INT2_PAD_SNG_TAP__MSK     0x20
-#define BMA250_EN_INT2_PAD_SNG_TAP__REG     BMA250_INT2_PAD_SEL_REG
-
-#define BMA250_EN_INT2_PAD_ORIENT__POS      6
-#define BMA250_EN_INT2_PAD_ORIENT__LEN      1
-#define BMA250_EN_INT2_PAD_ORIENT__MSK      0x40
-#define BMA250_EN_INT2_PAD_ORIENT__REG      BMA250_INT2_PAD_SEL_REG
-
-#define BMA250_EN_INT2_PAD_FLAT__POS        7
-#define BMA250_EN_INT2_PAD_FLAT__LEN        1
-#define BMA250_EN_INT2_PAD_FLAT__MSK        0x80
-#define BMA250_EN_INT2_PAD_FLAT__REG        BMA250_INT2_PAD_SEL_REG
-
-#define BMA250_EN_INT1_PAD_NEWDATA__POS     0
-#define BMA250_EN_INT1_PAD_NEWDATA__LEN     1
-#define BMA250_EN_INT1_PAD_NEWDATA__MSK     0x01
-#define BMA250_EN_INT1_PAD_NEWDATA__REG     BMA250_INT_DATA_SEL_REG
-
-#define BMA250_EN_INT2_PAD_NEWDATA__POS     7
-#define BMA250_EN_INT2_PAD_NEWDATA__LEN     1
-#define BMA250_EN_INT2_PAD_NEWDATA__MSK     0x80
-#define BMA250_EN_INT2_PAD_NEWDATA__REG     BMA250_INT_DATA_SEL_REG
-
-
-#define BMA250_UNFILT_INT_SRC_LOWG__POS        0
-#define BMA250_UNFILT_INT_SRC_LOWG__LEN        1
-#define BMA250_UNFILT_INT_SRC_LOWG__MSK        0x01
-#define BMA250_UNFILT_INT_SRC_LOWG__REG        BMA250_INT_SRC_REG
-
-#define BMA250_UNFILT_INT_SRC_HIGHG__POS       1
-#define BMA250_UNFILT_INT_SRC_HIGHG__LEN       1
-#define BMA250_UNFILT_INT_SRC_HIGHG__MSK       0x02
-#define BMA250_UNFILT_INT_SRC_HIGHG__REG       BMA250_INT_SRC_REG
-
-#define BMA250_UNFILT_INT_SRC_SLOPE__POS       2
-#define BMA250_UNFILT_INT_SRC_SLOPE__LEN       1
-#define BMA250_UNFILT_INT_SRC_SLOPE__MSK       0x04
-#define BMA250_UNFILT_INT_SRC_SLOPE__REG       BMA250_INT_SRC_REG
-
-#define BMA250_UNFILT_INT_SRC_TAP__POS         4
-#define BMA250_UNFILT_INT_SRC_TAP__LEN         1
-#define BMA250_UNFILT_INT_SRC_TAP__MSK         0x10
-#define BMA250_UNFILT_INT_SRC_TAP__REG         BMA250_INT_SRC_REG
-
-#define BMA250_UNFILT_INT_SRC_DATA__POS        5
-#define BMA250_UNFILT_INT_SRC_DATA__LEN        1
-#define BMA250_UNFILT_INT_SRC_DATA__MSK        0x20
-#define BMA250_UNFILT_INT_SRC_DATA__REG        BMA250_INT_SRC_REG
-
-#define BMA250_INT1_PAD_ACTIVE_LEVEL__POS       0
-#define BMA250_INT1_PAD_ACTIVE_LEVEL__LEN       1
-#define BMA250_INT1_PAD_ACTIVE_LEVEL__MSK       0x01
-#define BMA250_INT1_PAD_ACTIVE_LEVEL__REG       BMA250_INT_SET_REG
-
-#define BMA250_INT2_PAD_ACTIVE_LEVEL__POS       2
-#define BMA250_INT2_PAD_ACTIVE_LEVEL__LEN       1
-#define BMA250_INT2_PAD_ACTIVE_LEVEL__MSK       0x04
-#define BMA250_INT2_PAD_ACTIVE_LEVEL__REG       BMA250_INT_SET_REG
-
-#define BMA250_INT1_PAD_OUTPUT_TYPE__POS        1
-#define BMA250_INT1_PAD_OUTPUT_TYPE__LEN        1
-#define BMA250_INT1_PAD_OUTPUT_TYPE__MSK        0x02
-#define BMA250_INT1_PAD_OUTPUT_TYPE__REG        BMA250_INT_SET_REG
-
-#define BMA250_INT2_PAD_OUTPUT_TYPE__POS        3
-#define BMA250_INT2_PAD_OUTPUT_TYPE__LEN        1
-#define BMA250_INT2_PAD_OUTPUT_TYPE__MSK        0x08
-#define BMA250_INT2_PAD_OUTPUT_TYPE__REG        BMA250_INT_SET_REG
-
-
-#define BMA250_INT_MODE_SEL__POS                0
-#define BMA250_INT_MODE_SEL__LEN                4
-#define BMA250_INT_MODE_SEL__MSK                0x0F
-#define BMA250_INT_MODE_SEL__REG                BMA250_INT_CTRL_REG
-
-
-#define BMA250_INT_RESET_LATCHED__POS           7
-#define BMA250_INT_RESET_LATCHED__LEN           1
-#define BMA250_INT_RESET_LATCHED__MSK           0x80
-#define BMA250_INT_RESET_LATCHED__REG           BMA250_INT_CTRL_REG
-
-#define BMA250_LOWG_DUR__POS                    0
-#define BMA250_LOWG_DUR__LEN                    8
-#define BMA250_LOWG_DUR__MSK                    0xFF
-#define BMA250_LOWG_DUR__REG                    BMA250_LOW_DURN_REG
-
-#define BMA250_LOWG_THRES__POS                  0
-#define BMA250_LOWG_THRES__LEN                  8
-#define BMA250_LOWG_THRES__MSK                  0xFF
-#define BMA250_LOWG_THRES__REG                  BMA250_LOW_THRES_REG
-
-#define BMA250_LOWG_HYST__POS                   0
-#define BMA250_LOWG_HYST__LEN                   2
-#define BMA250_LOWG_HYST__MSK                   0x03
-#define BMA250_LOWG_HYST__REG                   BMA250_LOW_HIGH_HYST_REG
-
-#define BMA250_LOWG_INT_MODE__POS               2
-#define BMA250_LOWG_INT_MODE__LEN               1
-#define BMA250_LOWG_INT_MODE__MSK               0x04
-#define BMA250_LOWG_INT_MODE__REG               BMA250_LOW_HIGH_HYST_REG
-
-#define BMA250_HIGHG_DUR__POS                    0
-#define BMA250_HIGHG_DUR__LEN                    8
-#define BMA250_HIGHG_DUR__MSK                    0xFF
-#define BMA250_HIGHG_DUR__REG                    BMA250_HIGH_DURN_REG
-
-#define BMA250_HIGHG_THRES__POS                  0
-#define BMA250_HIGHG_THRES__LEN                  8
-#define BMA250_HIGHG_THRES__MSK                  0xFF
-#define BMA250_HIGHG_THRES__REG                  BMA250_HIGH_THRES_REG
-
-#define BMA250_HIGHG_HYST__POS                  6
-#define BMA250_HIGHG_HYST__LEN                  2
-#define BMA250_HIGHG_HYST__MSK                  0xC0
-#define BMA250_HIGHG_HYST__REG                  BMA250_LOW_HIGH_HYST_REG
-
-#define BMA250_SLOPE_DUR__POS                    0
-#define BMA250_SLOPE_DUR__LEN                    2
-#define BMA250_SLOPE_DUR__MSK                    0x03
-#define BMA250_SLOPE_DUR__REG                    BMA250_SLOPE_DURN_REG
-
-#define BMA250_SLOPE_THRES__POS                  0
-#define BMA250_SLOPE_THRES__LEN                  8
-#define BMA250_SLOPE_THRES__MSK                  0xFF
-#define BMA250_SLOPE_THRES__REG                  BMA250_SLOPE_THRES_REG
-
-#define BMA250_TAP_DUR__POS                    0
-#define BMA250_TAP_DUR__LEN                    3
-#define BMA250_TAP_DUR__MSK                    0x07
-#define BMA250_TAP_DUR__REG                    BMA250_TAP_PARAM_REG
-
-#define BMA250_TAP_SHOCK_DURN__POS             6
-#define BMA250_TAP_SHOCK_DURN__LEN             1
-#define BMA250_TAP_SHOCK_DURN__MSK             0x40
-#define BMA250_TAP_SHOCK_DURN__REG             BMA250_TAP_PARAM_REG
-
-#define BMA250_TAP_QUIET_DURN__POS             7
-#define BMA250_TAP_QUIET_DURN__LEN             1
-#define BMA250_TAP_QUIET_DURN__MSK             0x80
-#define BMA250_TAP_QUIET_DURN__REG             BMA250_TAP_PARAM_REG
-
-#define BMA250_TAP_THRES__POS                  0
-#define BMA250_TAP_THRES__LEN                  5
-#define BMA250_TAP_THRES__MSK                  0x1F
-#define BMA250_TAP_THRES__REG                  BMA250_TAP_THRES_REG
-
-#define BMA250_TAP_SAMPLES__POS                6
-#define BMA250_TAP_SAMPLES__LEN                2
-#define BMA250_TAP_SAMPLES__MSK                0xC0
-#define BMA250_TAP_SAMPLES__REG                BMA250_TAP_THRES_REG
-
-#define BMA250_ORIENT_MODE__POS                  0
-#define BMA250_ORIENT_MODE__LEN                  2
-#define BMA250_ORIENT_MODE__MSK                  0x03
-#define BMA250_ORIENT_MODE__REG                  BMA250_ORIENT_PARAM_REG
-
-#define BMA250_ORIENT_BLOCK__POS                 2
-#define BMA250_ORIENT_BLOCK__LEN                 2
-#define BMA250_ORIENT_BLOCK__MSK                 0x0C
-#define BMA250_ORIENT_BLOCK__REG                 BMA250_ORIENT_PARAM_REG
-
-#define BMA250_ORIENT_HYST__POS                  4
-#define BMA250_ORIENT_HYST__LEN                  3
-#define BMA250_ORIENT_HYST__MSK                  0x70
-#define BMA250_ORIENT_HYST__REG                  BMA250_ORIENT_PARAM_REG
-
-#define BMA250_ORIENT_AXIS__POS                  7
-#define BMA250_ORIENT_AXIS__LEN                  1
-#define BMA250_ORIENT_AXIS__MSK                  0x80
-#define BMA250_ORIENT_AXIS__REG                  BMA250_THETA_BLOCK_REG
-
-#define BMA250_THETA_BLOCK__POS                  0
-#define BMA250_THETA_BLOCK__LEN                  6
-#define BMA250_THETA_BLOCK__MSK                  0x3F
-#define BMA250_THETA_BLOCK__REG                  BMA250_THETA_BLOCK_REG
-
-#define BMA250_THETA_FLAT__POS                  0
-#define BMA250_THETA_FLAT__LEN                  6
-#define BMA250_THETA_FLAT__MSK                  0x3F
-#define BMA250_THETA_FLAT__REG                  BMA250_THETA_FLAT_REG
-
-#define BMA250_FLAT_HOLD_TIME__POS              4
-#define BMA250_FLAT_HOLD_TIME__LEN              2
-#define BMA250_FLAT_HOLD_TIME__MSK              0x30
-#define BMA250_FLAT_HOLD_TIME__REG              BMA250_FLAT_HOLD_TIME_REG
-
-#define BMA250_EN_SELF_TEST__POS                0
-#define BMA250_EN_SELF_TEST__LEN                2
-#define BMA250_EN_SELF_TEST__MSK                0x03
-#define BMA250_EN_SELF_TEST__REG                BMA250_SELF_TEST_REG
-
-
-
-#define BMA250_NEG_SELF_TEST__POS               2
-#define BMA250_NEG_SELF_TEST__LEN               1
-#define BMA250_NEG_SELF_TEST__MSK               0x04
-#define BMA250_NEG_SELF_TEST__REG               BMA250_SELF_TEST_REG
-
-
-#define BMA250_LOW_POWER_MODE_S__POS            0
-#define BMA250_LOW_POWER_MODE_S__LEN            1
-#define BMA250_LOW_POWER_MODE_S__MSK            0x01
-#define BMA250_LOW_POWER_MODE_S__REG            BMA250_STATUS_LOW_POWER_REG
-
-#define BMA250_EN_FAST_COMP__POS                5
-#define BMA250_EN_FAST_COMP__LEN                2
-#define BMA250_EN_FAST_COMP__MSK                0x60
-#define BMA250_EN_FAST_COMP__REG                BMA250_OFFSET_CTRL_REG
-
-#define BMA250_FAST_COMP_RDY_S__POS             4
-#define BMA250_FAST_COMP_RDY_S__LEN             1
-#define BMA250_FAST_COMP_RDY_S__MSK             0x10
-#define BMA250_FAST_COMP_RDY_S__REG             BMA250_OFFSET_CTRL_REG
-
-#define BMA250_COMP_TARGET_OFFSET_X__POS        1
-#define BMA250_COMP_TARGET_OFFSET_X__LEN        2
-#define BMA250_COMP_TARGET_OFFSET_X__MSK        0x06
-#define BMA250_COMP_TARGET_OFFSET_X__REG        BMA250_OFFSET_PARAMS_REG
-
-#define BMA250_COMP_TARGET_OFFSET_Y__POS        3
-#define BMA250_COMP_TARGET_OFFSET_Y__LEN        2
-#define BMA250_COMP_TARGET_OFFSET_Y__MSK        0x18
-#define BMA250_COMP_TARGET_OFFSET_Y__REG        BMA250_OFFSET_PARAMS_REG
-
-#define BMA250_COMP_TARGET_OFFSET_Z__POS        5
-#define BMA250_COMP_TARGET_OFFSET_Z__LEN        2
-#define BMA250_COMP_TARGET_OFFSET_Z__MSK        0x60
-#define BMA250_COMP_TARGET_OFFSET_Z__REG        BMA250_OFFSET_PARAMS_REG
-
-#define BMA250_UNLOCK_EE_WRITE_SETTING__POS     0
-#define BMA250_UNLOCK_EE_WRITE_SETTING__LEN     1
-#define BMA250_UNLOCK_EE_WRITE_SETTING__MSK     0x01
-#define BMA250_UNLOCK_EE_WRITE_SETTING__REG     BMA250_EEPROM_CTRL_REG
-
-#define BMA250_START_EE_WRITE_SETTING__POS      1
-#define BMA250_START_EE_WRITE_SETTING__LEN      1
-#define BMA250_START_EE_WRITE_SETTING__MSK      0x02
-#define BMA250_START_EE_WRITE_SETTING__REG      BMA250_EEPROM_CTRL_REG
-
-#define BMA250_EE_WRITE_SETTING_S__POS          2
-#define BMA250_EE_WRITE_SETTING_S__LEN          1
-#define BMA250_EE_WRITE_SETTING_S__MSK          0x04
-#define BMA250_EE_WRITE_SETTING_S__REG          BMA250_EEPROM_CTRL_REG
-
-#define BMA250_EN_SOFT_RESET__POS         0
-#define BMA250_EN_SOFT_RESET__LEN         8
-#define BMA250_EN_SOFT_RESET__MSK         0xFF
-#define BMA250_EN_SOFT_RESET__REG         BMA250_RESET_REG
-
-#define BMA250_EN_SOFT_RESET_VALUE        0xB6
-
-#define BMA250_RANGE_2G                 0
-#define BMA250_RANGE_4G                 1
-#define BMA250_RANGE_8G                 2
-#define BMA250_RANGE_16G                3
-
-#define BMA250_BW_7_81HZ        0x08
-#define BMA250_BW_15_63HZ       0x09
-#define BMA250_BW_31_25HZ       0x0A
-#define BMA250_BW_62_50HZ       0x0B
-#define BMA250_BW_125HZ         0x0C
-#define BMA250_BW_250HZ         0x0D
-#define BMA250_BW_500HZ         0x0E
-#define BMA250_BW_1000HZ        0x0F
-
-#define BMA250_MODE_NORMAL      0
-#define BMA250_MODE_LOWPOWER    1
-#define BMA250_MODE_SUSPEND     2
-
-
-#define BMA250_GET_BITSLICE(regvar, bitname)\
-	((regvar & bitname##__MSK) >> bitname##__POS)
-
-
-#define BMA250_SET_BITSLICE(regvar, bitname, val)\
-	((regvar & ~bitname##__MSK) | ((val<<bitname##__POS)&bitname##__MSK))
-
-
-
-
+/* function which gets slave data and sends it to SLAVE */
 
 struct slaveirq_dev_data {
 	struct miscdevice dev;
-#ifdef CONFIG_CIR_ALWAYS_READY
 	struct i2c_client *slave_client;
-#endif
 	struct mpuirq_data data;
 	wait_queue_head_t slaveirq_wait;
 	int irq;
 	int pid;
 	int data_ready;
 	int timeout;
-	struct work_struct bma_irq_work;
-	struct i2c_adapter * adapter;
-	struct input_dev *input;
-#ifdef CONFIG_CIR_ALWAYS_READY
-	struct input_dev *input_cir;
-	struct wake_lock cir_always_ready_wake_lock;
-#endif
 };
 
+/* The following depends on patch fa1f68db6ca7ebb6fc4487ac215bffba06c01c28
+ * drivers: misc: pass miscdevice pointer via file private data
+ */
 static int slaveirq_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 slaveirq_dev_data *data =
 		container_of(file->private_data, struct slaveirq_dev_data, dev);
 
@@ -780,6 +82,7 @@
 	return 0;
 }
 
+/* read function called when from /dev/slaveirq is read */
 static ssize_t slaveirq_read(struct file *file,
 			   char *buf, size_t count, loff_t *ppos)
 {
@@ -787,7 +90,11 @@
 	struct slaveirq_dev_data *data =
 		container_of(file->private_data, struct slaveirq_dev_data, dev);
 
-	if (!data->data_ready) {
+	//dev_dbg(data->dev.this_device, "%s\n", __func__);
+
+	if (!data->data_ready &&
+		data->timeout &&
+		!(file->f_flags & O_NONBLOCK)) {
 		wait_event_interruptible_timeout(data->slaveirq_wait,
 						 data->data_ready,
 						 data->timeout);
@@ -810,18 +117,21 @@
 	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 =
 		container_of(file->private_data, struct slaveirq_dev_data, dev);
 
+	//dev_dbg(data->dev.this_device, "%s\n", __func__);
 	poll_wait(file, &data->slaveirq_wait, poll);
 	if (data->data_ready)
 		mask |= POLLIN | POLLRDNORM;
 	return mask;
 }
 
+/* ioctl - I/O control */
 static long slaveirq_ioctl(struct file *file,
 			   unsigned int cmd, unsigned long arg)
 {
@@ -830,6 +140,7 @@
 	struct slaveirq_dev_data *data =
 		container_of(file->private_data, struct slaveirq_dev_data, dev);
 
+	//dev_dbg(data->dev.this_device, "%s cmd:%d\n", __func__, cmd);
 	switch (cmd) {
 	case SLAVEIRQ_SET_TIMEOUT:
 		data->timeout = arg;
@@ -862,10 +173,11 @@
 	struct timeval irqtime;
 	mycount++;
 
+	//dev_dbg(data->dev.this_device, "%s\n", __func__);
+
 	data->data.interruptcount++;
 
-	
-	
+	/* wake up (unblock) for reading data from userspace */
 	data->data_ready = 1;
 
 	do_gettimeofday(&irqtime);
@@ -879,6 +191,7 @@
 
 }
 
+/* define which file operations are supported */
 static const struct file_operations slaveirq_fops = {
 	.owner = THIS_MODULE,
 	.read = slaveirq_read,
@@ -893,65 +206,14 @@
 	.open = slaveirq_open,
 	.release = slaveirq_release,
 };
-#ifdef CONFIG_CIR_ALWAYS_READY
-static void bma250_irq_work_func(struct work_struct *work)
-{
 
-    struct slaveirq_dev_data *bma250 = container_of((struct work_struct *)work,
-	    struct slaveirq_dev_data, bma_irq_work);
-
-    wake_lock_timeout(&(bma250->cir_always_ready_wake_lock), 1*HZ);
-    input_report_rel(bma250->input_cir,
-	    SLOP_INTERRUPT,
-	    SLOPE_INTERRUPT_X_NEGATIVE_HAPPENED);
-    input_report_rel(bma250->input_cir,
-	    SLOP_INTERRUPT,
-	    SLOPE_INTERRUPT_Y_NEGATIVE_HAPPENED);
-    input_report_rel(bma250->input_cir,
-	    SLOP_INTERRUPT,
-	    SLOPE_INTERRUPT_X_HAPPENED);
-    input_report_rel(bma250->input_cir,
-	    SLOP_INTERRUPT,
-	    SLOPE_INTERRUPT_Y_HAPPENED);
-    input_sync(bma250->input_cir);
-    enable_irq(bma250->irq);
-}
-static irqreturn_t bma250_irq_handler(int irq, void *handle)
-{
-
-
-    struct slaveirq_dev_data *data = handle;
-
-    if (data)
-        disable_irq_nosync(data->irq);
-
-    if (data == NULL)
-	return IRQ_HANDLED;
-    if (data->slave_client == NULL)
-	return IRQ_HANDLED;
-
-
-    schedule_work(&data->bma_irq_work);
-
-    return IRQ_HANDLED;
-
-
-}
-#endif
 int slaveirq_init(struct i2c_adapter *slave_adapter,
-#ifdef CONFIG_CIR_ALWAYS_READY
-		  struct i2c_client  *client,
-#endif
 		  struct ext_slave_platform_data *pdata,
 		  char *name)
 {
 
 	int res;
 	struct slaveirq_dev_data *data;
-	struct input_dev *dev = NULL;
-#ifdef CONFIG_CIR_ALWAYS_READY
-	struct input_dev *dev_cir = NULL;
-#endif
 
 	if (!pdata->irq)
 		return -EINVAL;
@@ -970,57 +232,10 @@
 	data->data_ready = 0;
 	data->timeout = 0;
 
-#ifdef CONFIG_CIR_ALWAYS_READY
-	data->slave_client = client;
-#endif
-
-	data->adapter = slave_adapter;
 	init_waitqueue_head(&data->slaveirq_wait);
 
-	if(strncmp(name,"accelirq",strlen("accelirq")) == 0){
-	    dev = input_allocate_device();
-	    if (!dev)
-		return -ENOMEM;
-
-	    dev->name = SENSOR_NAME;
-	    dev->id.bustype = BUS_I2C;
-	    input_set_abs_params(dev, ABS_X, ABSMIN, ABSMAX, 0, 0);
-	    input_set_abs_params(dev, ABS_Y, ABSMIN, ABSMAX, 0, 0);
-	    input_set_abs_params(dev, ABS_Z, ABSMIN, ABSMAX, 0, 0);
-	    input_set_drvdata(dev, data);
-
-	    res = input_register_device(dev);
-	    if (res < 0) {
-		goto err_register_input_device;
-	    }
-	    data->input = dev;
-
-#ifdef CONFIG_CIR_ALWAYS_READY
-	    dev_cir = input_allocate_device();
-	    if (!dev_cir) {
-		goto err_allocate_input_cir_devive;
-	    }
-	    dev_cir->name = "CIRSensor";
-	    dev_cir->id.bustype = BUS_I2C;
-	    input_set_capability(dev_cir, EV_REL, SLOP_INTERRUPT);
-
-	    res = input_register_device(dev_cir);
-	    if (res < 0) {
-		goto err_register_cir_input_device;
-	    }
-	    data->input_cir = dev_cir;
-
-
-	    INIT_WORK(&data->bma_irq_work, bma250_irq_work_func);
-	    res = request_irq(data->irq, bma250_irq_handler, IRQF_TRIGGER_RISING,
-		    "bma250", data);
-	    enable_irq_wake(data->irq); 
-
-	    wake_lock_init(&(data->cir_always_ready_wake_lock), WAKE_LOCK_SUSPEND, "cir_always_ready");
-#endif
-	}else
-	    res = request_irq(data->irq, slaveirq_handler, IRQF_TRIGGER_RISING,
-		    data->dev.name, data);
+	res = request_irq(data->irq, slaveirq_handler, IRQF_TRIGGER_RISING,
+			  data->dev.name, data);
 
 	if (res) {
 		dev_err(&slave_adapter->dev,
@@ -1044,21 +259,7 @@
 out_request_irq:
 	kfree(pdata->irq_data);
 	pdata->irq_data = NULL;
-#ifdef CONFIG_CIR_ALWAYS_READY
-	if(dev_cir != NULL)
-	    input_unregister_device(data->input_cir);
-err_register_cir_input_device:
-	if(dev_cir != NULL)
-	    input_free_device(dev_cir);
-err_allocate_input_cir_devive:
-	if(dev != NULL)
-	    input_unregister_device(data->input);
-#endif
 
-err_register_input_device:
-	if(dev != NULL)
-	    input_free_device(dev);
-	kfree(data);
 	return res;
 }
 
diff --git a/drivers/input/misc/mpu3050/slaveirq.h b/drivers/input/misc/mpu3050/slaveirq.h
index 6a32bad..0542aea 100644
--- a/drivers/input/misc/mpu3050/slaveirq.h
+++ b/drivers/input/misc/mpu3050/slaveirq.h
@@ -20,30 +20,18 @@
 #ifndef __SLAVEIRQ__
 #define __SLAVEIRQ__
 
-#ifdef __KERNEL__
 #include <linux/i2c-dev.h>
-#endif
 
-#include "mpu.h"
+#include <linux/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__
 
 void slaveirq_exit(struct ext_slave_platform_data *pdata);
 int slaveirq_init(struct i2c_adapter *slave_adapter,
-#ifdef CONFIG_CIR_ALWAYS_READY
-		  struct i2c_client  *client,
-#endif
 		struct ext_slave_platform_data *pdata,
 		char *name);
-
-#endif
-
 #endif
diff --git a/drivers/input/misc/mpu3050/timerirq.c b/drivers/input/misc/mpu3050/timerirq.c
index ce2b153..0bfb603 100644
--- a/drivers/input/misc/mpu3050/timerirq.c
+++ b/drivers/input/misc/mpu3050/timerirq.c
@@ -16,6 +16,7 @@
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
   $
  */
+
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -38,10 +39,11 @@
 #include <linux/timer.h>
 #include <linux/slab.h>
 
-#include "mpu.h"
+#include <linux/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;
@@ -62,7 +64,6 @@
 	struct timerirq_data *data = (struct timerirq_data *)arg;
 	struct timeval irqtime;
 
-
 	data->data.interruptcount++;
 
 	data->data_ready = 1;
@@ -72,6 +73,10 @@
 	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)
@@ -86,50 +91,44 @@
 	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;
 
-	if (data->period > 200)
-		data->period = 200;
-
-	printk(KERN_DEBUG "[GSNR][MPU3050][TIMERIRQ]%s: data->period = %lu\n",
-		__func__, data->period);
-
 	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)
 {
-	int rc = -1;
-
 	dev_dbg(data->dev->this_device,
 		"%s current->pid %lx\n", __func__, (unsigned long)data);
 
-	printk(KERN_DEBUG "[GSNR][MPU3050][TIMERIRQ]%s: data->period = %lu, "
-			  "data->run = %d\n",
-			__func__, data->period, data->run);
-
 	if (data->run) {
 		data->run = FALSE;
 		mod_timer(&data->timer, jiffies + 1);
 		wait_for_completion(&data->timer_done);
-
-		rc = del_timer_sync(&(data->timer));
 	}
 	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)
@@ -142,44 +141,29 @@
 
 	dev_dbg(data->dev->this_device,
 		"%s current->pid %d\n", __func__, current->pid);
-
-	init_completion(&data->timer_done);
-	setup_timer(&data->timer, timerirq_handler, (unsigned long)data);
-
-	printk(KERN_DEBUG "[TIMERIRQ]%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;
-	int rc = -1;
-
-	printk(KERN_DEBUG "[TIMERIRQ] %s: data->run = %d\n",
-				__func__, data->run);
-
-	
-
+	dev_dbg(data->dev->this_device, "timerirq_release\n");
 	if (data->run)
 		stop_timerirq(data);
-
-	rc = del_timer_sync(&(data->timer));
-	printk(KERN_DEBUG "[TIMERIRQ]%s: del_timer_sync"
-		"() return = %d\n", __func__, rc);
-
 	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) {
+	if (!data->data_ready &&
+		data->timeout &&
+		!(file->f_flags & O_NONBLOCK)) {
 		wait_event_interruptible_timeout(data->timerirq_wait,
 						 data->data_ready,
 						 data->timeout);
@@ -189,6 +173,7 @@
 	    && count >= sizeof(data->data)) {
 		err = copy_to_user(buf, &data->data, sizeof(data->data));
 		data->data.data_type = 0;
+		dev_dbg(data->dev->this_device, "%s:copy_to_user\n", __func__);
 	} else {
 		return 0;
 	}
@@ -202,17 +187,20 @@
 	return len;
 }
 
-unsigned int timerirq_poll(struct file *file, struct poll_table_struct *poll)
+static unsigned int timerirq_poll(struct file *file,
+				struct poll_table_struct *poll)
 {
 	int mask = 0;
 	struct timerirq_data *data = file->private_data;
 
 	poll_wait(file, &data->timerirq_wait, poll);
+	dev_dbg(data->dev->this_device, "%s:poll_wait\n", __func__);
 	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)
 {
@@ -252,6 +240,7 @@
 	return retval;
 }
 
+/* define which file operations are supported */
 static const struct file_operations timerirq_fops = {
 	.owner = THIS_MODULE,
 	.read = timerirq_read,
@@ -289,6 +278,8 @@
 		return res;
 	}
 
+	dev_dbg(data->this_device, "%s\n", __func__);
+
 	return res;
 }
 module_init(timerirq_init);
@@ -300,9 +291,6 @@
 	dev_info(data->this_device, "Unregistering %s\n",
 		 data->name);
 
-	printk(KERN_DEBUG "[TIMERIRQ]%s: Unregistering %s\n",
-		__func__, data->name);
-
 	misc_deregister(data);
 	kfree(data);
 
diff --git a/drivers/input/misc/mpu3050/timerirq.h b/drivers/input/misc/mpu3050/timerirq.h
index a38b490..6785d6a 100644
--- a/drivers/input/misc/mpu3050/timerirq.h
+++ b/drivers/input/misc/mpu3050/timerirq.h
@@ -20,9 +20,11 @@
 #ifndef __TIMERIRQ__
 #define __TIMERIRQ__
 
-#define TIMERIRQ_SET_TIMEOUT           (5)
-#define TIMERIRQ_GET_INTERRUPT_CNT     (7)
-#define TIMERIRQ_START                 (8)
-#define TIMERIRQ_STOP                  (9)
+#include <linux/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/i2c/lsm303dlh.h b/include/linux/i2c/lsm303dlh.h
index bb07cc6..9f07adf 100644
--- a/include/linux/i2c/lsm303dlh.h
+++ b/include/linux/i2c/lsm303dlh.h
@@ -39,6 +39,12 @@
 #define	LSM303DLH_MAG_DEV_NAME	"lsm303dlh_mag_sysfs"
 
 
+#define LSM303DLH_ACC_MIN_POLL_PERIOD_MS 1
+#define LSM303DLH_MAG_MIN_POLL_PERIOD_MS 5
+
+#define LSM303DLH_ACC_DEFAULT_INT1_GPIO (-EINVAL)
+#define LSM303DLH_ACC_DEFAULT_INT2_GPIO (-EINVAL)
+
 
 /************************************************/
 /* 	Accelerometer section defines	 	*/
@@ -57,7 +63,23 @@
 #define LSM303DLH_ACC_PM_OFF		LSM303DLH_ACC_DISABLE
 
 
+/* RESUME STATE INDICES */
+#define	RES_CTRL_REG1		0
+#define	RES_CTRL_REG2		1
+#define	RES_CTRL_REG3		2
+#define	RES_CTRL_REG4		3
+#define	RES_CTRL_REG5		4
+#define	RES_REFERENCE		5
 
+#define	RES_INT_CFG1		6
+#define	RES_INT_THS1		7
+#define	RES_INT_DUR1		8
+#define	RES_INT_CFG2		9
+#define	RES_INT_THS2		10
+#define	RES_INT_DUR2		11
+
+#define	RESUME_ENTRIES		12
+/* end RESUME STATE INDICES */
 
 /************************************************/
 /* 	Magnetometer section defines	 	*/
@@ -109,6 +131,40 @@
 	int gpio_int2;
 };
 
+struct lsm303dlh_acc_data {
+	struct i2c_client *client;
+	struct lsm303dlh_acc_platform_data *pdata;
+
+	struct mutex lock;
+	struct delayed_work input_work;
+
+	struct input_dev *input_dev;
+
+	int hw_initialized;
+	/* hw_working=-1 means not tested yet */
+	int hw_working;
+	int selftest_enabled;
+
+	atomic_t enabled;
+	int on_before_suspend;
+
+	u8 sensitivity;
+
+	u8 resume_state[RESUME_ENTRIES];
+
+	int irq1;
+	struct work_struct irq1_work;
+	struct workqueue_struct *irq1_work_queue;
+	int irq2;
+	struct work_struct irq2_work;
+	struct workqueue_struct *irq2_work_queue;
+
+	u8 reg_addr;
+
+	int ext_adap_enabled;
+	void *ext_handle;
+};
+
 struct lsm303dlh_mag_platform_data {
 
 	int poll_interval;
@@ -130,6 +186,30 @@
 	int (*power_off)(void);
 
 };
+
+struct lsm303dlh_mag_data {
+	struct i2c_client *client;
+	struct lsm303dlh_mag_platform_data *pdata;
+
+	struct mutex lock;
+
+	struct input_polled_dev *input_poll_dev;
+
+	int hw_initialized;
+	atomic_t enabled;
+	atomic_t self_test_enabled;
+
+	u16 xy_sensitivity;
+	u16 z_sensitivity;
+
+	u8 resume_state[3];
+
+	u8 reg_addr;
+
+	int on_before_suspend;
+	int ext_adap_enabled;
+	void *ext_handle;
+};
 #endif /* __KERNEL__ */
 
 #endif  /* __LSM303DLH_H__ */
diff --git a/include/linux/mpu.h b/include/linux/mpu.h
index d4e0e91..026a0b7 100644
--- a/include/linux/mpu.h
+++ b/include/linux/mpu.h
@@ -30,82 +30,44 @@
 #include "mpu3050.h"
 #endif
 
+/* Number of axes on each sensor */
 #define GYRO_NUM_AXES               (3)
 #define ACCEL_NUM_AXES              (3)
 #define COMPASS_NUM_AXES            (3)
 
-#define MPU_SET_MPU_CONFIG          (0x00)
-#define MPU_SET_INT_CONFIG          (0x01)
-#define MPU_SET_EXT_SYNC            (0x02)
-#define MPU_SET_FULL_SCALE          (0x03)
-#define MPU_SET_LPF                 (0x04)
-#define MPU_SET_CLK_SRC             (0x05)
-#define MPU_SET_DIVIDER             (0x06)
-#define MPU_SET_LEVEL_SHIFTER       (0x07)
-#define MPU_SET_DMP_ENABLE          (0x08)
-#define MPU_SET_FIFO_ENABLE         (0x09)
-#define MPU_SET_DMP_CFG1            (0x0a)
-#define MPU_SET_DMP_CFG2            (0x0b)
-#define MPU_SET_OFFSET_TC           (0x0c)
-#define MPU_SET_RAM                 (0x0d)
-
-#define MPU_SET_PLATFORM_DATA       (0x0e)
-
-#define MPU_GET_MPU_CONFIG          (0x80)
-#define MPU_GET_INT_CONFIG          (0x81)
-#define MPU_GET_EXT_SYNC            (0x82)
-#define MPU_GET_FULL_SCALE          (0x83)
-#define MPU_GET_LPF                 (0x84)
-#define MPU_GET_CLK_SRC             (0x85)
-#define MPU_GET_DIVIDER             (0x86)
-#define MPU_GET_LEVEL_SHIFTER       (0x87)
-#define MPU_GET_DMP_ENABLE          (0x88)
-#define MPU_GET_FIFO_ENABLE         (0x89)
-#define MPU_GET_DMP_CFG1            (0x8a)
-#define MPU_GET_DMP_CFG2            (0x8b)
-#define MPU_GET_OFFSET_TC           (0x8c)
-#define MPU_GET_RAM                 (0x8d)
-
-#define MPU_READ_REGISTER           (0x40)
-#define MPU_WRITE_REGISTER          (0x41)
-#define MPU_READ_MEMORY             (0x42)
-#define MPU_WRITE_MEMORY            (0x43)
-
-#define MPU_SUSPEND                 (0x44)
-#define MPU_RESUME                  (0x45)
-#define MPU_READ_COMPASS            (0x46)
-#define MPU_READ_ACCEL              (0x47)
-#define MPU_READ_PRESSURE           (0x48)
-
-#define MPU_CONFIG_ACCEL            (0x20)
-#define MPU_CONFIG_COMPASS          (0x21)
-#define MPU_CONFIG_PRESSURE         (0x22)
-
-#define MPU_GET_CONFIG_ACCEL        (0x28)
-#define MPU_GET_CONFIG_COMPASS      (0x29)
-#define MPU_GET_CONFIG_PRESSURE     (0x2a)
-
-#ifdef CONFIG_MACH_HTC
-#define HTC_READ_CAL_DATA
-#endif
-#ifdef HTC_READ_CAL_DATA
-#define MPU_READ_CAL_DATA           (0xef)
-extern unsigned char gyro_gsensor_kvalue[37];
-#endif
-
+/* Structure for the following IOCTL's:
+   MPU_READ
+   MPU_WRITE
+   MPU_READ_MEM
+   MPU_WRITE_MEM
+   MPU_READ_FIFO
+   MPU_WRITE_FIFO
+*/
 struct mpu_read_write {
+	/* Memory address or register address depending on ioctl */
 	unsigned short address;
 	unsigned short length;
 	unsigned char *data;
 };
 
+enum mpuirq_data_type {
+	MPUIRQ_DATA_TYPE_MPU_IRQ,
+	MPUIRQ_DATA_TYPE_SLAVE_IRQ,
+	MPUIRQ_DATA_TYPE_PM_EVENT,
+	MPUIRQ_DATA_TYPE_NUM_TYPES,
+};
+
+/* User space PM event notification */
+#define MPU_PM_EVENT_SUSPEND_PREPARE (3)
+#define MPU_PM_EVENT_POST_SUSPEND    (4)
+
 struct mpuirq_data {
 	int interruptcount;
 	unsigned long long irqtime;
 	int data_type;
-	int data_size;
-	void *data;
+	long data;
 };
+
 enum ext_slave_config_key {
 	MPU_SLAVE_CONFIG_ODR_SUSPEND,
 	MPU_SLAVE_CONFIG_ODR_RESUME,
@@ -119,15 +81,44 @@
 	MPU_SLAVE_CONFIG_IRQ_RESUME,
 	MPU_SLAVE_WRITE_REGISTERS,
 	MPU_SLAVE_READ_REGISTERS,
+	/* AMI 306 specific config keys */
+	MPU_SLAVE_PARAM,
+	MPU_SLAVE_WINDOW,
+	MPU_SLAVE_READWINPARAMS,
+	MPU_SLAVE_SEARCHOFFSET,
+	/* AKM specific config keys */
+	MPU_SLAVE_READ_SCALE,
+	/* YAS specific config keys */
+	MPU_SLAVE_OFFSET_VALS,
+	MPU_SLAVE_RANGE_CHECK,
+
 	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
+ *
+ * @key one of enum ext_slave_config_key
+ * @len length of data pointed to by data
+ * @apply zero if communication with the chip is not necessary, false otherwise
+ *        This flag can be used to select cached data or to refresh cashed data
+ *        cache data to be pushed later or push immediately.  If true and the
+ *        slave is on the secondary bus the MPU will first enger bypass mode
+ *        before calling the slaves .config or .get_config funcion
+ * @data pointer to the data to confgure or get
+ */
 struct ext_slave_config {
 	int key;
 	int len;
@@ -140,7 +131,9 @@
 	EXT_SLAVE_TYPE_ACCELEROMETER,
 	EXT_SLAVE_TYPE_COMPASS,
 	EXT_SLAVE_TYPE_PRESSURE,
-	
+	/*EXT_SLAVE_TYPE_TEMPERATURE */
+
+	EXT_SLAVE_NUM_TYPES
 };
 
 enum ext_slave_id {
@@ -159,7 +152,6 @@
     ACCEL_ID_LIS3DH,
 
 	COMPASS_ID_AKM,
-	COMPASS_ID_AKM8963,
 	COMPASS_ID_AMI30X,
 	COMPASS_ID_YAS529,
 	COMPASS_ID_HMC5883,
@@ -186,6 +178,26 @@
 };
 
 
+/**
+ *  struct ext_slave_platform_data - Platform data for mpu3050 and mpu6050
+ *  slave devices
+ *
+ *  @get_slave_descr: Function pointer to retrieve the struct ext_slave_descr
+ *                    for this slave
+ *  @irq: the irq number attached to the slave if any.
+ *  @adapt_num: the I2C adapter number.
+ *  @bus: the bus the slave is attached to: enum ext_slave_bus
+ *  @address: the I2C slave address of the slave device.
+ *  @orientation: the mounting matrix of the device relative to MPU.
+ *  @irq_data: private data for the slave irq handler
+ *  @private_data: additional data, user customizable.  Not touched by the MPU
+ *                 driver.
+ *
+ * The orientation matricies are 3x3 rotation matricies
+ * that are applied to the data to rotate from the mounting orientation to the
+ * platform orientation.  The values must be one of 0, 1, or -1 and each row and
+ * column should have exactly 1 non-zero value.
+ */
 struct ext_slave_platform_data {
 	struct ext_slave_descr *(*get_slave_descr) (void);
 	int irq;
@@ -195,14 +207,49 @@
 	signed char orientation[9];
 	void *irq_data;
 	void *private_data;
+	void (*bypass_state)(int, char*);
+	int (*check_sleep_status)(void);
+	void (*vote_sleep_status)(int, int);
+
 };
 
-
-struct tFixPntRange {
+struct fix_pnt_range {
 	long mantissa;
 	long fraction;
 };
 
+static inline long range_fixedpoint_to_long_mg(struct fix_pnt_range rng)
+{
+	return (long)(rng.mantissa * 1000 + rng.fraction / 10);
+}
+
+struct ext_slave_read_trigger {
+	unsigned char reg;
+	unsigned char value;
+};
+
+/**
+ *  struct ext_slave_descr - Description of the slave device for programming.
+ *
+ *  @suspend:	function pointer to put the device in suspended state
+ *  @resume:	function pointer to put the device in running state
+ *  @read:	function that reads the device data
+ *  @init:	function used to preallocate memory used by the driver
+ *  @exit:	function used to free memory allocated for the driver
+ *  @config:	function used to configure the device
+ *  @get_config:function used to get the device's configuration
+ *
+ *  @name:	text name of the device
+ *  @type:	device type. enum ext_slave_type
+ *  @id:	enum ext_slave_id
+ *  @reg:	starting register address to retrieve data.
+ *  @len:	length in bytes of the sensor data.  Should be 6.
+ *  @endian:	byte order of the data. enum ext_slave_endian
+ *  @range:	full scale range of the slave ouput: struct tFixPntRange
+ *
+ *  Defines the functions and information about the slave the mpu3050 needs to
+ *  use the slave device.
+ */
 struct ext_slave_descr {
 	int (*init) (void *mlsl_handle,
 		     struct ext_slave_descr *slave,
@@ -242,78 +289,99 @@
 	unsigned char reg;
 	unsigned int len;
 	unsigned char endian;
-	struct tFixPntRange range;
+	struct fix_pnt_range range;
+	struct ext_slave_read_trigger *trigger;
 };
 
+/**
+ * struct mpu3050_platform_data - Platform data for the mpu driver
+ * @int_config:		Bits [7:3] of the int config register.
+ * @orientation:	Orientation matrix of the gyroscope
+ * @level_shifter:	0: VLogic, 1: VDD
+ * @accel:		Accel platform data
+ * @compass:		Compass platform data
+ * @pressure:		Pressure platform data
+ *
+ * Contains platform specific information on how to configure the MPU3050 to
+ * work on this platform.  The orientation matricies are 3x3 rotation matricies
+ * that are applied to the data to rotate from the mounting orientation to the
+ * platform orientation.  The values must be one of 0, 1, or -1 and each row and
+ * column should have exactly 1 non-zero value.
+ */
 struct mpu3050_platform_data {
 	unsigned char int_config;
-	signed char orientation[MPU_NUM_AXES * MPU_NUM_AXES];
+	signed char orientation[GYRO_NUM_AXES * GYRO_NUM_AXES];
 	unsigned char level_shifter;
 	struct ext_slave_platform_data accel;
 	struct ext_slave_platform_data compass;
 	struct ext_slave_platform_data pressure;
-	int (*g_sensors_reset)(void);
-	int (*power_LPM)(int on);
+	int (*setup)(struct device *dev, int enable);
+	void (*hw_config)(int enable);
+	void (*power_mode)(int enable);
 };
 
 
+/*
+    Accelerometer
+*/
 #define get_accel_slave_descr NULL
 
-#ifdef CONFIG_MPU_SENSORS_ADXL346	
+#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_MPU_SENSORS_BMA150	
+#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_MPU_SENSORS_BMA250	
+#ifdef CONFIG_MPU_SENSORS_BMA250	/* Bosch 250 accelerometer */
 struct ext_slave_descr *bma250_get_slave_descr(void);
 #undef get_accel_slave_descr
 #define get_accel_slave_descr bma250_get_slave_descr
 #endif
 
-#ifdef CONFIG_MPU_SENSORS_BMA222	
+#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_MPU_SENSORS_KXSD9	
+#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_MPU_SENSORS_KXTF9	
+#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_MPU_SENSORS_LIS331DLH	
+#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_MPU_SENSORS_LIS3DH	
+#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	
+#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_MPU_SENSORS_MPU6000) || \
     defined(CONFIG_MPU_SENSORS_MPU6000_MODULE)
 struct ext_slave_descr *mantis_get_slave_descr(void);
@@ -321,80 +389,111 @@
 #define get_accel_slave_descr mantis_get_slave_descr
 #endif
 
-#ifdef CONFIG_MPU_SENSORS_MMA8450	
+#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_MPU_SENSORS_MMA845X	
+#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 mma845x_get_slave_descr
 #endif
 
 
+/*
+    Compass
+*/
 #define get_compass_slave_descr NULL
 
-#ifdef CONFIG_MPU_SENSORS_AK8975	
+#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_MPU_SENSORS_AK8963	
-struct ext_slave_descr *ak8963_get_slave_descr(void);
-#undef get_compass_slave_descr
-#define get_compass_slave_descr ak8963_get_slave_descr
-#endif
-
-#ifdef CONFIG_MPU_SENSORS_AMI30X	
+#ifdef CONFIG_MPU_SENSORS_AMI30X	/* AICHI Steel compass */
 struct ext_slave_descr *ami30x_get_slave_descr(void);
 #undef get_compass_slave_descr
 #define get_compass_slave_descr ami30x_get_slave_descr
 #endif
 
-#ifdef CONFIG_MPU_SENSORS_HMC5883	
+#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_MPU_SENSORS_MMC314X	
+#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_MPU_SENSORS_LSM303DLHM	
+#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_MPU_SENSORS_YAS529	
+#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_MPU_SENSORS_HSCDTD002B	
+#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	
+#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_MPU_SENSORS_BMA085	
+#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
 #endif
 
-#endif				
+#define MPU_IOCTL (0x81) /* Magic number for MPU Iocts */
+/* IOCTL commands for /dev/mpu */
+#define MPU_SET_MPU_CONFIG	_IOWR(MPU_IOCTL, 0x00, struct mldl_cfg)
+#define MPU_GET_MPU_CONFIG	_IOW(MPU_IOCTL,  0x00, struct mldl_cfg)
+
+#define MPU_SET_PLATFORM_DATA	_IOWR(MPU_IOCTL, 0x01, struct mldl_cfg)
+
+#define MPU_READ		_IOWR(MPU_IOCTL, 0x10, struct mpu_read_write)
+#define MPU_WRITE		_IOW(MPU_IOCTL,  0x10, struct mpu_read_write)
+#define MPU_READ_MEM		_IOWR(MPU_IOCTL, 0x11, struct mpu_read_write)
+#define MPU_WRITE_MEM		_IOW(MPU_IOCTL,  0x11, struct mpu_read_write)
+#define MPU_READ_FIFO		_IOWR(MPU_IOCTL, 0x12, struct mpu_read_write)
+#define MPU_WRITE_FIFO		_IOW(MPU_IOCTL,  0x12, struct mpu_read_write)
+
+#define MPU_READ_COMPASS	_IOR(MPU_IOCTL, 0x12, 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	_IOWR(MPU_IOCTL, 0x20, struct ext_slave_config)
+#define MPU_GET_CONFIG_COMPASS	_IOWR(MPU_IOCTL, 0x21, struct ext_slave_config)
+#define MPU_GET_CONFIG_PRESSURE	_IOWR(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				/* __MPU_H_ */
diff --git a/include/linux/mpu3050.h b/include/linux/mpu3050.h
index 936d136..034dad8 100644
--- a/include/linux/mpu3050.h
+++ b/include/linux/mpu3050.h
@@ -1,105 +1,98 @@
 /*
  $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_
 #define __MPU3050_H_
 
-#ifdef __KERNEL__
 #include <linux/types.h>
-#endif
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
 
-#ifdef M_HW
-#error MPU6000 build including MPU3050 header
+#if defined(MPUDEBUG)
+#define mpu_dbg(format, arg...)		\
+	printk(KERN_DEBUG format, ## arg);
+#else
+#define mpu_dbg(format, arg...)
 #endif
 
 #define MPU_NAME "mpu3050"
 #define DEFAULT_MPU_SLAVEADDR       0x68
 
+/*==== MPU REGISTER SET ====*/
 enum mpu_register {
-	MPUREG_WHO_AM_I = 0,	
-	MPUREG_PRODUCT_ID,	
-	MPUREG_02_RSVD,		
-	MPUREG_03_RSVD,		
-	MPUREG_04_RSVD,		
-	MPUREG_XG_OFFS_TC,	
-	MPUREG_06_RSVD,		
-	MPUREG_07_RSVD,		
-	MPUREG_YG_OFFS_TC,	
-	MPUREG_09_RSVD,		
-	MPUREG_0A_RSVD,		
-	MPUREG_ZG_OFFS_TC,	
-	MPUREG_X_OFFS_USRH,	
-	MPUREG_X_OFFS_USRL,	
-	MPUREG_Y_OFFS_USRH,	
-	MPUREG_Y_OFFS_USRL,	
-	MPUREG_Z_OFFS_USRH,	
-	MPUREG_Z_OFFS_USRL,	
-	MPUREG_FIFO_EN1,	
-	MPUREG_FIFO_EN2,	
-	MPUREG_AUX_SLV_ADDR,	
-	MPUREG_SMPLRT_DIV,	
-	MPUREG_DLPF_FS_SYNC,	
-	MPUREG_INT_CFG,		
-	MPUREG_ACCEL_BURST_ADDR,
-	MPUREG_19_RSVD,		
-	MPUREG_INT_STATUS,	
-	MPUREG_TEMP_OUT_H,	
-	MPUREG_TEMP_OUT_L,	
-	MPUREG_GYRO_XOUT_H,	
-	MPUREG_GYRO_XOUT_L,	
-	MPUREG_GYRO_YOUT_H,	
-	MPUREG_GYRO_YOUT_L,	
-	MPUREG_GYRO_ZOUT_H,	
-	MPUREG_GYRO_ZOUT_L,	
-	MPUREG_23_RSVD,		
-	MPUREG_24_RSVD,		
-	MPUREG_25_RSVD,		
-	MPUREG_26_RSVD,		
-	MPUREG_27_RSVD,		
-	MPUREG_28_RSVD,		
-	MPUREG_29_RSVD,		
-	MPUREG_2A_RSVD,		
-	MPUREG_2B_RSVD,		
-	MPUREG_2C_RSVD,		
-	MPUREG_2D_RSVD,		
-	MPUREG_2E_RSVD,		
-	MPUREG_2F_RSVD,		
-	MPUREG_30_RSVD,		
-	MPUREG_31_RSVD,		
-	MPUREG_32_RSVD,		
-	MPUREG_33_RSVD,		
-	MPUREG_34_RSVD,		
-	MPUREG_DMP_CFG_1,	
-	MPUREG_DMP_CFG_2,	
-	MPUREG_BANK_SEL,	
-	MPUREG_MEM_START_ADDR,	
-	MPUREG_MEM_R_W,		
-	MPUREG_FIFO_COUNTH,	
-	MPUREG_FIFO_COUNTL,	
-	MPUREG_FIFO_R_W,	
-	MPUREG_USER_CTRL,	
-	MPUREG_PWR_MGM,		
-	MPUREG_3F_RSVD,		
-	NUM_OF_MPU_REGISTERS	
+	MPUREG_WHO_AM_I = 0,	/* 00 0x00 */
+	MPUREG_PRODUCT_ID,	/* 01 0x01 */
+	MPUREG_02_RSVD,		/* 02 0x02 */
+	MPUREG_03_RSVD,		/* 03 0x03 */
+	MPUREG_04_RSVD,		/* 04 0x04 */
+	MPUREG_XG_OFFS_TC,	/* 05 0x05 */
+	MPUREG_06_RSVD,		/* 06 0x06 */
+	MPUREG_07_RSVD,		/* 07 0x07 */
+	MPUREG_YG_OFFS_TC,	/* 08 0x08 */
+	MPUREG_09_RSVD,		/* 09 0x09 */
+	MPUREG_0A_RSVD,		/* 10 0x0a */
+	MPUREG_ZG_OFFS_TC,	/* 11 0x0b */
+	MPUREG_X_OFFS_USRH,	/* 12 0x0c */
+	MPUREG_X_OFFS_USRL,	/* 13 0x0d */
+	MPUREG_Y_OFFS_USRH,	/* 14 0x0e */
+	MPUREG_Y_OFFS_USRL,	/* 15 0x0f */
+	MPUREG_Z_OFFS_USRH,	/* 16 0x10 */
+	MPUREG_Z_OFFS_USRL,	/* 17 0x11 */
+	MPUREG_FIFO_EN1,	/* 18 0x12 */
+	MPUREG_FIFO_EN2,	/* 19 0x13 */
+	MPUREG_AUX_SLV_ADDR,	/* 20 0x14 */
+	MPUREG_SMPLRT_DIV,	/* 21 0x15 */
+	MPUREG_DLPF_FS_SYNC,	/* 22 0x16 */
+	MPUREG_INT_CFG,		/* 23 0x17 */
+	MPUREG_ACCEL_BURST_ADDR,/* 24 0x18 */
+	MPUREG_19_RSVD,		/* 25 0x19 */
+	MPUREG_INT_STATUS,	/* 26 0x1a */
+	MPUREG_TEMP_OUT_H,	/* 27 0x1b */
+	MPUREG_TEMP_OUT_L,	/* 28 0x1c */
+	MPUREG_GYRO_XOUT_H,	/* 29 0x1d */
+	MPUREG_GYRO_XOUT_L,	/* 30 0x1e */
+	MPUREG_GYRO_YOUT_H,	/* 31 0x1f */
+	MPUREG_GYRO_YOUT_L,	/* 32 0x20 */
+	MPUREG_GYRO_ZOUT_H,	/* 33 0x21 */
+	MPUREG_GYRO_ZOUT_L,	/* 34 0x22 */
+	MPUREG_23_RSVD,		/* 35 0x23 */
+	MPUREG_24_RSVD,		/* 36 0x24 */
+	MPUREG_25_RSVD,		/* 37 0x25 */
+	MPUREG_26_RSVD,		/* 38 0x26 */
+	MPUREG_27_RSVD,		/* 39 0x27 */
+	MPUREG_28_RSVD,		/* 40 0x28 */
+	MPUREG_29_RSVD,		/* 41 0x29 */
+	MPUREG_2A_RSVD,		/* 42 0x2a */
+	MPUREG_2B_RSVD,		/* 43 0x2b */
+	MPUREG_2C_RSVD,		/* 44 0x2c */
+	MPUREG_2D_RSVD,		/* 45 0x2d */
+	MPUREG_2E_RSVD,		/* 46 0x2e */
+	MPUREG_2F_RSVD,		/* 47 0x2f */
+	MPUREG_30_RSVD,		/* 48 0x30 */
+	MPUREG_31_RSVD,		/* 49 0x31 */
+	MPUREG_32_RSVD,		/* 50 0x32 */
+	MPUREG_33_RSVD,		/* 51 0x33 */
+	MPUREG_34_RSVD,		/* 52 0x34 */
+	MPUREG_DMP_CFG_1,	/* 53 0x35 */
+	MPUREG_DMP_CFG_2,	/* 54 0x36 */
+	MPUREG_BANK_SEL,	/* 55 0x37 */
+	MPUREG_MEM_START_ADDR,	/* 56 0x38 */
+	MPUREG_MEM_R_W,		/* 57 0x39 */
+	MPUREG_FIFO_COUNTH,	/* 58 0x3a */
+	MPUREG_FIFO_COUNTL,	/* 59 0x3b */
+	MPUREG_FIFO_R_W,	/* 60 0x3c */
+	MPUREG_USER_CTRL,	/* 61 0x3d */
+	MPUREG_PWR_MGM,		/* 62 0x3e */
+	MPUREG_3F_RSVD,		/* 63 0x3f */
+	NUM_OF_MPU_REGISTERS	/* 64 0x40 */
 };
 
+/*==== BITS FOR MPU ====*/
 
+/*---- MPU 'FIFO_EN1' register (12) ----*/
 #define BIT_TEMP_OUT                0x80
 #define BIT_GYRO_XOUT               0x40
 #define BIT_GYRO_YOUT               0x20
@@ -108,8 +101,10 @@
 #define BIT_ACCEL_YOUT              0x04
 #define BIT_ACCEL_ZOUT              0x02
 #define BIT_AUX_1OUT                0x01
+/*---- MPU 'FIFO_EN2' register (13) ----*/
 #define BIT_AUX_2OUT                0x02
 #define BIT_AUX_3OUT                0x01
+/*---- MPU 'DLPF_FS_SYNC' register (16) ----*/
 #define BITS_EXT_SYNC_NONE          0x00
 #define BITS_EXT_SYNC_TEMP          0x20
 #define BITS_EXT_SYNC_GYROX         0x40
@@ -133,6 +128,7 @@
 #define BITS_DLPF_CFG_5HZ           0x06
 #define BITS_DLPF_CFG_2100HZ_NOLPF  0x07
 #define BITS_DLPF_CFG_MASK          0x07
+/*---- MPU 'INT_CFG' register (17) ----*/
 #define BIT_ACTL                    0x80
 #define BIT_ACTL_LOW                0x80
 #define BIT_ACTL_HIGH               0x00
@@ -147,13 +143,16 @@
 #define BIT_MPU_RDY_EN              0x04
 #define BIT_DMP_INT_EN              0x02
 #define BIT_RAW_RDY_EN              0x01
+/*---- MPU 'INT_STATUS' register (1A) ----*/
 #define BIT_INT_STATUS_FIFO_OVERLOW 0x80
 #define BIT_MPU_RDY                 0x04
 #define BIT_DMP_INT                 0x02
 #define BIT_RAW_RDY                 0x01
+/*---- MPU 'BANK_SEL' register (37) ----*/
 #define BIT_PRFTCH_EN               0x20
 #define BIT_CFG_USER_BANK           0x10
 #define BITS_MEM_SEL                0x0f
+/*---- MPU 'USER_CTRL' register (3D) ----*/
 #define BIT_DMP_EN                  0x80
 #define BIT_FIFO_EN                 0x40
 #define BIT_AUX_IF_EN               0x20
@@ -162,6 +161,7 @@
 #define BIT_DMP_RST                 0x04
 #define BIT_FIFO_RST                0x02
 #define BIT_GYRO_RST                0x01
+/*---- MPU 'PWR_MGM' register (3E) ----*/
 #define BIT_H_RESET                 0x80
 #define BIT_SLEEP                   0x40
 #define BIT_STBY_XG                 0x20
@@ -169,11 +169,13 @@
 #define BIT_STBY_ZG                 0x08
 #define BITS_CLKSEL                 0x07
 
-#define MPU_SILICON_REV_A4           1	
-#define MPU_SILICON_REV_B1           2	
-#define MPU_SILICON_REV_B4           3	
-#define MPU_SILICON_REV_B6           4	
+/*---- MPU Silicon Revision ----*/
+#define MPU_SILICON_REV_A4           1	/* MPU A4 Device */
+#define MPU_SILICON_REV_B1           2	/* MPU B1 Device */
+#define MPU_SILICON_REV_B4           3	/* MPU B4 Device */
+#define MPU_SILICON_REV_B6           4	/* MPU B6 Device */
 
+/*---- MPU Memory ----*/
 #define MPU_MEM_BANK_SIZE           (256)
 #define FIFO_HW_SIZE                (512)
 
@@ -184,12 +186,15 @@
 	MPU_MEM_RAM_BANK_3,
 	MPU_MEM_NUM_RAM_BANKS,
 	MPU_MEM_OTP_BANK_0 = MPU_MEM_NUM_RAM_BANKS,
-	
+	/* This one is always last */
 	MPU_MEM_NUM_BANKS
 };
 
 #define MPU_NUM_AXES (3)
 
+/*---- structure containing control variables used by MLDL ----*/
+/*---- MPU clock source settings ----*/
+/*---- MPU filter selections ----*/
 enum mpu_filter {
 	MPU_FILTER_256HZ_NOLPF2 = 0,
 	MPU_FILTER_188HZ,
@@ -237,4 +242,4 @@
 #define DLPF_FS_SYNC_VALUE(ext_sync, full_scale, lpf) \
     ((ext_sync << 5) | (full_scale << 3) | lpf)
 
-#endif				
+#endif				/* __MPU3050_H_ */