input: mpu3050: adjust LPF bandwidth according to sampling frequency.

Low pass filter bandwidth is configured to be equal to or greater than
half of the sampling freqency.

Signed-off-by: Wentao Xu <wentaox@codeaurora.org>
(cherry picked from commit 04f4cc9ff3707a39af39c23cc9f3aeb5c344c60c)

Signed-off-by: Sudhir Sharma <sudsha@codeaurora.org>
(cherry picked from commit a7d8fe1d40061ec56c938308d8f7265f29b146c1)

Change-Id: I796d30d474aa64c1679781b38ca5f151b37c92fd
Signed-off-by: Sudhir Sharma <sudsha@codeaurora.org>
diff --git a/drivers/input/misc/mpu3050.c b/drivers/input/misc/mpu3050.c
index d3da652..04a7598 100644
--- a/drivers/input/misc/mpu3050.c
+++ b/drivers/input/misc/mpu3050.c
@@ -123,6 +123,7 @@
 	struct delayed_work input_work;
 	u32    use_poll;
 	u32    poll_interval;
+	u32    dlpf_index;
 };
 
 struct sensor_regulator {
@@ -137,6 +138,39 @@
 	{NULL, "vlogic", 1800000, 1800000},
 };
 
+struct dlpf_cfg_tb {
+	u8  cfg;	/* cfg index */
+	u32 lpf_bw;	/* low pass filter bandwidth in Hz */
+	u32 sample_rate; /* analog sample rate in Khz, 1 or 8 */
+};
+
+static struct dlpf_cfg_tb dlpf_table[] = {
+	{6,   5, 1},
+	{5,  10, 1},
+	{4,  20, 1},
+	{3,  42, 1},
+	{2,  98, 1},
+	{1, 188, 1},
+	{0, 256, 8},
+};
+
+static u8 interval_to_dlpf_cfg(u32 interval)
+{
+	u32 sample_rate = 1000 / interval;
+	u32 i;
+
+	/* the filter bandwidth needs to be greater or
+	 * equal to half of the sample rate
+	 */
+	for (i = 0; i < sizeof(dlpf_table)/sizeof(dlpf_table[0]); i++) {
+		if (dlpf_table[i].lpf_bw * 2 >= sample_rate)
+			return i;
+	}
+
+	/* return the maximum possible */
+	return --i;
+}
+
 static int mpu3050_config_regulator(struct i2c_client *client, bool on)
 {
 	int rc = 0, i;
@@ -217,6 +251,9 @@
 {
 	struct mpu3050_sensor *sensor = dev_get_drvdata(dev);
 	unsigned long interval_ms;
+	unsigned int  dlpf_index;
+	u8  divider, reg;
+	int ret;
 
 	if (kstrtoul(buf, 10, &interval_ms))
 		return -EINVAL;
@@ -224,12 +261,27 @@
 		(interval_ms > MPU3050_MAX_POLL_INTERVAL))
 		return -EINVAL;
 
-	if (sensor)
-		sensor->poll_interval = interval_ms;
+	dlpf_index = interval_to_dlpf_cfg(interval_ms);
+	divider = interval_ms * dlpf_table[dlpf_index].sample_rate - 1;
 
-	/* Output frequency divider. The poll interval */
-	i2c_smbus_write_byte_data(sensor->client, MPU3050_SMPLRT_DIV,
-					interval_ms - 1);
+	if (sensor->dlpf_index != dlpf_index) {
+		/* Set low pass filter and full scale */
+		reg = dlpf_table[dlpf_index].cfg;
+		reg |= MPU3050_DEFAULT_FS_RANGE << 3;
+		reg |= MPU3050_EXT_SYNC_NONE << 5;
+		ret = i2c_smbus_write_byte_data(sensor->client,
+				MPU3050_DLPF_FS_SYNC, reg);
+		if (ret == 0)
+			sensor->dlpf_index = dlpf_index;
+	}
+
+	if (sensor->poll_interval != interval_ms) {
+		/* Output frequency divider. The poll interval */
+		ret = i2c_smbus_write_byte_data(sensor->client,
+				MPU3050_SMPLRT_DIV, divider);
+		if (ret == 0)
+			sensor->poll_interval = interval_ms;
+	}
 
 	return size;
 }
@@ -482,8 +534,8 @@
 		return ret;
 
 	/* Set low pass filter and full scale */
-	reg = MPU3050_DEFAULT_FS_RANGE;
-	reg |= MPU3050_DLPF_CFG_42HZ << 3;
+	reg = MPU3050_DLPF_CFG_42HZ;
+	reg |= MPU3050_DEFAULT_FS_RANGE << 3;
 	reg |= MPU3050_EXT_SYNC_NONE << 5;
 	ret = i2c_smbus_write_byte_data(client, MPU3050_DLPF_FS_SYNC, reg);
 	if (ret < 0)