aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/sensorhub/atmel/ssp_data.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/sensorhub/atmel/ssp_data.c')
-rwxr-xr-xdrivers/sensorhub/atmel/ssp_data.c275
1 files changed, 275 insertions, 0 deletions
diff --git a/drivers/sensorhub/atmel/ssp_data.c b/drivers/sensorhub/atmel/ssp_data.c
new file mode 100755
index 00000000000..09d5c099ac6
--- /dev/null
+++ b/drivers/sensorhub/atmel/ssp_data.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2012, Samsung Electronics Co. Ltd. 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.
+ *
+ */
+#include "ssp.h"
+
+/* SSP -> AP Instruction */
+#define MSG2AP_INST_BYPASS_DATA 0x00
+#define MSG2AP_INST_LIBRARY_DATA 0x01
+#define MSG2AP_INST_SELFTEST_DATA 0x02
+#define MSG2AP_INST_DEBUG_DATA 0x03
+
+/* Factory data length */
+#define ACCEL_FACTORY_DATA_LENGTH 1
+#define GYRO_FACTORY_DATA_LENGTH 27
+#define MAGNETIC_FACTORY_DATA_LENGTH 6
+#define PRESSURE_FACTORY_DATA_LENGTH 1
+#define MCU_FACTORY_DATA_LENGTH 5
+#define GYRO_TEMP_FACTORY_DATA_LENGTH 1
+#define GYRO_DPS_FACTORY_DATA_LENGTH 1
+#define MCU_SLEEP_FACTORY_DATA_LENGTH 39
+
+/*************************************************************************/
+/* SSP parsing the dataframe */
+/*************************************************************************/
+
+static void get_3axis_sensordata(char *pchRcvDataFrame, int *iDataIdx,
+ struct sensor_value *sensorsdata)
+{
+ int iTemp;
+
+ iTemp = (int)pchRcvDataFrame[(*iDataIdx)++];
+ iTemp <<= 8;
+ iTemp += pchRcvDataFrame[(*iDataIdx)++];
+ sensorsdata->x = iTemp;
+
+ iTemp = (int)pchRcvDataFrame[(*iDataIdx)++];
+ iTemp <<= 8;
+ iTemp += pchRcvDataFrame[(*iDataIdx)++];
+ sensorsdata->y = iTemp;
+
+ iTemp = (int)pchRcvDataFrame[(*iDataIdx)++];
+ iTemp <<= 8;
+ iTemp += pchRcvDataFrame[(*iDataIdx)++];
+ sensorsdata->z = iTemp;
+}
+
+static void get_light_sensordata(char *pchRcvDataFrame, int *iDataIdx,
+ struct sensor_value *sensorsdata)
+{
+ int iTemp;
+
+ iTemp = (int)pchRcvDataFrame[(*iDataIdx)++];
+ iTemp <<= 8;
+ iTemp += pchRcvDataFrame[(*iDataIdx)++];
+ sensorsdata->r = iTemp;
+
+ iTemp = (int)pchRcvDataFrame[(*iDataIdx)++];
+ iTemp <<= 8;
+ iTemp += pchRcvDataFrame[(*iDataIdx)++];
+ sensorsdata->g = iTemp;
+
+ iTemp = (int)pchRcvDataFrame[(*iDataIdx)++];
+ iTemp <<= 8;
+ iTemp += pchRcvDataFrame[(*iDataIdx)++];
+ sensorsdata->b = iTemp;
+
+ iTemp = (int)pchRcvDataFrame[(*iDataIdx)++];
+ iTemp <<= 8;
+ iTemp += pchRcvDataFrame[(*iDataIdx)++];
+ sensorsdata->w = iTemp;
+}
+
+static void get_pressure_sensordata(char *pchRcvDataFrame, int *iDataIdx,
+ struct sensor_value *sensorsdata)
+{
+ int iTemp;
+
+ iTemp = (int)pchRcvDataFrame[(*iDataIdx)++];
+ iTemp <<= 16;
+ sensorsdata->pressure[0] = iTemp;
+
+ iTemp = (int)pchRcvDataFrame[(*iDataIdx)++];
+ iTemp <<= 8;
+ sensorsdata->pressure[0] += iTemp;
+
+ iTemp = (int)pchRcvDataFrame[(*iDataIdx)++];
+ sensorsdata->pressure[0] += iTemp;
+
+ iTemp = (int)pchRcvDataFrame[(*iDataIdx)++];
+ iTemp <<= 8;
+ iTemp += (int)pchRcvDataFrame[(*iDataIdx)++];
+ sensorsdata->pressure[1] = (s16)iTemp;
+}
+
+static void get_gesture_sensordata(char *pchRcvDataFrame, int *iDataIdx,
+ struct sensor_value *sensorsdata)
+{
+ int iTemp;
+
+ iTemp = (int)pchRcvDataFrame[(*iDataIdx)++];
+ iTemp <<= 8;
+ iTemp += pchRcvDataFrame[(*iDataIdx)++];
+ sensorsdata->data[0] = iTemp;
+
+ iTemp = (int)pchRcvDataFrame[(*iDataIdx)++];
+ iTemp <<= 8;
+ iTemp += pchRcvDataFrame[(*iDataIdx)++];
+ sensorsdata->data[1] = iTemp;
+
+ iTemp = (int)pchRcvDataFrame[(*iDataIdx)++];
+ iTemp <<= 8;
+ iTemp += pchRcvDataFrame[(*iDataIdx)++];
+ sensorsdata->data[2] = iTemp;
+
+ iTemp = (int)pchRcvDataFrame[(*iDataIdx)++];
+ iTemp <<= 8;
+ iTemp += pchRcvDataFrame[(*iDataIdx)++];
+ sensorsdata->data[3] = iTemp;
+}
+
+static void get_proximity_sensordata(char *pchRcvDataFrame, int *iDataIdx,
+ struct sensor_value *sensorsdata)
+{
+ sensorsdata->prox[0] = (u8)pchRcvDataFrame[(*iDataIdx)++];
+ sensorsdata->prox[1] = (u8)pchRcvDataFrame[(*iDataIdx)++];
+}
+
+static void get_proximity_rawdata(char *pchRcvDataFrame, int *iDataIdx,
+ struct sensor_value *sensorsdata)
+{
+ sensorsdata->prox[0] = (u8)pchRcvDataFrame[(*iDataIdx)++];
+}
+
+static void get_factoty_data(struct ssp_data *data, int iSensorData,
+ char *pchRcvDataFrame, int *iDataIdx)
+{
+ int iIdx, iTotalLenth = 0;
+ unsigned int uTemp = 0;
+
+ switch (iSensorData) {
+ case ACCELEROMETER_FACTORY:
+ uTemp = (1 << ACCELEROMETER_FACTORY);
+ iTotalLenth = ACCEL_FACTORY_DATA_LENGTH;
+ break;
+ case GYROSCOPE_FACTORY:
+ uTemp = (1 << GYROSCOPE_FACTORY);
+ iTotalLenth = GYRO_FACTORY_DATA_LENGTH;
+ break;
+ case GEOMAGNETIC_FACTORY:
+ uTemp = (1 << GEOMAGNETIC_FACTORY);
+ iTotalLenth = MAGNETIC_FACTORY_DATA_LENGTH;
+ break;
+ case PRESSURE_FACTORY:
+ uTemp = (1 << PRESSURE_FACTORY);
+ iTotalLenth = PRESSURE_FACTORY_DATA_LENGTH;
+ break;
+ case MCU_FACTORY:
+ uTemp = (1 << MCU_FACTORY);
+ iTotalLenth = MCU_FACTORY_DATA_LENGTH;
+ break;
+ case GYROSCOPE_TEMP_FACTORY:
+ uTemp = (1 << GYROSCOPE_TEMP_FACTORY);
+ iTotalLenth = GYRO_TEMP_FACTORY_DATA_LENGTH;
+ break;
+ case GYROSCOPE_DPS_FACTORY:
+ uTemp = (1 << GYROSCOPE_DPS_FACTORY);
+ iTotalLenth = GYRO_DPS_FACTORY_DATA_LENGTH;
+ break;
+ case MCU_SLEEP_FACTORY:
+ uTemp = (1 << MCU_SLEEP_FACTORY);
+ iTotalLenth = MCU_SLEEP_FACTORY_DATA_LENGTH;
+ break;
+ }
+
+ ssp_dbg("[SSP]: %s - Factory test data %d\n", __func__, iSensorData);
+ for (iIdx = 0; iIdx < iTotalLenth; iIdx++)
+ data->uFactorydata[iIdx] = (u8)pchRcvDataFrame[(*iDataIdx)++];
+
+ data->uFactorydataReady = uTemp;
+}
+
+int parse_dataframe(struct ssp_data *data, char *pchRcvDataFrame, int iLength)
+{
+ int iDataIdx, iSensorData;
+ struct sensor_value *sensorsdata;
+
+ sensorsdata = kzalloc(sizeof(*sensorsdata), GFP_KERNEL);
+ if (sensorsdata == NULL)
+ return ERROR;
+
+ for (iDataIdx = 0; iDataIdx < iLength;) {
+ if (pchRcvDataFrame[iDataIdx] == MSG2AP_INST_BYPASS_DATA) {
+ iDataIdx++;
+ iSensorData = pchRcvDataFrame[iDataIdx++];
+ if ((iSensorData < 0) ||
+ (iSensorData >= (SENSOR_MAX - 1))) {
+ pr_err("[SSP]: %s - Mcu data frame1 error %d\n",
+ __func__, iSensorData);
+ kfree(sensorsdata);
+ return ERROR;
+ }
+
+ data->get_sensor_data[iSensorData](pchRcvDataFrame,
+ &iDataIdx, sensorsdata);
+ data->report_sensor_data[iSensorData](data,
+ sensorsdata);
+ } else if (pchRcvDataFrame[iDataIdx] ==
+ MSG2AP_INST_SELFTEST_DATA) {
+ iDataIdx++;
+ iSensorData = pchRcvDataFrame[iDataIdx++];
+ if ((iSensorData < 0) ||
+ (iSensorData >= SENSOR_FACTORY_MAX)) {
+ pr_err("[SSP]: %s - Mcu data frame2 error %d\n",
+ __func__, iSensorData);
+ kfree(sensorsdata);
+ return ERROR;
+ }
+ get_factoty_data(data, iSensorData, pchRcvDataFrame,
+ &iDataIdx);
+ } else if (pchRcvDataFrame[iDataIdx] ==
+ MSG2AP_INST_DEBUG_DATA) {
+ iSensorData
+ = print_mcu_debug(pchRcvDataFrame + iDataIdx+1,
+ &iDataIdx, iLength);
+ if (iSensorData) {
+ pr_err("[SSP]: %s - Mcu data frame3 error %d\n",
+ __func__, iSensorData);
+ kfree(sensorsdata);
+ return ERROR;
+ }
+#ifdef CONFIG_SENSORS_SSP_SENSORHUB
+ } else if (pchRcvDataFrame[iDataIdx] ==
+ MSG2AP_INST_LIBRARY_DATA) {
+ ssp_sensorhub_handle_data(data,
+ pchRcvDataFrame, iDataIdx, iLength);
+ break;
+#endif
+ } else
+ iDataIdx++;
+ }
+ kfree(sensorsdata);
+ return SUCCESS;
+}
+
+void initialize_function_pointer(struct ssp_data *data)
+{
+ data->get_sensor_data[ACCELEROMETER_SENSOR] = get_3axis_sensordata;
+ data->get_sensor_data[GYROSCOPE_SENSOR] = get_3axis_sensordata;
+ data->get_sensor_data[GEOMAGNETIC_SENSOR] = get_3axis_sensordata;
+ data->get_sensor_data[PRESSURE_SENSOR] = get_pressure_sensordata;
+ data->get_sensor_data[GESTURE_SENSOR] = get_gesture_sensordata;
+ data->get_sensor_data[PROXIMITY_SENSOR] = get_proximity_sensordata;
+ data->get_sensor_data[PROXIMITY_RAW] = get_proximity_rawdata;
+ data->get_sensor_data[LIGHT_SENSOR] = get_light_sensordata;
+
+ data->report_sensor_data[ACCELEROMETER_SENSOR] = report_acc_data;
+ data->report_sensor_data[GYROSCOPE_SENSOR] = report_gyro_data;
+ data->report_sensor_data[GEOMAGNETIC_SENSOR] = report_mag_data;
+ data->report_sensor_data[PRESSURE_SENSOR] = report_pressure_data;
+ data->report_sensor_data[GESTURE_SENSOR] = report_gesture_data;
+ data->report_sensor_data[PROXIMITY_SENSOR] = report_prox_data;
+ data->report_sensor_data[PROXIMITY_RAW] = report_prox_raw_data;
+ data->report_sensor_data[LIGHT_SENSOR] = report_light_data;
+}