input: mpu3050: Add HTC version of MPU3050 sensor

HTC kernel version: evitaul-jb-crc-3.4.10-ec474a3

Change-Id: I53903035d40fe4eae1b4240068765c3e32a31ddd
diff --git a/drivers/input/misc/mpu3050/mlsl-kernel.c b/drivers/input/misc/mpu3050/mlsl-kernel.c
new file mode 100644
index 0000000..d5bc256
--- /dev/null
+++ b/drivers/input/misc/mpu3050/mlsl-kernel.c
@@ -0,0 +1,229 @@
+/*
+ $License:
+    Copyright (C) 2010 InvenSense Corporation, All Rights Reserved.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+  $
+ */
+
+#include "mlsl.h"
+#include "mpu-i2c.h"
+
+
+
+
+tMLError MLSLSerialOpen(char const *port, void **sl_handle)
+{
+	return ML_SUCCESS;
+}
+
+tMLError MLSLSerialReset(void *sl_handle)
+{
+	return ML_SUCCESS;
+}
+
+tMLError MLSLSerialClose(void *sl_handle)
+{
+	return ML_SUCCESS;
+}
+
+tMLError 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);
+}
+
+
+tMLError MLSLSerialWrite(void *sl_handle,
+			 unsigned char slaveAddr,
+			 unsigned short length, unsigned char const *data)
+{
+	tMLError result;
+	const unsigned short dataLength = length - 1;
+	const unsigned char startRegAddr = data[0];
+	unsigned char i2cWrite[SERIAL_MAX_TRANSFER_SIZE + 1];
+	unsigned short bytesWritten = 0;
+
+	while (bytesWritten < dataLength) {
+		unsigned short thisLen = min(SERIAL_MAX_TRANSFER_SIZE,
+					     dataLength - bytesWritten);
+		if (bytesWritten == 0) {
+			result = sensor_i2c_write((struct i2c_adapter *)
+						  sl_handle, slaveAddr,
+						  1 + thisLen, data);
+		} else {
+			
+			i2cWrite[0] = startRegAddr + bytesWritten;
+			memcpy(&i2cWrite[1], &data[1 + bytesWritten],
+			       thisLen);
+			result = sensor_i2c_write((struct i2c_adapter *)
+						  sl_handle, slaveAddr,
+						  1 + thisLen, i2cWrite);
+		}
+		if (ML_SUCCESS != result)
+			return result;
+		bytesWritten += thisLen;
+	}
+	return ML_SUCCESS;
+}
+
+
+tMLError MLSLSerialRead(void *sl_handle,
+			unsigned char slaveAddr,
+			unsigned char registerAddr,
+			unsigned short length, unsigned char *data)
+{
+	tMLError result;
+	unsigned short bytesRead = 0;
+
+	if (registerAddr == MPUREG_FIFO_R_W
+	    || registerAddr == MPUREG_MEM_R_W) {
+		return ML_ERROR_INVALID_PARAMETER;
+	}
+	while (bytesRead < length) {
+		unsigned short thisLen =
+		    min(SERIAL_MAX_TRANSFER_SIZE, length - bytesRead);
+		result =
+		    sensor_i2c_read((struct i2c_adapter *) sl_handle,
+				    slaveAddr, registerAddr + bytesRead,
+				    thisLen, &data[bytesRead]);
+		if (ML_SUCCESS != result)
+			return result;
+		bytesRead += thisLen;
+	}
+	return ML_SUCCESS;
+}
+
+
+tMLError MLSLSerialWriteMem(void *sl_handle,
+			    unsigned char slaveAddr,
+			    unsigned short memAddr,
+			    unsigned short length,
+			    unsigned char const *data)
+{
+	tMLError 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);
+		return ML_ERROR_INVALID_PARAMETER;
+	}
+	while (bytesWritten < length) {
+		unsigned short thisLen =
+		    min(SERIAL_MAX_TRANSFER_SIZE, length - bytesWritten);
+		result =
+		    mpu_memory_write((struct i2c_adapter *) sl_handle,
+				     slaveAddr, memAddr + bytesWritten,
+				     thisLen, &data[bytesWritten]);
+		if (ML_SUCCESS != result)
+			return result;
+		bytesWritten += thisLen;
+	}
+	return ML_SUCCESS;
+}
+
+
+tMLError MLSLSerialReadMem(void *sl_handle,
+			   unsigned char slaveAddr,
+			   unsigned short memAddr,
+			   unsigned short length, unsigned char *data)
+{
+	tMLError result;
+	unsigned short bytesRead = 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);
+		return ML_ERROR_INVALID_PARAMETER;
+	}
+	while (bytesRead < length) {
+		unsigned short thisLen =
+		    min(SERIAL_MAX_TRANSFER_SIZE, length - bytesRead);
+		result =
+		    mpu_memory_read((struct i2c_adapter *) sl_handle,
+				    slaveAddr, memAddr + bytesRead,
+				    thisLen, &data[bytesRead]);
+		if (ML_SUCCESS != result)
+			return result;
+		bytesRead += thisLen;
+	}
+	return ML_SUCCESS;
+}
+
+
+tMLError MLSLSerialWriteFifo(void *sl_handle,
+			     unsigned char slaveAddr,
+			     unsigned short length,
+			     unsigned char const *data)
+{
+	tMLError result;
+	unsigned char i2cWrite[SERIAL_MAX_TRANSFER_SIZE + 1];
+	unsigned short bytesWritten = 0;
+
+	if (length > FIFO_HW_SIZE) {
+		printk(KERN_ERR
+		       "maximum fifo write length is %d\n", FIFO_HW_SIZE);
+		return ML_ERROR_INVALID_PARAMETER;
+	}
+	while (bytesWritten < length) {
+		unsigned short thisLen =
+		    min(SERIAL_MAX_TRANSFER_SIZE, length - bytesWritten);
+		i2cWrite[0] = MPUREG_FIFO_R_W;
+		memcpy(&i2cWrite[1], &data[bytesWritten], thisLen);
+		result = sensor_i2c_write((struct i2c_adapter *) sl_handle,
+					  slaveAddr, thisLen + 1,
+					  i2cWrite);
+		if (ML_SUCCESS != result)
+			return result;
+		bytesWritten += thisLen;
+	}
+	return ML_SUCCESS;
+}
+
+
+tMLError MLSLSerialReadFifo(void *sl_handle,
+			    unsigned char slaveAddr,
+			    unsigned short length, unsigned char *data)
+{
+	tMLError result;
+	unsigned short bytesRead = 0;
+
+	if (length > FIFO_HW_SIZE) {
+		printk(KERN_ERR
+		       "maximum fifo read length is %d\n", FIFO_HW_SIZE);
+		return ML_ERROR_INVALID_PARAMETER;
+	}
+	while (bytesRead < length) {
+		unsigned short thisLen =
+		    min(SERIAL_MAX_TRANSFER_SIZE, length - bytesRead);
+		result =
+		    sensor_i2c_read((struct i2c_adapter *) sl_handle,
+				    slaveAddr, MPUREG_FIFO_R_W, thisLen,
+				    &data[bytesRead]);
+		if (ML_SUCCESS != result)
+			return result;
+		bytesRead += thisLen;
+	}
+
+	return ML_SUCCESS;
+}
+