ssp_i2c.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825
  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. #define LIMIT_DELAY_CNT 200
  17. #define RECEIVEBUFFERSIZE 12
  18. #define DEBUG_SHOW_DATA 0
  19. static void clean_msg(struct ssp_msg *msg) {
  20. if (msg->free_buffer)
  21. kfree(msg->buffer);
  22. kfree(msg);
  23. }
  24. static int do_transfer(struct ssp_data *data, struct ssp_msg *msg,
  25. struct completion *done, int timeout) {
  26. int status = 0;
  27. int iDelaycnt = 0;
  28. bool msg_dead = false, ssp_down = false;
  29. bool use_no_irq = msg->length == 0;
  30. msg->dead_hook = &msg_dead;
  31. msg->dead = false;
  32. msg->done = done;
  33. mutex_lock(&data->comm_mutex);
  34. gpio_set_value_cansleep(data->ap_int, 0);
  35. while (gpio_get_value_cansleep(data->mcu_int2)) {
  36. mdelay(3);
  37. if ((ssp_down = data->bSspShutdown) || iDelaycnt++ > 500) {
  38. pr_err("[SSP]: %s exit1 - Time out!!\n", __func__);
  39. gpio_set_value_cansleep(data->ap_int, 1);
  40. status = -1;
  41. goto exit;
  42. }
  43. }
  44. status = spi_write(data->spi, msg, 9) >= 0;
  45. if (status == 0) {
  46. pr_err("[SSP]: %s spi_write fail!!\n", __func__);
  47. gpio_set_value_cansleep(data->ap_int, 1);
  48. status = -1;
  49. goto exit;
  50. }
  51. if (!use_no_irq) {
  52. mutex_lock(&data->pending_mutex);
  53. list_add_tail(&msg->list, &data->pending_list);
  54. mutex_unlock(&data->pending_mutex);
  55. }
  56. iDelaycnt = 0;
  57. gpio_set_value_cansleep(data->ap_int, 1);
  58. while (!gpio_get_value_cansleep(data->mcu_int2)) {
  59. mdelay(3);
  60. if ((ssp_down = data->bSspShutdown) || iDelaycnt++ > 500) {
  61. pr_err("[SSP]: %s exit2 - Time out!!\n", __func__);
  62. status = -2;
  63. goto exit;
  64. }
  65. }
  66. exit:
  67. mutex_unlock(&data->comm_mutex);
  68. if (ssp_down)
  69. pr_err("[SSP] : %s, ssp down", __func__);
  70. if (status == -1) {
  71. data->uTimeOutCnt += ssp_down ? 0 : 1;
  72. clean_msg(msg);
  73. return status;
  74. }
  75. if (status == 1 && done != NULL)
  76. if (wait_for_completion_timeout(done, msecs_to_jiffies(timeout)) == 0)
  77. status = -2;
  78. mutex_lock(&data->pending_mutex);
  79. if (!msg_dead) {
  80. msg->done = NULL;
  81. msg->dead_hook = NULL;
  82. if (status != 1)
  83. msg->dead = true;
  84. if (status == -2)
  85. data->uTimeOutCnt += ssp_down ? 0 : 1;
  86. }
  87. mutex_unlock(&data->pending_mutex);
  88. if (use_no_irq)
  89. clean_msg(msg);
  90. return status;
  91. }
  92. int ssp_spi_async(struct ssp_data *data, struct ssp_msg *msg) {
  93. int status = 0;
  94. status = do_transfer(data, msg, NULL, 0);
  95. return status;
  96. }
  97. int ssp_spi_sync(struct ssp_data *data, struct ssp_msg *msg, int timeout) {
  98. DECLARE_COMPLETION_ONSTACK(done);
  99. int status = 0;
  100. if (msg->length == 0) {
  101. pr_err("[SSP]: %s length must not be 0\n", __func__);
  102. clean_msg(msg);
  103. return status;
  104. }
  105. status = do_transfer(data, msg, &done, timeout);
  106. return status;
  107. }
  108. int select_irq_msg(struct ssp_data *data) {
  109. struct ssp_msg *msg, *n;
  110. bool found = false;
  111. u16 chLength = 0, msg_options = 0;
  112. u8 msg_type = 0;
  113. int iRet = 0;
  114. char* buffer;
  115. char chTempBuf[4] = { -1 };
  116. iRet = spi_read(data->spi, chTempBuf, sizeof(chTempBuf));
  117. if (iRet < 0) {
  118. pr_err("[SSP]: %s spi_read fail!!\n", __func__);
  119. return ERROR;
  120. }
  121. memcpy(&msg_options, &chTempBuf[0], 2);
  122. msg_type = msg_options & SSP_SPI_MASK;
  123. memcpy(&chLength, &chTempBuf[2], 2);
  124. switch (msg_type) {
  125. case AP2HUB_READ:
  126. case AP2HUB_WRITE:
  127. mutex_lock(&data->pending_mutex);
  128. if (!list_empty(&data->pending_list)) {
  129. list_for_each_entry_safe(msg, n, &data->pending_list, list)
  130. {
  131. if (msg->options == msg_options) {
  132. list_del(&msg->list);
  133. found = true;
  134. break;
  135. }
  136. }
  137. if (!found) {
  138. pr_err("[SSP]: %s %d - Not match error\n", __func__, msg_options);
  139. goto exit;
  140. }
  141. if (msg->dead && !msg->free_buffer) {
  142. msg->buffer = (char*) kzalloc(msg->length, GFP_KERNEL);
  143. msg->free_buffer = 1;
  144. } // For dead msg, make a temporary buffer to read.
  145. if (msg_type == AP2HUB_READ)
  146. iRet = spi_read(data->spi, msg->buffer, msg->length);
  147. if (msg_type == AP2HUB_WRITE) {
  148. iRet = spi_write(data->spi, msg->buffer, msg->length);
  149. if (msg_options & AP2HUB_RETURN) {
  150. msg->options = AP2HUB_READ | AP2HUB_RETURN;
  151. msg->length = 1;
  152. list_add_tail(&msg->list, &data->pending_list);
  153. goto exit;
  154. }
  155. }
  156. if (msg->done != NULL && !completion_done(msg->done))
  157. complete(msg->done);
  158. if (msg->dead_hook != NULL)
  159. *(msg->dead_hook) = true;
  160. clean_msg(msg);
  161. } else
  162. pr_err("[SSP]List empty error(%d)\n", msg_type);
  163. exit:
  164. mutex_unlock(&data->pending_mutex);
  165. break;
  166. case HUB2AP_WRITE:
  167. buffer = (char*) kzalloc(chLength, GFP_KERNEL);
  168. if (buffer == NULL) {
  169. pr_err("[SSP] %s, failed to alloc memory for buffer\n", __func__);
  170. iRet = -ENOMEM;
  171. break;
  172. }
  173. iRet = spi_read(data->spi, buffer, chLength);
  174. parse_dataframe(data, buffer, chLength);
  175. kfree(buffer);
  176. break;
  177. default:
  178. pr_err("[SSP]No type error(%d)\n", msg_type);
  179. break;
  180. }
  181. if (iRet < 0) {
  182. pr_err("[SSP]: %s - MSG2SSP_SSD error %d\n", __func__, iRet);
  183. return ERROR;
  184. }
  185. return SUCCESS;
  186. }
  187. void clean_pending_list(struct ssp_data *data) {
  188. struct ssp_msg *msg, *n;
  189. mutex_lock(&data->pending_mutex);
  190. list_for_each_entry_safe(msg, n, &data->pending_list, list)
  191. {
  192. list_del(&msg->list);
  193. if (msg->done != NULL && !completion_done(msg->done))
  194. complete(msg->done);
  195. if (msg->dead_hook != NULL)
  196. *(msg->dead_hook) = true;
  197. clean_msg(msg);
  198. }
  199. mutex_unlock(&data->pending_mutex);
  200. }
  201. int ssp_send_cmd(struct ssp_data *data, char command, int arg)
  202. {
  203. int iRet = 0;
  204. struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
  205. msg->cmd = command;
  206. msg->length = 0;
  207. msg->options = AP2HUB_WRITE;
  208. msg->data = arg;
  209. msg->free_buffer = 0;
  210. iRet = ssp_spi_async(data, msg);
  211. if (iRet != SUCCESS) {
  212. pr_err("[SSP]: %s - command 0x%x failed %d\n",
  213. __func__, command, iRet);
  214. return ERROR;
  215. }
  216. ssp_dbg("[SSP]: %s - command 0x%x %d\n", __func__, command, arg);
  217. return SUCCESS;
  218. }
  219. int send_instruction(struct ssp_data *data, u8 uInst,
  220. u8 uSensorType, u8 *uSendBuf, u8 uLength)
  221. {
  222. char command;
  223. int iRet = 0;
  224. struct ssp_msg *msg;
  225. if (data->fw_dl_state == FW_DL_STATE_DOWNLOADING) {
  226. pr_err("[SSP] %s - Skip Inst! DL state = %d\n",
  227. __func__, data->fw_dl_state);
  228. return SUCCESS;
  229. } else if ((!(data->uSensorState & (1 << uSensorType)))
  230. && (uInst <= CHANGE_DELAY)) {
  231. pr_err("[SSP]: %s - Bypass Inst Skip! - %u\n",
  232. __func__, uSensorType);
  233. return FAIL;
  234. }
  235. switch (uInst) {
  236. case REMOVE_SENSOR:
  237. command = MSG2SSP_INST_BYPASS_SENSOR_REMOVE;
  238. break;
  239. case ADD_SENSOR:
  240. command = MSG2SSP_INST_BYPASS_SENSOR_ADD;
  241. break;
  242. case CHANGE_DELAY:
  243. command = MSG2SSP_INST_CHANGE_DELAY;
  244. break;
  245. case GO_SLEEP:
  246. command = MSG2SSP_AP_STATUS_SLEEP;
  247. data->uLastAPState = MSG2SSP_AP_STATUS_SLEEP;
  248. break;
  249. case REMOVE_LIBRARY:
  250. command = MSG2SSP_INST_LIBRARY_REMOVE;
  251. break;
  252. case ADD_LIBRARY:
  253. command = MSG2SSP_INST_LIBRARY_ADD;
  254. break;
  255. default:
  256. command = uInst;
  257. break;
  258. }
  259. msg = kzalloc(sizeof(*msg), GFP_KERNEL);
  260. if (msg == NULL) {
  261. pr_err("[SSP] %s, failed to alloc memory for ssp_msg\n", __func__);
  262. iRet = -ENOMEM;
  263. return iRet;
  264. }
  265. if(uSensorType == GEOMAGNETIC_SENSOR)
  266. uLength += 1;
  267. msg->cmd = command;
  268. msg->length = uLength + 1;
  269. msg->options = AP2HUB_WRITE;
  270. msg->buffer = (char*) kzalloc(uLength + 1, GFP_KERNEL);
  271. msg->free_buffer = 1;
  272. msg->buffer[0] = uSensorType;
  273. memcpy(&msg->buffer[1], uSendBuf, uLength);
  274. if(uSensorType == GEOMAGNETIC_SENSOR) {
  275. msg->buffer[10] = MAG_LOG_MODE;
  276. }
  277. ssp_dbg("[SSP]: %s - Inst = 0x%x, Sensor Type = 0x%x, data = %u\n",
  278. __func__, command, uSensorType, msg->buffer[1]);
  279. iRet = ssp_spi_async(data, msg);
  280. if (iRet != SUCCESS) {
  281. pr_err("[SSP]: %s - Instruction CMD Fail %d\n", __func__, iRet);
  282. return ERROR;
  283. }
  284. return iRet;
  285. }
  286. int send_instruction_sync(struct ssp_data *data, u8 uInst,
  287. u8 uSensorType, u8 *uSendBuf, u8 uLength)
  288. {
  289. char command;
  290. int iRet = 0;
  291. char buffer[10] = { 0, };
  292. struct ssp_msg *msg;
  293. if (data->fw_dl_state == FW_DL_STATE_DOWNLOADING) {
  294. pr_err("[SSP] %s - Skip Inst! DL state = %d\n",
  295. __func__, data->fw_dl_state);
  296. return SUCCESS;
  297. } else if ((!(data->uSensorState & (1 << uSensorType)))
  298. && (uInst <= CHANGE_DELAY)) {
  299. pr_err("[SSP]: %s - Bypass Inst Skip! - %u\n",
  300. __func__, uSensorType);
  301. return FAIL;
  302. }
  303. switch (uInst) {
  304. case REMOVE_SENSOR:
  305. command = MSG2SSP_INST_BYPASS_SENSOR_REMOVE;
  306. break;
  307. case ADD_SENSOR:
  308. command = MSG2SSP_INST_BYPASS_SENSOR_ADD;
  309. break;
  310. case CHANGE_DELAY:
  311. command = MSG2SSP_INST_CHANGE_DELAY;
  312. break;
  313. case GO_SLEEP:
  314. command = MSG2SSP_AP_STATUS_SLEEP;
  315. data->uLastAPState = MSG2SSP_AP_STATUS_SLEEP;
  316. break;
  317. case REMOVE_LIBRARY:
  318. command = MSG2SSP_INST_LIBRARY_REMOVE;
  319. break;
  320. case ADD_LIBRARY:
  321. command = MSG2SSP_INST_LIBRARY_ADD;
  322. break;
  323. default:
  324. command = uInst;
  325. break;
  326. }
  327. msg = kzalloc(sizeof(*msg), GFP_KERNEL);
  328. msg->cmd = command;
  329. msg->length = uLength + 1;
  330. msg->options = AP2HUB_WRITE | AP2HUB_RETURN;
  331. msg->buffer = buffer;
  332. msg->free_buffer = 0;
  333. msg->buffer[0] = uSensorType;
  334. memcpy(&msg->buffer[1], uSendBuf, uLength);
  335. ssp_dbg("[SSP]: %s - Inst Sync = 0x%x, Sensor Type = %u, data = %u\n",
  336. __func__, command, uSensorType, msg->buffer[0]);
  337. iRet = ssp_spi_sync(data, msg, 1000);
  338. if (iRet != SUCCESS) {
  339. pr_err("[SSP]: %s - Instruction CMD Fail %d\n", __func__, iRet);
  340. return ERROR;
  341. }
  342. return buffer[0];
  343. }
  344. int flush(struct ssp_data *data, u8 uSensorType) {
  345. int iRet = 0;
  346. char buffer = 0;
  347. struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
  348. msg->cmd = MSG2SSP_AP_MCU_BATCH_FLUSH;
  349. msg->length = 1;
  350. msg->options = AP2HUB_READ;
  351. msg->data = uSensorType;
  352. msg->buffer = &buffer;
  353. msg->free_buffer = 0;
  354. iRet = ssp_spi_sync(data, msg, 1000);
  355. if (iRet != SUCCESS) {
  356. pr_err("[SSP]: %s - fail %d\n", __func__, iRet);
  357. return ERROR;
  358. }
  359. ssp_dbg("[SSP]: %s Sensor Type = 0x%x, data = %u\n", __func__, uSensorType,
  360. buffer);
  361. return buffer ? 0 : -1;
  362. }
  363. int get_batch_count(struct ssp_data *data, u8 uSensorType) {
  364. int iRet = 0;
  365. s32 result = 0;
  366. char buffer[4] = { 0, };
  367. struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
  368. msg->cmd = MSG2SSP_AP_MCU_BATCH_COUNT;
  369. msg->length = 4;
  370. msg->options = AP2HUB_READ;
  371. msg->data = uSensorType;
  372. msg->buffer = buffer;
  373. msg->free_buffer = 0;
  374. iRet = ssp_spi_sync(data, msg, 1000);
  375. if (iRet != SUCCESS) {
  376. pr_err("[SSP]: %s - fail %d\n", __func__, iRet);
  377. return ERROR;
  378. }
  379. memcpy(&result, buffer, 4);
  380. ssp_dbg("[SSP]: %s Sensor Type = 0x%x, data = %u\n", __func__, uSensorType,
  381. result);
  382. return result;
  383. }
  384. int get_chipid(struct ssp_data *data)
  385. {
  386. int iRet, iReties = 0;
  387. char buffer = 0;
  388. struct ssp_msg *msg;
  389. retries:
  390. msg = kzalloc(sizeof(*msg), GFP_KERNEL);
  391. if (msg == NULL) {
  392. pr_err("[SSP] %s, failed to alloc memory for ssp_msg\n", __func__);
  393. return -ENOMEM;
  394. }
  395. msg->cmd = MSG2SSP_AP_WHOAMI;
  396. msg->length = 1;
  397. msg->options = AP2HUB_READ;
  398. msg->buffer = &buffer;
  399. msg->free_buffer = 0;
  400. iRet = ssp_spi_sync(data, msg, 1000);
  401. if (buffer != DEVICE_ID && iReties++ < 2) {
  402. mdelay(5);
  403. pr_err("[SSP] %s - get chip ID retry\n", __func__);
  404. goto retries;
  405. }
  406. if (iRet == SUCCESS)
  407. return buffer;
  408. pr_err("[SSP] %s - get chip ID failed %d\n", __func__, iRet);
  409. return ERROR;
  410. }
  411. int set_sensor_position(struct ssp_data *data)
  412. {
  413. int iRet = 0;
  414. struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
  415. msg->cmd = MSG2SSP_AP_SENSOR_FORMATION;
  416. msg->length = 3;
  417. msg->options = AP2HUB_WRITE;
  418. msg->buffer = (char*) kzalloc(3, GFP_KERNEL);
  419. msg->free_buffer = 1;
  420. msg->buffer[0] = data->accel_position;
  421. msg->buffer[1] = data->accel_position;
  422. msg->buffer[2] = data->mag_position;
  423. pr_info("[SSP] Sensor Posision A : %u, G : %u, M: %u\n",
  424. data->accel_position, data->accel_position, data->mag_position);
  425. iRet = ssp_spi_async(data, msg);
  426. if (iRet != SUCCESS) {
  427. pr_err("[SSP]: %s - i2c fail %d\n", __func__, iRet);
  428. iRet = ERROR;
  429. }
  430. return iRet;
  431. }
  432. void set_proximity_threshold(struct ssp_data *data,
  433. unsigned int uData1, unsigned int uData2)
  434. {
  435. int iRet = 0;
  436. struct ssp_msg *msg;
  437. if (!(data->uSensorState & (1<<PROXIMITY_SENSOR))) {
  438. pr_info("[SSP]: %s - Skip this function!!!"\
  439. ", proximity sensor is not connected(0x%x)\n",
  440. __func__, data->uSensorState);
  441. return;
  442. }
  443. msg= kzalloc(sizeof(*msg), GFP_KERNEL);
  444. msg->cmd = MSG2SSP_AP_SENSOR_PROXTHRESHOLD;
  445. #if defined(CONFIG_SENSORS_SSP_MAX88921)
  446. msg->length = 4;
  447. #else
  448. msg->length = 2;
  449. #endif
  450. msg->options = AP2HUB_WRITE;
  451. msg->buffer = (char*) kzalloc(4, GFP_KERNEL);
  452. msg->free_buffer = 1;
  453. pr_err("[SSP]: %s - SENSOR_PROXTHRESHOL",__func__);
  454. #if defined(CONFIG_SENSORS_SSP_MAX88921)
  455. msg->buffer[0] = ((char) (uData1 >> 8) & 0x07);
  456. msg->buffer[1] = (char) uData1;
  457. msg->buffer[2] = ((char) (uData2 >> 8) & 0x07);
  458. msg->buffer[3] = (char) uData2;
  459. #else
  460. if (uData1 < uData2) {
  461. pr_info("[SSP] %s - invalid threshold (%u, %u)\n",
  462. __func__, uData1, uData2);
  463. uData1 = DEFUALT_HIGH_THRESHOLD;
  464. uData2 = DEFUALT_LOW_THRESHOLD;
  465. }
  466. msg->buffer[0] = (char)uData1;
  467. msg->buffer[1] = (char)uData2;
  468. #endif
  469. iRet = ssp_spi_async(data, msg);
  470. if (iRet != SUCCESS) {
  471. pr_err("[SSP]: %s - SENSOR_PROXTHRESHOLD CMD fail %d\n",
  472. __func__, iRet);
  473. return;
  474. }
  475. pr_info("[SSP]: Proximity Threshold - %u, %u\n", uData1, uData2);
  476. }
  477. void set_proximity_barcode_enable(struct ssp_data *data, bool bEnable)
  478. {
  479. int iRet = 0;
  480. struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
  481. msg->cmd = MSG2SSP_AP_SENSOR_BARCODE_EMUL;
  482. msg->length = 1;
  483. msg->options = AP2HUB_WRITE;
  484. msg->buffer = (char*) kzalloc(1, GFP_KERNEL);
  485. msg->free_buffer = 1;
  486. data->bBarcodeEnabled = bEnable;
  487. msg->buffer[0] = bEnable;
  488. iRet = ssp_spi_async(data, msg);
  489. if (iRet != SUCCESS) {
  490. pr_err("[SSP]: %s - SENSOR_BARCODE_EMUL CMD fail %d\n",
  491. __func__, iRet);
  492. return;
  493. }
  494. pr_info("[SSP] Proximity Barcode En : %u\n", bEnable);
  495. }
  496. #ifdef CONFIG_DUAL_LCD
  497. void set_magnetic_cal_with_folder_state(struct ssp_data *data, bool bEnable)
  498. {
  499. int iRet = 0;
  500. struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
  501. msg->cmd = MSG2SSP_AP_MCU_SET_MAGNETIC_CAL;
  502. msg->length = 1;
  503. msg->options = AP2HUB_WRITE;
  504. msg->buffer = (char*) kzalloc(1, GFP_KERNEL);
  505. msg->free_buffer = 1;
  506. /*if 1: close, 0: open*/
  507. msg->buffer[0] = bEnable;
  508. iRet = ssp_spi_async(data, msg);
  509. if (iRet != SUCCESS) {
  510. pr_err("[SSP]: %s - SENSOR_MAGNETIC_CAL fail %d\n",
  511. __func__, iRet);
  512. return;
  513. }
  514. pr_info("[SSP] magneticsensor calibration with folder state En : %u\n", bEnable);
  515. }
  516. #endif
  517. void set_gesture_current(struct ssp_data *data, unsigned char uData1)
  518. {
  519. int iRet = 0;
  520. struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
  521. msg->cmd = MSG2SSP_AP_SENSOR_GESTURE_CURRENT;
  522. msg->length = 1;
  523. msg->options = AP2HUB_WRITE;
  524. msg->buffer = (char*) kzalloc(1, GFP_KERNEL);
  525. msg->free_buffer = 1;
  526. msg->buffer[0] = uData1;
  527. iRet = ssp_spi_async(data, msg);
  528. if (iRet != SUCCESS) {
  529. pr_err("[SSP]: %s - SENSOR_GESTURE_CURRENT CMD fail %d\n", __func__,
  530. iRet);
  531. return;
  532. }
  533. pr_info("[SSP]: Gesture Current Setting - %u\n", uData1);
  534. }
  535. unsigned int get_sensor_scanning_info(struct ssp_data *data) {
  536. int iRet = 0, z = 0;
  537. u32 result = 0;
  538. char bin[SENSOR_MAX + 1];
  539. struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
  540. if (msg == NULL) {
  541. pr_err("[SSP] %s, failed to alloc memory for ssp_msg\n", __func__);
  542. return -ENOMEM;
  543. }
  544. msg->cmd = MSG2SSP_AP_SENSOR_SCANNING;
  545. msg->length = 4;
  546. msg->options = AP2HUB_READ;
  547. msg->buffer = (char*) &result;
  548. msg->free_buffer = 0;
  549. iRet = ssp_spi_sync(data, msg, 1000);
  550. if (iRet != SUCCESS)
  551. pr_err("[SSP]: %s - i2c fail %d\n", __func__, iRet);
  552. bin[SENSOR_MAX] = '\0';
  553. for (z = 0; z < SENSOR_MAX; z++)
  554. bin[SENSOR_MAX - 1 - z] = (result & (1 << z)) ? '1' : '0';
  555. pr_err("[SSP]: state: %s\n", bin);
  556. return result;
  557. }
  558. unsigned int get_firmware_rev(struct ssp_data *data) {
  559. int iRet;
  560. u32 result = SSP_INVALID_REVISION;
  561. struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
  562. msg->cmd = MSG2SSP_AP_FIRMWARE_REV;
  563. msg->length = 4;
  564. msg->options = AP2HUB_READ;
  565. msg->buffer = (char*) &result;
  566. msg->free_buffer = 0;
  567. iRet = ssp_spi_sync(data, msg, 1000);
  568. if (iRet != SUCCESS)
  569. pr_err("[SSP]: %s - transfer fail %d\n", __func__, iRet);
  570. return result;
  571. }
  572. int get_fuserom_data(struct ssp_data *data)
  573. {
  574. int iRet = 0;
  575. char buffer[3] = { 0, };
  576. struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
  577. msg->cmd = MSG2SSP_AP_FUSEROM;
  578. msg->length = 3;
  579. msg->options = AP2HUB_READ;
  580. msg->buffer = buffer;
  581. msg->free_buffer = 0;
  582. iRet = ssp_spi_sync(data, msg, 1000);
  583. if (iRet) {
  584. data->uFuseRomData[0] = buffer[0];
  585. data->uFuseRomData[1] = buffer[1];
  586. data->uFuseRomData[2] = buffer[2];
  587. } else {
  588. data->uFuseRomData[0] = 0;
  589. data->uFuseRomData[1] = 0;
  590. data->uFuseRomData[2] = 0;
  591. return FAIL;
  592. }
  593. pr_info("[SSP] FUSE ROM Data %d , %d, %d\n", data->uFuseRomData[0],
  594. data->uFuseRomData[1], data->uFuseRomData[2]);
  595. return SUCCESS;
  596. }
  597. int set_big_data_start(struct ssp_data *data, u8 type, u32 length) {
  598. int iRet = 0;
  599. struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
  600. msg->cmd = MSG2SSP_AP_START_BIG_DATA;
  601. msg->length = 5;
  602. msg->options = AP2HUB_WRITE;
  603. msg->buffer = (char*) kzalloc(5, GFP_KERNEL);
  604. msg->free_buffer = 1;
  605. msg->buffer[0] = type;
  606. memcpy(&msg->buffer[1], &length, 4);
  607. iRet = ssp_spi_async(data, msg);
  608. if (iRet != SUCCESS) {
  609. pr_err("[SSP]: %s - i2c fail %d\n", __func__, iRet);
  610. iRet = ERROR;
  611. }
  612. return iRet;
  613. }
  614. int set_time(struct ssp_data *data) {
  615. int iRet;
  616. struct ssp_msg *msg;
  617. struct timespec ts;
  618. struct rtc_time tm;
  619. getnstimeofday(&ts);
  620. rtc_time_to_tm(ts.tv_sec, &tm);
  621. pr_info("[SSP]: %s %d-%02d-%02d %02d:%02d:%02d.%09lu UTC\n", __func__,
  622. tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min,
  623. tm.tm_sec, ts.tv_nsec);
  624. msg = kzalloc(sizeof(*msg), GFP_KERNEL);
  625. msg->cmd = MSG2SSP_AP_MCU_SET_TIME;
  626. msg->length = 12;
  627. msg->options = AP2HUB_WRITE;
  628. msg->buffer = (char*) kzalloc(12, GFP_KERNEL);
  629. msg->free_buffer = 1;
  630. msg->buffer[0] = tm.tm_hour;
  631. msg->buffer[1] = tm.tm_min;
  632. msg->buffer[2] = tm.tm_sec;
  633. msg->buffer[3] = tm.tm_hour > 11 ? 64 : 0;
  634. msg->buffer[4] = tm.tm_wday;
  635. msg->buffer[5] = tm.tm_mon + 1;
  636. msg->buffer[6] = tm.tm_mday;
  637. msg->buffer[7] = tm.tm_year % 100;
  638. memcpy(&msg->buffer[8], &ts.tv_nsec, 4);
  639. iRet = ssp_spi_async(data, msg);
  640. if (iRet != SUCCESS) {
  641. pr_err("[SSP]: %s - i2c fail %d\n", __func__, iRet);
  642. iRet = ERROR;
  643. }
  644. return iRet;
  645. }
  646. int get_time(struct ssp_data *data) {
  647. int iRet;
  648. char buffer[12] = { 0, };
  649. struct ssp_msg *msg;
  650. struct timespec ts;
  651. struct rtc_time tm;
  652. getnstimeofday(&ts);
  653. rtc_time_to_tm(ts.tv_sec, &tm);
  654. pr_info("[SSP]: %s ap %d-%02d-%02d %02d:%02d:%02d.%09lu UTC\n", __func__,
  655. tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min,
  656. tm.tm_sec, ts.tv_nsec);
  657. msg = kzalloc(sizeof(*msg), GFP_KERNEL);
  658. msg->cmd = MSG2SSP_AP_MCU_GET_TIME;
  659. msg->length = 12;
  660. msg->options = AP2HUB_READ;
  661. msg->buffer = buffer;
  662. msg->free_buffer = 0;
  663. iRet = ssp_spi_sync(data, msg, 1000);
  664. if (iRet != SUCCESS) {
  665. pr_err("[SSP]: %s - i2c failed %d\n", __func__, iRet);
  666. return 0;
  667. }
  668. tm.tm_hour = buffer[0];
  669. tm.tm_min = buffer[1];
  670. tm.tm_sec = buffer[2];
  671. tm.tm_mon = msg->buffer[5] - 1;
  672. tm.tm_mday = buffer[6];
  673. tm.tm_year = buffer[7] + 100;
  674. rtc_tm_to_time(&tm, &ts.tv_sec);
  675. memcpy(&ts.tv_nsec, &msg->buffer[8], 4);
  676. rtc_time_to_tm(ts.tv_sec, &tm);
  677. pr_info("[SSP]: %s mcu %d-%02d-%02d %02d:%02d:%02d.%09lu UTC\n", __func__,
  678. tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min,
  679. tm.tm_sec, ts.tv_nsec);
  680. return iRet;
  681. }