ssp_firmware.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  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 SSP_FIRMWARE_REVISION 101901
  17. #if defined(CONFIG_MACH_JACTIVESKT)
  18. #define SSP_FIRMWARE_REVISION_03 14032500 /*MCU L5, 6500 fortius-skt*/
  19. #else
  20. #define SSP_FIRMWARE_REVISION_03 14122201/*MCU L5, 6500*/
  21. #endif
  22. /* Bootload mode cmd */
  23. #define BL_FW_NAME_L0 "ssp_L0.fw"
  24. #define BL_FW_NAME "ssp.fw"
  25. #define BL_FW_NAME_03 "ssp_rev03.fw"
  26. #define BL_FW_NAME_FORTIUS "ssp_fortius.fw"
  27. #define BL_UMS_FW_NAME "ssp.bin"
  28. #define BL_CRASHED_FW_NAME "ssp_crashed.fw"
  29. #define BL_UMS_FW_PATH 255
  30. #define APP_SLAVE_ADDR 0x18
  31. #define BOOTLOADER_SLAVE_ADDR 0x26
  32. /* Bootloader mode status */
  33. #define BL_WAITING_BOOTLOAD_CMD 0xc0 /* valid 7 6 bit only */
  34. #define BL_WAITING_FRAME_DATA 0x80 /* valid 7 6 bit only */
  35. #define BL_FRAME_CRC_CHECK 0x02
  36. #define BL_FRAME_CRC_FAIL 0x03
  37. #define BL_FRAME_CRC_PASS 0x04
  38. #define BL_APP_CRC_FAIL 0x40 /* valid 7 8 bit only */
  39. #define BL_BOOT_STATUS_MASK 0x3f
  40. /* Command to unlock bootloader */
  41. #define BL_UNLOCK_CMD_MSB 0xaa
  42. #define BL_UNLOCK_CMD_LSB 0xdc
  43. static int ssp_wait_for_chg(struct ssp_data *data)
  44. {
  45. int timeout_counter = 0;
  46. int count = 1E4;
  47. while ((timeout_counter++ <= count) && gpio_get_value(data->chg))
  48. udelay(20);
  49. if (timeout_counter > count) {
  50. dev_err(&data->client->dev, "ssp_wait_for_chg() timeout!\n");
  51. return -EIO;
  52. }
  53. return 0;
  54. }
  55. unsigned int get_module_rev(struct ssp_data *data)
  56. {
  57. if (data->ssp_changes == SSP_MCU_L0)
  58. return SSP_FIRMWARE_REVISION;
  59. else
  60. return SSP_FIRMWARE_REVISION_03;
  61. }
  62. static int check_bootloader(struct i2c_client *client, unsigned int uState)
  63. {
  64. u8 uVal;
  65. u8 uTemp;
  66. struct ssp_data *data = i2c_get_clientdata(client);
  67. recheck:
  68. if (i2c_master_recv(client, &uVal, 1) != 1)
  69. return -EIO;
  70. pr_debug("%s, uVal = 0x%x\n", __func__, uVal);
  71. if (uVal & 0x20) {
  72. if (i2c_master_recv(client, &uTemp, 1) != 1) {
  73. pr_err("[SSP]: %s - i2c recv fail\n", __func__);
  74. return -EIO;
  75. }
  76. if (i2c_master_recv(client, &uTemp, 1) != 1) {
  77. pr_err("[SSP]: %s - i2c recv fail\n", __func__);
  78. return -EIO;
  79. }
  80. uVal &= ~0x20;
  81. }
  82. if ((uVal & 0xF0) == BL_APP_CRC_FAIL) {
  83. pr_info("[SSP] SSP_APP_CRC_FAIL - There is no bootloader.\n");
  84. if (i2c_master_recv(client, &uVal, 1) != 1) {
  85. pr_err("[SSP]: %s - i2c recv fail\n", __func__);
  86. return -EIO;
  87. }
  88. if (uVal & 0x20) {
  89. if (i2c_master_recv(client, &uTemp, 1) != 1) {
  90. pr_err("[SSP]: %s - i2c recv fail\n", __func__);
  91. return -EIO;
  92. }
  93. if (i2c_master_recv(client, &uTemp, 1) != 1) {
  94. pr_err("[SSP]: %s - i2c recv fail\n", __func__);
  95. return -EIO;
  96. }
  97. uVal &= ~0x20;
  98. }
  99. }
  100. switch (uState) {
  101. case BL_WAITING_BOOTLOAD_CMD:
  102. case BL_WAITING_FRAME_DATA:
  103. uVal &= ~BL_BOOT_STATUS_MASK;
  104. break;
  105. case BL_FRAME_CRC_PASS:
  106. if (uVal == BL_FRAME_CRC_CHECK) {
  107. if (data->ssp_changes == SSP_MCU_L5)
  108. ssp_wait_for_chg(data);
  109. goto recheck;
  110. }
  111. break;
  112. default:
  113. return -EINVAL;
  114. }
  115. if (uVal != uState) {
  116. pr_err("[SSP]: %s - Invalid bootloader mode state\n", __func__);
  117. return -EINVAL;
  118. }
  119. return 0;
  120. }
  121. static int unlock_bootloader(struct i2c_client *client)
  122. {
  123. u8 uBuf[2];
  124. uBuf[0] = BL_UNLOCK_CMD_LSB;
  125. uBuf[1] = BL_UNLOCK_CMD_MSB;
  126. if (i2c_master_send(client, uBuf, 2) != 2) {
  127. pr_err("[SSP]: %s - i2c send failed\n", __func__);
  128. return -EIO;
  129. }
  130. return 0;
  131. }
  132. static int fw_write(struct i2c_client *client,
  133. const u8 *pData, unsigned int uFrameSize)
  134. {
  135. if (i2c_master_send(client, pData, uFrameSize) != uFrameSize) {
  136. pr_err("[SSP]: %s - i2c send failed\n", __func__);
  137. return -EIO;
  138. }
  139. return 0;
  140. }
  141. static int load_ums_fw_bootmode(struct i2c_client *client, const char *pFn)
  142. {
  143. const u8 *buff = NULL;
  144. char fw_path[BL_UMS_FW_PATH+1];
  145. unsigned int uFrameSize;
  146. unsigned int uFSize = 0, uNRead = 0;
  147. unsigned int uPos = 0;
  148. int iRet = SUCCESS;
  149. int iCheckFrameCrcError = 0;
  150. int iCheckWatingFrameDataError = 0;
  151. int count = 0;
  152. struct file *fp = NULL;
  153. mm_segment_t old_fs = get_fs();
  154. struct ssp_data *data = i2c_get_clientdata(client);
  155. pr_info("[SSP] ssp_load_ums_fw start!!!\n");
  156. old_fs = get_fs();
  157. set_fs(get_ds());
  158. snprintf(fw_path, BL_UMS_FW_PATH, "/sdcard/ssp/%s", pFn);
  159. fp = filp_open(fw_path, O_RDONLY, 0);
  160. if (IS_ERR(fp)) {
  161. iRet = ERROR;
  162. pr_err("file %s open error:%d\n", fw_path, (s32)fp);
  163. goto err_open;
  164. }
  165. uFSize = (unsigned int)fp->f_path.dentry->d_inode->i_size;
  166. pr_info("ssp_load_ums firmware size: %u\n", uFSize);
  167. buff = kzalloc((size_t)uFSize, GFP_KERNEL);
  168. if (!buff) {
  169. iRet = ERROR;
  170. pr_err("fail to alloc buffer for fw\n");
  171. goto err_alloc;
  172. }
  173. uNRead = (unsigned int)vfs_read(fp, (char __user *)buff,
  174. (unsigned int)uFSize, &fp->f_pos);
  175. if (uNRead != uFSize) {
  176. iRet = ERROR;
  177. pr_err("fail to read file %s (nread = %u)\n", fw_path, uNRead);
  178. goto err_fw_size;
  179. }
  180. /* Unlock bootloader */
  181. iRet = unlock_bootloader(client);
  182. if (iRet < 0) {
  183. pr_err("[SSP] %s - unlock_bootloader failed! %d\n",
  184. __func__, iRet);
  185. goto out;
  186. }
  187. while (uPos < uFSize) {
  188. if (data->ssp_changes == SSP_MCU_L5) {
  189. iRet = ssp_wait_for_chg(data);
  190. if (iRet < 0) {
  191. pr_err("[SSP] %s - ssp_wait_for_chg failed! %d\n",
  192. __func__, iRet);
  193. goto out;
  194. }
  195. }
  196. if (check_bootloader(client, BL_WAITING_FRAME_DATA)) {
  197. iCheckWatingFrameDataError++;
  198. if (iCheckWatingFrameDataError > 10) {
  199. iRet = ERROR;
  200. pr_err("[SSP]: %s - F/W update fail\n",
  201. __func__);
  202. goto out;
  203. } else {
  204. pr_err("[SSP]: %s - F/W data_error %d, retry\n",
  205. __func__, iCheckWatingFrameDataError);
  206. continue;
  207. }
  208. }
  209. uFrameSize = (unsigned int)((*(buff + uPos) << 8) |
  210. *(buff + uPos + 1));
  211. /* We should add 2 at frame size as the the firmware data is not
  212. * included the CRC bytes.
  213. */
  214. uFrameSize += 2;
  215. /* Write one frame to device */
  216. fw_write(client, buff + uPos, uFrameSize);
  217. if (data->ssp_changes == SSP_MCU_L5) {
  218. iRet = ssp_wait_for_chg(data);
  219. if (iRet < 0) {
  220. pr_err("[SSP] %s - ssp_wait_for_chg failed! %d\n",
  221. __func__, iRet);
  222. goto out;
  223. }
  224. }
  225. if (check_bootloader(client, BL_FRAME_CRC_PASS)) {
  226. iCheckFrameCrcError++;
  227. if (iCheckFrameCrcError > 10) {
  228. iRet = ERROR;
  229. pr_err("[SSP]: %s - F/W Update Fail. crc err\n",
  230. __func__);
  231. goto out;
  232. } else {
  233. pr_err("[SSP]: %s - F/W crc_error %d, retry\n",
  234. __func__, iCheckFrameCrcError);
  235. continue;
  236. }
  237. }
  238. uPos += uFrameSize;
  239. if (count++ == 100) {
  240. pr_info("[SSP] Updated %u bytes / %u bytes\n", uPos,
  241. uFSize);
  242. count = 0;
  243. }
  244. mdelay(1);
  245. }
  246. out:
  247. err_fw_size:
  248. kfree(buff);
  249. err_alloc:
  250. filp_close(fp, NULL);
  251. err_open:
  252. set_fs(old_fs);
  253. return iRet;
  254. }
  255. static int load_kernel_fw_bootmode(struct i2c_client *client, const char *pFn)
  256. {
  257. const struct firmware *fw = NULL;
  258. unsigned int uFrameSize;
  259. unsigned int uPos = 0;
  260. int iRet;
  261. int iCheckFrameCrcError = 0;
  262. int iCheckWatingFrameDataError = 0;
  263. int count = 0;
  264. struct ssp_data *data = i2c_get_clientdata(client);
  265. pr_info("[SSP] ssp_load_fw start!!!\n");
  266. iRet = request_firmware(&fw, pFn, &client->dev);
  267. if (iRet) {
  268. pr_err("[SSP]: %s - Unable to open firmware %s\n",
  269. __func__, pFn);
  270. return iRet;
  271. }
  272. /* Unlock bootloader */
  273. iRet = unlock_bootloader(client);
  274. if (iRet < 0) {
  275. pr_err("[SSP] %s - unlock_bootloader failed! %d\n",
  276. __func__, iRet);
  277. goto out;
  278. }
  279. while (uPos < fw->size) {
  280. if (data->ssp_changes == SSP_MCU_L5) {
  281. iRet = ssp_wait_for_chg(data);
  282. if (iRet < 0) {
  283. pr_err("[SSP] %s - ssp_wait_for_chg failed! %d\n",
  284. __func__, iRet);
  285. goto out;
  286. }
  287. }
  288. iRet = check_bootloader(client, BL_WAITING_FRAME_DATA);
  289. if (iRet) {
  290. iCheckWatingFrameDataError++;
  291. if (iCheckWatingFrameDataError > 10) {
  292. pr_err("[SSP]: %s - F/W update fail\n",
  293. __func__);
  294. goto out;
  295. } else {
  296. pr_err("[SSP]: %s - F/W data_error %d, retry\n",
  297. __func__, iCheckWatingFrameDataError);
  298. continue;
  299. }
  300. }
  301. uFrameSize = ((*(fw->data + uPos) << 8) |
  302. *(fw->data + uPos + 1));
  303. /* We should add 2 at frame size as the the firmware data is not
  304. * included the CRC bytes.
  305. */
  306. uFrameSize += 2;
  307. /* Write one frame to device */
  308. fw_write(client, fw->data + uPos, uFrameSize);
  309. if (data->ssp_changes == SSP_MCU_L5) {
  310. iRet = ssp_wait_for_chg(data);
  311. if (iRet < 0) {
  312. pr_err("[SSP] %s - ssp_wait_for_chg failed! %d\n",
  313. __func__, iRet);
  314. goto out;
  315. }
  316. }
  317. iRet = check_bootloader(client, BL_FRAME_CRC_PASS);
  318. if (iRet) {
  319. iCheckFrameCrcError++;
  320. if (iCheckFrameCrcError > 10) {
  321. pr_err("[SSP]: %s - F/W Update Fail. crc err\n",
  322. __func__);
  323. goto out;
  324. } else {
  325. pr_err("[SSP]: %s - F/W crc_error %d, retry\n",
  326. __func__, iCheckFrameCrcError);
  327. continue;
  328. }
  329. }
  330. uPos += uFrameSize;
  331. if (count++ == 100) {
  332. pr_info("[SSP] Updated %d bytes / %zd bytes\n", uPos,
  333. fw->size);
  334. count = 0;
  335. }
  336. mdelay(1);
  337. }
  338. pr_info("[SSP] Firmware download is success.(%d bytes)\n", uPos);
  339. out:
  340. release_firmware(fw);
  341. return iRet;
  342. }
  343. static void change_to_bootmode(struct ssp_data *data)
  344. {
  345. int iCnt = 0;
  346. for (iCnt = 0; iCnt < 10; iCnt++) {
  347. gpio_set_value_cansleep(data->rst, 0);
  348. udelay(10);
  349. gpio_set_value_cansleep(data->rst, 1);
  350. msleep(100);
  351. }
  352. msleep(50);
  353. }
  354. void toggle_mcu_reset(struct ssp_data *data)
  355. {
  356. u8 uBuf[2] = {0,};
  357. gpio_set_value_cansleep(data->rst, 0);
  358. udelay(10);
  359. gpio_set_value_cansleep(data->rst, 1);
  360. mdelay(50);
  361. data->client->addr = BOOTLOADER_SLAVE_ADDR;
  362. if (i2c_master_send(data->client, uBuf, 2) != 2)
  363. pr_info("[SSP]: %s - ssp_Normal Mode\n", __func__);
  364. else
  365. pr_info("[SSP]: %s - ssp_load_fw_bootmode\n", __func__);
  366. data->client->addr = APP_SLAVE_ADDR;
  367. }
  368. static int update_mcu_bin(struct ssp_data *data, int iBinType)
  369. {
  370. int iRet = SUCCESS;
  371. pr_info("[SSP] ssp_change_to_bootmode\n");
  372. change_to_bootmode(data);
  373. data->client->addr = BOOTLOADER_SLAVE_ADDR;
  374. switch (iBinType) {
  375. case KERNEL_BINARY:
  376. if (data->ssp_changes == SSP_MCU_L0)
  377. iRet = load_kernel_fw_bootmode(data->client,
  378. BL_FW_NAME_L0);
  379. else /* SSP_MCU_L5 */
  380. #if defined(CONFIG_MACH_JACTIVESKT)
  381. iRet = load_kernel_fw_bootmode(data->client,
  382. BL_FW_NAME_FORTIUS); // for fortius-kor models
  383. #else
  384. iRet = load_kernel_fw_bootmode(data->client,
  385. BL_FW_NAME_03);
  386. #endif
  387. break;
  388. case KERNEL_CRASHED_BINARY:
  389. iRet = load_kernel_fw_bootmode(data->client,
  390. BL_CRASHED_FW_NAME);
  391. break;
  392. case UMS_BINARY:
  393. iRet = load_ums_fw_bootmode(data->client,
  394. BL_UMS_FW_NAME);
  395. break;
  396. default:
  397. pr_err("[SSP] binary type error!!\n");
  398. }
  399. msleep(SSP_SW_RESET_TIME);
  400. data->client->addr = APP_SLAVE_ADDR;
  401. return iRet;
  402. }
  403. int forced_to_download_binary(struct ssp_data *data, int iBinType)
  404. {
  405. int iRet = 0;
  406. ssp_dbg("[SSP]: %s - mcu binany update!\n", __func__);
  407. ssp_enable(data, false);
  408. data->fw_dl_state = FW_DL_STATE_DOWNLOADING;
  409. pr_info("[SSP] %s, DL state = %d\n", __func__,
  410. data->fw_dl_state);
  411. iRet = update_mcu_bin(data, iBinType);
  412. if (iRet < 0) {
  413. ssp_dbg("[SSP]: %s - update_mcu_bin failed!\n", __func__);
  414. goto out;
  415. }
  416. data->fw_dl_state = FW_DL_STATE_SYNC;
  417. pr_info("[SSP] %s, DL state = %d\n", __func__, data->fw_dl_state);
  418. iRet = initialize_mcu(data);
  419. if (iRet == ERROR) {
  420. data->uResetCnt++;
  421. toggle_mcu_reset(data);
  422. msleep(SSP_SW_RESET_TIME);
  423. initialize_mcu(data);
  424. } else if (iRet < ERROR) {
  425. pr_err("[SSP]: %s - initialize_mcu failed\n", __func__);
  426. goto out;
  427. }
  428. ssp_enable(data, true);
  429. sync_sensor_state(data);
  430. #ifdef CONFIG_SENSORS_SSP_SENSORHUB
  431. ssp_sensorhub_report_notice(data, MSG2SSP_AP_STATUS_RESET);
  432. #endif
  433. data->fw_dl_state = FW_DL_STATE_DONE;
  434. pr_info("[SSP] %s, DL state = %d\n", __func__, data->fw_dl_state);
  435. iRet = SUCCESS;
  436. out:
  437. return iRet;
  438. }
  439. static unsigned int check_firmware_rev(struct ssp_data *data)
  440. {
  441. char chTxData = MSG2SSP_AP_FIRMWARE_REV;
  442. char chRxBuf[3] = {0,};
  443. unsigned int uRev = SSP_INVALID_REVISION;
  444. int iRet;
  445. iRet = ssp_i2c_read(data, &chTxData, 1, chRxBuf, 3, 0);
  446. if (iRet != SUCCESS) {
  447. pr_err("[SSP]: %s - i2c fail %d\n", __func__, iRet);
  448. } else
  449. uRev = ((unsigned int)chRxBuf[0] << 16)
  450. | ((unsigned int)chRxBuf[1] << 8) | chRxBuf[2];
  451. return uRev;
  452. }
  453. int check_fwbl(struct ssp_data *data)
  454. {
  455. int iRet;
  456. unsigned int fw_revision;
  457. pr_info("[SSP] change_rev = %d\n", data->ssp_changes);
  458. if (data->ssp_changes == SSP_MCU_L0)
  459. fw_revision = SSP_FIRMWARE_REVISION;
  460. else
  461. fw_revision = SSP_FIRMWARE_REVISION_03;
  462. data->client->addr = APP_SLAVE_ADDR;
  463. data->uCurFirmRev = check_firmware_rev(data);
  464. if (data->uCurFirmRev == SSP_INVALID_REVISION) {
  465. toggle_mcu_reset(data);
  466. msleep(SSP_SW_RESET_TIME);
  467. }
  468. if ((data->uCurFirmRev == SSP_INVALID_REVISION) \
  469. || (data->uCurFirmRev == SSP_INVALID_REVISION2)) {
  470. data->client->addr = BOOTLOADER_SLAVE_ADDR;
  471. iRet = check_bootloader(data->client, BL_WAITING_BOOTLOAD_CMD);
  472. if (iRet >= 0) {
  473. pr_info("[SSP] ssp_load_fw_bootmode\n");
  474. return FW_DL_STATE_NEED_TO_SCHEDULE;
  475. } else {
  476. pr_warn("[SSP] Firm Rev is invalid(%8u). Retry.\n",
  477. data->uCurFirmRev);
  478. data->client->addr = APP_SLAVE_ADDR;
  479. data->uCurFirmRev = get_firmware_rev(data);
  480. if (data->uCurFirmRev == SSP_INVALID_REVISION ||\
  481. data->uCurFirmRev == ERROR) {
  482. pr_err("[SSP] MCU is not working, FW download failed\n");
  483. return FW_DL_STATE_FAIL;
  484. } else if (data->uCurFirmRev != fw_revision) {
  485. pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n",
  486. data->uCurFirmRev, fw_revision);
  487. return FW_DL_STATE_NEED_TO_SCHEDULE;
  488. }
  489. pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n",
  490. data->uCurFirmRev, fw_revision);
  491. }
  492. } else {
  493. if (data->uCurFirmRev != fw_revision) {
  494. pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n",
  495. data->uCurFirmRev, fw_revision);
  496. return FW_DL_STATE_NEED_TO_SCHEDULE;
  497. }
  498. pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n",
  499. data->uCurFirmRev, fw_revision);
  500. }
  501. return FW_DL_STATE_NONE;
  502. }