123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360 |
- /*
- * 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 0x37
- #define MSG2AP_INST_LIBRARY_DATA 0x01
- #define MSG2AP_INST_DEBUG_DATA 0x03
- #define MSG2AP_INST_BIG_DATA 0x04
- #define MSG2AP_INST_META_DATA 0x05
- #define MSG2AP_INST_TIME_SYNC 0x06
- #define MSG2AP_INST_RESET 0x07
- /*************************************************************************/
- /* SSP parsing the dataframe */
- /*************************************************************************/
- static void get_timestamp(struct ssp_data *data, char *pchRcvDataFrame,
- int *iDataIdx, struct sensor_value *sensorsdata) {
- s32 otimestamp = 0;
- s64 ctimestamp = 0;
- memcpy(&otimestamp, pchRcvDataFrame + *iDataIdx, 4);
- *iDataIdx += 4;
- ctimestamp = (s64) otimestamp * 1000000;
- sensorsdata->timestamp = data->timestamp + ctimestamp;
- }
- static void get_3axis_sensordata(char *pchRcvDataFrame, int *iDataIdx,
- struct sensor_value *sensorsdata)
- {
- memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 6);
- *iDataIdx += 6;
- }
- static void get_uncalib_sensordata(char *pchRcvDataFrame, int *iDataIdx,
- struct sensor_value *sensorsdata)
- {
- memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 12);
- *iDataIdx += 12;
- }
- static void get_geomagnetic_uncaldata(char *pchRcvDataFrame, int *iDataIdx,
- struct sensor_value *sensorsdata)
- {
- memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 12);
- *iDataIdx += 12;
- }
- static void get_geomagnetic_rawdata(char *pchRcvDataFrame, int *iDataIdx,
- struct sensor_value *sensorsdata)
- {
- memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 6);
- *iDataIdx += 6;
- }
- static void get_geomagnetic_caldata(char *pchRcvDataFrame, int *iDataIdx,
- struct sensor_value *sensorsdata)
- {
- #ifdef SAVE_MAG_LOG
- memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 20);
- *iDataIdx += 20;
- #else
- memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 7);
- *iDataIdx += 7;
- #endif
- }
- static void get_rot_sensordata(char *pchRcvDataFrame, int *iDataIdx,
- struct sensor_value *sensorsdata)
- {
- memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 17);
- *iDataIdx += 17;
- }
- static void get_step_det_sensordata(char *pchRcvDataFrame, int *iDataIdx,
- struct sensor_value *sensorsdata)
- {
- memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 1);
- *iDataIdx += 1;
- }
- static void get_light_sensordata(char *pchRcvDataFrame, int *iDataIdx,
- struct sensor_value *sensorsdata)
- {
- #if defined(CONFIG_SENSORS_SSP_TMG399X)
- memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 10);
- *iDataIdx += 10;
- #elif defined(CONFIG_SENSORS_SSP_MAX88921)
- memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 12);
- *iDataIdx += 12;
- #else
- memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 8);
- *iDataIdx += 8;
- #endif
- }
- static void get_pressure_sensordata(char *pchRcvDataFrame, int *iDataIdx,
- struct sensor_value *sensorsdata)
- {
- s16 temperature = 0;
- memcpy(&sensorsdata->pressure[0], pchRcvDataFrame + *iDataIdx, 4);
- memcpy(&temperature, pchRcvDataFrame + *iDataIdx + 4, 2);
- sensorsdata->pressure[1] = temperature;
- *iDataIdx += 6;
- }
- static void get_gesture_sensordata(char *pchRcvDataFrame, int *iDataIdx,
- struct sensor_value *sensorsdata)
- {
- #if defined(CONFIG_SENSORS_SSP_MAX88921)
- memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 38);
- *iDataIdx += 38;
- #else//CONFIG_SENSORS_SSP_TMG399X
- memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 20);
- *iDataIdx += 20;
- #endif
- }
- static void get_proximity_sensordata(char *pchRcvDataFrame, int *iDataIdx,
- struct sensor_value *sensorsdata)
- {
- #if defined(CONFIG_SENSORS_SSP_MAX88921)
- memset(&sensorsdata->prox[0], 0, 2);
- memcpy(&sensorsdata->prox[0], pchRcvDataFrame + *iDataIdx, 1);
- memcpy(&sensorsdata->prox[1], pchRcvDataFrame + *iDataIdx + 1, 2);
- *iDataIdx += 3;
- #else
- memset(&sensorsdata->prox[0], 0, 1);
- memcpy(&sensorsdata->prox[0], pchRcvDataFrame + *iDataIdx, 2);
- //memcpy(&sensorsdata->prox[1], pchRcvDataFrame + *iDataIdx + 1, 1);
- *iDataIdx += 2;
- #endif
- }
- static void get_proximity_rawdata(char *pchRcvDataFrame, int *iDataIdx,
- struct sensor_value *sensorsdata)
- {
- #if defined(CONFIG_SENSORS_SSP_MAX88921)
- memcpy(&sensorsdata->prox[0], pchRcvDataFrame + *iDataIdx, 2);
- *iDataIdx += 2;
- #else
- memcpy(&sensorsdata->prox[0], pchRcvDataFrame + *iDataIdx, 1);
- *iDataIdx += 1;
- #endif
- }
- static void get_temp_humidity_sensordata(char *pchRcvDataFrame, int *iDataIdx,
- struct sensor_value *sensorsdata)
- {
- memset(&sensorsdata->data[2], 0, 2);
- memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 5);
- *iDataIdx += 5;
- }
- static void get_sig_motion_sensordata(char *pchRcvDataFrame, int *iDataIdx,
- struct sensor_value *sensorsdata)
- {
- memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 1);
- *iDataIdx += 1;
- }
- static void get_step_cnt_sensordata(char *pchRcvDataFrame, int *iDataIdx,
- struct sensor_value *sensorsdata)
- {
- memcpy(&sensorsdata->step_diff, pchRcvDataFrame + *iDataIdx, 4);
- *iDataIdx += 4;
- }
- static void get_shake_cam_sensordata(char *pchRcvDataFrame, int *iDataIdx,
- struct sensor_value *sensorsdata)
- {
- memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 1);
- *iDataIdx += 1;
- }
- int handle_big_data(struct ssp_data *data, char *pchRcvDataFrame, int *pDataIdx) {
- u8 bigType = 0;
- struct ssp_big *big = kzalloc(sizeof(*big), GFP_KERNEL);
- big->data = data;
- bigType = pchRcvDataFrame[(*pDataIdx)++];
- memcpy(&big->length, pchRcvDataFrame + *pDataIdx, 4);
- *pDataIdx += 4;
- memcpy(&big->addr, pchRcvDataFrame + *pDataIdx, 4);
- *pDataIdx += 4;
- if (bigType >= BIG_TYPE_MAX) {
- kfree(big);
- return FAIL;
- }
- INIT_WORK(&big->work, data->ssp_big_task[bigType]);
- queue_work(data->debug_wq, &big->work);
- return SUCCESS;
- }
- void refresh_task(struct work_struct *work) {
- struct ssp_data *data = container_of((struct delayed_work *)work,
- struct ssp_data, work_refresh);
- if(data->bSspShutdown == true) {
- pr_err("[SSP]: %s - ssp already shutdown\n", __func__);
- return;
- }
- wake_lock(&data->ssp_wake_lock);
- pr_err("[SSP]: %s\n", __func__);
- data->uResetCnt++;
- if (initialize_mcu(data) > 0) {
- sync_sensor_state(data);
- ssp_sensorhub_report_notice(data, MSG2SSP_AP_STATUS_RESET);
- if (data->uLastAPState != 0)
- ssp_send_cmd(data, data->uLastAPState, 0);
- if (data->uLastResumeState != 0)
- ssp_send_cmd(data, data->uLastResumeState, 0);
- data->uTimeOutCnt = 0;
- }
- wake_unlock(&data->ssp_wake_lock);
- }
- int queue_refresh_task(struct ssp_data *data, int delay) {
- cancel_delayed_work_sync(&data->work_refresh);
- INIT_DELAYED_WORK(&data->work_refresh, refresh_task);
- queue_delayed_work(data->debug_wq, &data->work_refresh,
- msecs_to_jiffies(delay));
- return SUCCESS;
- }
- int parse_dataframe(struct ssp_data *data, char *pchRcvDataFrame, int iLength) {
- int iDataIdx, iSensorData;
- u16 length = 0;
- struct sensor_value sensorsdata;
- struct timespec ts;
- getnstimeofday(&ts);
- for (iDataIdx = 0; iDataIdx < iLength;) {
- switch (pchRcvDataFrame[iDataIdx++]) {
- case MSG2AP_INST_BYPASS_DATA:
- iSensorData = pchRcvDataFrame[iDataIdx++];
- if ((iSensorData < 0) || (iSensorData >= SENSOR_MAX)) {
- pr_err("[SSP]: %s - Mcu data frame1 error %d\n", __func__,
- iSensorData);
- return ERROR;
- }
- data->get_sensor_data[iSensorData](pchRcvDataFrame, &iDataIdx,
- &sensorsdata);
- get_timestamp(data, pchRcvDataFrame, &iDataIdx, &sensorsdata);
- data->report_sensor_data[iSensorData](data, &sensorsdata);
- break;
- case MSG2AP_INST_DEBUG_DATA:
- iSensorData = print_mcu_debug(pchRcvDataFrame, &iDataIdx, iLength);
- if (iSensorData) {
- pr_err("[SSP]: %s - Mcu data frame3 error %d\n", __func__,
- iSensorData);
- return ERROR;
- }
- break;
- case MSG2AP_INST_LIBRARY_DATA:
- memcpy(&length, pchRcvDataFrame + iDataIdx, 2);
- iDataIdx += 2;
- ssp_sensorhub_handle_data(data, pchRcvDataFrame, iDataIdx,
- iDataIdx + length);
- iDataIdx += length;
- break;
- case MSG2AP_INST_BIG_DATA:
- handle_big_data(data, pchRcvDataFrame, &iDataIdx);
- break;
- case MSG2AP_INST_META_DATA:
- sensorsdata.meta_data.what = pchRcvDataFrame[iDataIdx++];
- sensorsdata.meta_data.sensor = pchRcvDataFrame[iDataIdx++];
- report_meta_data(data, &sensorsdata);
- break;
- case MSG2AP_INST_TIME_SYNC:
- data->bTimeSyncing = true;
- break;
- case MSG2AP_INST_RESET:
- queue_refresh_task(data, 0);
- break;
- }
- }
- if (data->bTimeSyncing)
- data->timestamp = ts.tv_sec * 1000000000ULL + ts.tv_nsec;
- 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_UNCALIB_SENSOR] =
- get_geomagnetic_uncaldata;
- data->get_sensor_data[GEOMAGNETIC_RAW] = get_geomagnetic_rawdata;
- data->get_sensor_data[GEOMAGNETIC_SENSOR] =
- get_geomagnetic_caldata;
- 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->get_sensor_data[TEMPERATURE_HUMIDITY_SENSOR] =
- get_temp_humidity_sensordata;
- data->get_sensor_data[ROTATION_VECTOR] = get_rot_sensordata;
- data->get_sensor_data[GAME_ROTATION_VECTOR] = get_rot_sensordata;
- data->get_sensor_data[STEP_DETECTOR] = get_step_det_sensordata;
- data->get_sensor_data[SIG_MOTION_SENSOR] = get_sig_motion_sensordata;
- data->get_sensor_data[GYRO_UNCALIB_SENSOR] = get_uncalib_sensordata;
- data->get_sensor_data[STEP_COUNTER] = get_step_cnt_sensordata;
- data->get_sensor_data[SHAKE_CAM] = get_shake_cam_sensordata;
- data->report_sensor_data[ACCELEROMETER_SENSOR] = report_acc_data;
- data->report_sensor_data[GYROSCOPE_SENSOR] = report_gyro_data;
- data->report_sensor_data[GEOMAGNETIC_UNCALIB_SENSOR] =
- report_mag_uncaldata;
- data->report_sensor_data[GEOMAGNETIC_RAW] = report_geomagnetic_raw_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;
- data->report_sensor_data[TEMPERATURE_HUMIDITY_SENSOR] =
- report_temp_humidity_data;
- data->report_sensor_data[ROTATION_VECTOR] = report_rot_data;
- data->report_sensor_data[GAME_ROTATION_VECTOR] = report_game_rot_data;
- data->report_sensor_data[STEP_DETECTOR] = report_step_det_data;
- data->report_sensor_data[SIG_MOTION_SENSOR] = report_sig_motion_data;
- data->report_sensor_data[GYRO_UNCALIB_SENSOR] = report_uncalib_gyro_data;
- data->report_sensor_data[STEP_COUNTER] = report_step_cnt_data;
- data->report_sensor_data[SHAKE_CAM] = report_shake_cam_data;
- data->ssp_big_task[BIG_TYPE_DUMP] = ssp_dump_task;
- data->ssp_big_task[BIG_TYPE_READ_LIB] = ssp_read_big_library_task;
- data->ssp_big_task[BIG_TYPE_VOICE_NET] = ssp_send_big_library_task;
- data->ssp_big_task[BIG_TYPE_VOICE_GRAM] = ssp_send_big_library_task;
- data->ssp_big_task[BIG_TYPE_VOICE_PCM] = ssp_pcm_dump_task;
- #ifdef CONFIG_SENSORS_SSP_SHTC1
- data->ssp_big_task[BIG_TYPE_TEMP] = ssp_temp_task;
- #endif
- }
|