ssp_debug.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. /*
  2. * Copyright (C) 2012, Samsung Electronics Co. Ltd. All Rights Reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. */
  15. #include "ssp.h"
  16. #include <linux/fs.h>
  17. #include <mach/sec_debug.h>
  18. #define SSP_DEBUG_TIMER_SEC (10 * HZ)
  19. #define LIMIT_RESET_CNT 3000000
  20. #define LIMIT_SSD_FAIL_CNT 3
  21. #define LIMIT_INSTRUCTION_FAIL_CNT 1
  22. #define LIMIT_IRQ_FAIL_CNT 2
  23. #define LIMIT_TIMEOUT_CNT 2
  24. #define DUMP_FILE_PATH "/data/log/MCU_DUMP"
  25. void ssp_dump_task(struct work_struct *work) {
  26. struct ssp_big *big;
  27. struct file *dump_file;
  28. struct ssp_msg *msg;
  29. char *buffer;
  30. char strFilePath[60];
  31. struct timeval cur_time;
  32. int iTimeTemp;
  33. mm_segment_t fs;
  34. int buf_len, packet_len, residue, iRet = 0, index = 0 ,iRetTrans=0 ,iRetWrite=0;
  35. big = container_of(work, struct ssp_big, work);
  36. pr_err("[SSP]: %s - start ssp dumping (%d)(%d)\n", __func__,big->data->bMcuDumpMode,big->data->uDumpCnt);
  37. big->data->uDumpCnt++;
  38. wake_lock(&big->data->ssp_wake_lock);
  39. fs = get_fs();
  40. set_fs(get_ds());
  41. if(big->data->bMcuDumpMode == true)
  42. {
  43. do_gettimeofday(&cur_time);
  44. iTimeTemp = (int) cur_time.tv_sec;
  45. sprintf(strFilePath, "%s%d.txt", DUMP_FILE_PATH, iTimeTemp);
  46. dump_file = filp_open(strFilePath, O_RDWR | O_CREAT | O_APPEND, 0666);
  47. if (IS_ERR(dump_file)) {
  48. pr_err("[SSP]: %s - Can't open dump file\n", __func__);
  49. set_fs(fs);
  50. iRet = PTR_ERR(dump_file);
  51. wake_unlock(&big->data->ssp_wake_lock);
  52. return;
  53. }
  54. }
  55. else
  56. dump_file = NULL;
  57. buf_len = big->length > DATA_PACKET_SIZE ? DATA_PACKET_SIZE : big->length;
  58. buffer = kzalloc(buf_len, GFP_KERNEL);
  59. residue = big->length;
  60. while (residue > 0) {
  61. packet_len = residue > DATA_PACKET_SIZE ? DATA_PACKET_SIZE : residue;
  62. msg = kzalloc(sizeof(*msg), GFP_KERNEL);
  63. msg->cmd = MSG2SSP_AP_GET_BIG_DATA;
  64. msg->length = packet_len;
  65. msg->options = AP2HUB_READ | (index++ << SSP_INDEX);
  66. msg->data = big->addr;
  67. msg->buffer = buffer;
  68. msg->free_buffer = 0;
  69. iRetTrans = ssp_spi_sync(big->data, msg, 1000);
  70. if (iRetTrans != SUCCESS) {
  71. pr_err("[SSP]: %s - Fail to receive data %d (%d)\n", __func__, iRetTrans,residue);
  72. break;
  73. }
  74. if(big->data->bMcuDumpMode == true)
  75. {
  76. iRetWrite = vfs_write(dump_file, (char __user *) buffer, packet_len,
  77. &dump_file->f_pos);
  78. if (iRetWrite < 0) {
  79. pr_err("[SSP]: %s - Can't write dump to file\n", __func__);
  80. break;
  81. }
  82. }
  83. residue -= packet_len;
  84. }
  85. if(big->data->bMcuDumpMode == true && (iRetTrans != SUCCESS || iRetWrite < 0) )
  86. {
  87. char FAILSTRING[100];
  88. sprintf(FAILSTRING,"FAIL OCCURED(%d)(%d)(%d)",iRetTrans,iRetWrite,big->length);
  89. vfs_write(dump_file, (char __user *) FAILSTRING, strlen(FAILSTRING),&dump_file->f_pos);
  90. }
  91. ssp_send_cmd(big->data, MSG2SSP_AP_MCU_DUMP_FINISH, SUCCESS);
  92. big->data->bDumping = false;
  93. if(big->data->bMcuDumpMode == true)
  94. {
  95. filp_close(dump_file, current->files);
  96. }
  97. set_fs(fs);
  98. sanity_check(big->data);
  99. wake_unlock(&big->data->ssp_wake_lock);
  100. kfree(buffer);
  101. kfree(big);
  102. pr_err("[SSP]: %s done\n", __func__);
  103. }
  104. void ssp_temp_task(struct work_struct *work) {
  105. struct ssp_big *big;
  106. struct ssp_msg *msg;
  107. char *buffer;
  108. int buf_len, packet_len, residue, iRet = 0, index = 0, i = 0, buffindex = 0;
  109. big = container_of(work, struct ssp_big, work);
  110. buf_len = big->length > DATA_PACKET_SIZE ? DATA_PACKET_SIZE : big->length;
  111. buffer = kzalloc(buf_len, GFP_KERNEL);
  112. residue = big->length;
  113. mutex_lock(&big->data->bulk_temp_read_lock);
  114. if (big->data->bulk_buffer == NULL)
  115. big->data->bulk_buffer = kzalloc(sizeof(struct shtc1_buffer),
  116. GFP_KERNEL);
  117. big->data->bulk_buffer->len = big->length / 12;
  118. while (residue > 0) {
  119. packet_len = residue > DATA_PACKET_SIZE ? DATA_PACKET_SIZE : residue;
  120. msg = kzalloc(sizeof(*msg), GFP_KERNEL);
  121. msg->cmd = MSG2SSP_AP_GET_BIG_DATA;
  122. msg->length = packet_len;
  123. msg->options = AP2HUB_READ | (index++ << SSP_INDEX);
  124. msg->data = big->addr;
  125. msg->buffer = buffer;
  126. msg->free_buffer = 0;
  127. iRet = ssp_spi_sync(big->data, msg, 1000);
  128. if (iRet != SUCCESS) {
  129. pr_err("[SSP]: %s - Fail to receive data %d\n", __func__, iRet);
  130. break;
  131. }
  132. // 12 = 1 chunk size for ks79.shin
  133. // order is thermistor Bat, thermistor PA, Temp, Humidity, Baro, Gyro
  134. // each data consist of 2bytes
  135. i = 0;
  136. while (packet_len - i >= 12) {
  137. ssp_dbg("[SSP]: %s %d %d %d %d %d %d", __func__,
  138. *((s16 *) (buffer + i + 0)), *((s16 *) (buffer + i + 2)),
  139. *((s16 *) (buffer + i + 4)), *((s16 *) (buffer + i + 6)),
  140. *((s16 *) (buffer + i + 8)), *((s16 *) (buffer +i + 10)));
  141. big->data->bulk_buffer->batt[buffindex] = *((u16 *) (buffer + i + 0));
  142. big->data->bulk_buffer->chg[buffindex] = *((u16 *) (buffer + i + 2));
  143. big->data->bulk_buffer->temp[buffindex] = *((s16 *) (buffer + i + 4));
  144. big->data->bulk_buffer->humidity[buffindex] = *((u16 *) (buffer + i + 6));
  145. big->data->bulk_buffer->baro[buffindex] = *((s16 *) (buffer + i + 8));
  146. big->data->bulk_buffer->gyro[buffindex] = *((s16 *) (buffer + i + 10));
  147. buffindex++;
  148. i += 12;
  149. }
  150. residue -= packet_len;
  151. }
  152. if (iRet == SUCCESS)
  153. report_bulk_comp_data(big->data);
  154. mutex_unlock(&big->data->bulk_temp_read_lock);
  155. kfree(buffer);
  156. kfree(big);
  157. ssp_dbg("[SSP]: %s done\n", __func__);
  158. }
  159. /*************************************************************************/
  160. /* SSP Debug timer function */
  161. /*************************************************************************/
  162. int print_mcu_debug(char *pchRcvDataFrame, int *pDataIdx,
  163. int iRcvDataFrameLength)
  164. {
  165. int iLength = pchRcvDataFrame[(*pDataIdx)++];
  166. int cur = *pDataIdx;
  167. if (iLength > iRcvDataFrameLength - *pDataIdx || iLength <= 0) {
  168. ssp_dbg("[SSP]: MSG From MCU - invalid debug length(%d/%d/%d)\n",
  169. iLength, iRcvDataFrameLength, cur);
  170. return iLength ? iLength : ERROR;
  171. }
  172. ssp_dbg("[SSP]: MSG From MCU - %s\n", &pchRcvDataFrame[*pDataIdx]);
  173. *pDataIdx += iLength;
  174. return 0;
  175. }
  176. void reset_mcu(struct ssp_data *data)
  177. {
  178. func_dbg();
  179. ssp_enable(data, false);
  180. clean_pending_list(data);
  181. toggle_mcu_reset(data);
  182. msleep(SSP_SW_RESET_TIME);
  183. ssp_enable(data, true);
  184. if (initialize_mcu(data) < 0)
  185. return;
  186. sync_sensor_state(data);
  187. #ifdef CONFIG_SENSORS_SSP_SENSORHUB
  188. ssp_sensorhub_report_notice(data, MSG2SSP_AP_STATUS_RESET);
  189. #endif
  190. if(data->uLastAPState!=0)
  191. ssp_send_cmd(data, data->uLastAPState, 0);
  192. if(data->uLastResumeState != 0)
  193. ssp_send_cmd(data, data->uLastResumeState, 0);
  194. }
  195. void sync_sensor_state(struct ssp_data *data)
  196. {
  197. unsigned char uBuf[9] = {0,};
  198. unsigned int uSensorCnt;
  199. int iRet = 0;
  200. iRet = set_hw_offset(data);
  201. if (iRet < 0) {
  202. pr_err("[SSP]: %s - set_hw_offset failed\n", __func__);
  203. }
  204. iRet = set_gyro_cal(data);
  205. if (iRet < 0) {
  206. pr_err("[SSP]: %s - set_gyro_cal failed\n", __func__);
  207. }
  208. iRet = set_accel_cal(data);
  209. if (iRet < 0) {
  210. pr_err("[SSP]: %s - set_accel_cal failed\n", __func__);
  211. }
  212. udelay(10);
  213. for (uSensorCnt = 0; uSensorCnt < SENSOR_MAX; uSensorCnt++) {
  214. if (atomic_read(&data->aSensorEnable) & (1 << uSensorCnt)) {
  215. s32 dMsDelay = get_msdelay(data->adDelayBuf[uSensorCnt]);
  216. memcpy(&uBuf[0], &dMsDelay, 4);
  217. memcpy(&uBuf[4], &data->batchLatencyBuf[uSensorCnt], 4);
  218. uBuf[8] = data->batchOptBuf[uSensorCnt];
  219. send_instruction(data, ADD_SENSOR, uSensorCnt, uBuf, 9);
  220. udelay(10);
  221. }
  222. }
  223. if (data->bProximityRawEnabled == true) {
  224. s32 dMsDelay = 20;
  225. memcpy(&uBuf[0], &dMsDelay, 4);
  226. send_instruction(data, ADD_SENSOR, PROXIMITY_RAW, uBuf, 4);
  227. }
  228. set_proximity_threshold(data, data->uProxHiThresh,data->uProxLoThresh);
  229. data->bMcuDumpMode = sec_debug_is_enabled();
  230. iRet = ssp_send_cmd(data, MSG2SSP_AP_MCU_SET_DUMPMODE,data->bMcuDumpMode);
  231. if (iRet < 0) {
  232. pr_err("[SSP]: %s - MSG2SSP_AP_MCU_SET_DUMPMODE failed\n", __func__);
  233. }
  234. }
  235. static void print_sensordata(struct ssp_data *data, unsigned int uSensor)
  236. {
  237. switch (uSensor) {
  238. case ACCELEROMETER_SENSOR:
  239. case GYROSCOPE_SENSOR:
  240. ssp_dbg("[SSP] %u : %d, %d, %d (%ums)\n", uSensor,
  241. data->buf[uSensor].x, data->buf[uSensor].y,
  242. data->buf[uSensor].z,
  243. get_msdelay(data->adDelayBuf[uSensor]));
  244. break;
  245. case GEOMAGNETIC_SENSOR:
  246. ssp_dbg("[SSP] %u : %d, %d, %d, %d (%ums)\n", uSensor,
  247. data->buf[uSensor].cal_x, data->buf[uSensor].cal_y,
  248. data->buf[uSensor].cal_y, data->buf[uSensor].accuracy,
  249. get_msdelay(data->adDelayBuf[uSensor]));
  250. break;
  251. case GEOMAGNETIC_UNCALIB_SENSOR:
  252. ssp_dbg("[SSP] %u : %d, %d, %d, %d, %d, %d (%ums)\n", uSensor,
  253. data->buf[uSensor].uncal_x, data->buf[uSensor].uncal_y,
  254. data->buf[uSensor].uncal_z, data->buf[uSensor].offset_x,
  255. data->buf[uSensor].offset_y, data->buf[uSensor].offset_z,
  256. get_msdelay(data->adDelayBuf[uSensor]));
  257. break;
  258. case PRESSURE_SENSOR:
  259. ssp_dbg("[SSP] %u : %d, %d (%ums)\n", uSensor,
  260. data->buf[uSensor].pressure[0],
  261. data->buf[uSensor].pressure[1],
  262. get_msdelay(data->adDelayBuf[uSensor]));
  263. break;
  264. case GESTURE_SENSOR:
  265. ssp_dbg("[SSP] %u : %d %d %d %d (%ums)\n", uSensor,
  266. data->buf[uSensor].data[0], data->buf[uSensor].data[1],
  267. data->buf[uSensor].data[2], data->buf[uSensor].data[3],
  268. get_msdelay(data->adDelayBuf[uSensor]));
  269. break;
  270. case TEMPERATURE_HUMIDITY_SENSOR:
  271. ssp_dbg("[SSP] %u : %d %d %d(%ums)\n", uSensor,
  272. data->buf[uSensor].data[0], data->buf[uSensor].data[1],
  273. data->buf[uSensor].data[2], get_msdelay(data->adDelayBuf[uSensor]));
  274. break;
  275. case LIGHT_SENSOR:
  276. #if defined (CONFIG_SENSORS_SSP_MAX88921)
  277. ssp_dbg("[SSP] %u : %u, %u, %u, %u, %u, %u (%ums)\n", uSensor,
  278. data->buf[uSensor].r, data->buf[uSensor].g,
  279. data->buf[uSensor].b, data->buf[uSensor].w,
  280. data->buf[uSensor].ir_cmp, data->buf[uSensor].amb_pga,
  281. get_msdelay(data->adDelayBuf[uSensor]));
  282. #else
  283. ssp_dbg("[SSP] %u : %u, %u, %u, %u (%ums)\n", uSensor,
  284. data->buf[uSensor].r, data->buf[uSensor].g,
  285. data->buf[uSensor].b, data->buf[uSensor].w,
  286. get_msdelay(data->adDelayBuf[uSensor]));
  287. #endif
  288. break;
  289. case PROXIMITY_SENSOR:
  290. ssp_dbg("[SSP] %u : %d %d(%ums)\n", uSensor,
  291. data->buf[uSensor].prox[0], data->buf[uSensor].prox[1],
  292. get_msdelay(data->adDelayBuf[uSensor]));
  293. break;
  294. case STEP_DETECTOR:
  295. ssp_dbg("[SSP] %u : %u(%ums)\n", uSensor,
  296. data->buf[uSensor].step_det,
  297. get_msdelay(data->adDelayBuf[uSensor]));
  298. break;
  299. case GAME_ROTATION_VECTOR:
  300. case ROTATION_VECTOR:
  301. ssp_dbg(" %u : %d, %d, %d, %d, %d (%ums)\n", uSensor,
  302. data->buf[uSensor].quat_a, data->buf[uSensor].quat_b,
  303. data->buf[uSensor].quat_c, data->buf[uSensor].quat_d,
  304. data->buf[uSensor].acc_rot,
  305. get_msdelay(data->adDelayBuf[uSensor]));
  306. break;
  307. case SIG_MOTION_SENSOR:
  308. ssp_dbg("[SSP] %u : %u(%ums)\n", uSensor,
  309. data->buf[uSensor].sig_motion,
  310. get_msdelay(data->adDelayBuf[uSensor]));
  311. break;
  312. case GYRO_UNCALIB_SENSOR:
  313. ssp_dbg("[SSP] %u : %d, %d, %d, %d, %d, %d (%ums)\n", uSensor,
  314. data->buf[uSensor].uncal_x, data->buf[uSensor].uncal_y,
  315. data->buf[uSensor].uncal_z, data->buf[uSensor].offset_x,
  316. data->buf[uSensor].offset_y, data->buf[uSensor].offset_z,
  317. get_msdelay(data->adDelayBuf[uSensor]));
  318. break;
  319. case STEP_COUNTER:
  320. ssp_dbg("[SSP] %u : %u(%ums)\n", uSensor,
  321. data->buf[uSensor].step_diff,
  322. get_msdelay(data->adDelayBuf[uSensor]));
  323. break;
  324. default:
  325. ssp_dbg("[SSP] Wrong sensorCnt: %u\n", uSensor);
  326. break;
  327. }
  328. }
  329. static void debug_work_func(struct work_struct *work)
  330. {
  331. unsigned int uSensorCnt;
  332. struct ssp_data *data = container_of(work, struct ssp_data, work_debug);
  333. ssp_dbg("[SSP]: %s(%u) - Sensor state: 0x%x, RC: %u, MS: %u Santi: %u Dump: %u\n",
  334. __func__, data->uIrqCnt, data->uSensorState, data->uResetCnt,
  335. data->uMissSensorCnt,data->uSanityCnt,data->uDumpCnt);
  336. if (data->fw_dl_state >= FW_DL_STATE_DOWNLOADING &&
  337. data->fw_dl_state < FW_DL_STATE_DONE) {
  338. pr_info("[SSP] : %s firmware downloading state = %d\n",
  339. __func__, data->fw_dl_state);
  340. return;
  341. } else if (data->fw_dl_state == FW_DL_STATE_FAIL) {
  342. pr_err("[SSP] : %s firmware download failed = %d\n",
  343. __func__, data->fw_dl_state);
  344. return;
  345. }
  346. if ((data->uSensorState & 0xff) == 0x0){
  347. pr_err("[SSP] : %s MCU sensor probe fail\n", __func__);
  348. return;
  349. }
  350. wake_lock(&data->ssp_wake_lock);
  351. if (data->uLastResumeState != MSG2SSP_AP_STATUS_SUSPEND) {
  352. if(sanity_check(data)>0) data->uSanityCnt++;
  353. if (set_sensor_position(data) < 0) {
  354. pr_err("[SSP]: %s :set_sensor_position delayed \n", __func__);
  355. }
  356. }
  357. for (uSensorCnt = 0; uSensorCnt < SENSOR_MAX; uSensorCnt++)
  358. if ((atomic_read(&data->aSensorEnable) & (1 << uSensorCnt))
  359. || data->batchLatencyBuf[uSensorCnt])
  360. print_sensordata(data, uSensorCnt);
  361. if (((data->uSsdFailCnt >= LIMIT_SSD_FAIL_CNT)
  362. || (data->uInstFailCnt >= LIMIT_INSTRUCTION_FAIL_CNT)
  363. || (data->uIrqFailCnt >= LIMIT_IRQ_FAIL_CNT)
  364. || ((data->uTimeOutCnt + data->uBusyCnt) > LIMIT_TIMEOUT_CNT))
  365. && (data->bSspShutdown == false)
  366. && (data->uLastResumeState != MSG2SSP_AP_STATUS_SUSPEND)) {
  367. if (data->uResetCnt < LIMIT_RESET_CNT) {
  368. pr_info("[SSP] : %s - uSsdFailCnt(%u), uInstFailCnt(%u),"\
  369. "uIrqFailCnt(%u), uTimeOutCnt(%u), uBusyCnt(%u), pending(%u)\n",
  370. __func__, data->uSsdFailCnt, data->uInstFailCnt, data->uIrqFailCnt,
  371. data->uTimeOutCnt, data->uBusyCnt, !list_empty(&data->pending_list));
  372. reset_mcu(data);
  373. data->uResetCnt++;
  374. } else {
  375. pr_info("[SSP] : %s - data->uResetCnt == LIMIT_RESET_CNT\n", __func__);
  376. ssp_enable(data, false);
  377. }
  378. data->uSsdFailCnt = 0;
  379. data->uInstFailCnt = 0;
  380. data->uTimeOutCnt = 0;
  381. data->uBusyCnt = 0;
  382. data->uIrqFailCnt = 0;
  383. }
  384. data->uIrqCnt = 0;
  385. wake_unlock(&data->ssp_wake_lock);
  386. }
  387. static void debug_timer_func(unsigned long ptr)
  388. {
  389. struct ssp_data *data = (struct ssp_data *)ptr;
  390. queue_work(data->debug_wq, &data->work_debug);
  391. mod_timer(&data->debug_timer,
  392. round_jiffies_up(jiffies + SSP_DEBUG_TIMER_SEC));
  393. }
  394. void enable_debug_timer(struct ssp_data *data)
  395. {
  396. mod_timer(&data->debug_timer,
  397. round_jiffies_up(jiffies + SSP_DEBUG_TIMER_SEC));
  398. }
  399. void disable_debug_timer(struct ssp_data *data)
  400. {
  401. del_timer_sync(&data->debug_timer);
  402. cancel_work_sync(&data->work_debug);
  403. }
  404. int initialize_debug_timer(struct ssp_data *data)
  405. {
  406. setup_timer(&data->debug_timer, debug_timer_func, (unsigned long)data);
  407. data->debug_wq = create_singlethread_workqueue("ssp_debug_wq");
  408. if (!data->debug_wq)
  409. return ERROR;
  410. INIT_WORK(&data->work_debug, debug_work_func);
  411. return SUCCESS;
  412. }