ssp_debug.c 13 KB

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