spi-dev.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041
  1. #include <linux/spi/spi.h>
  2. #include <linux/init.h>
  3. #include <linux/module.h>
  4. #include <linux/types.h>
  5. #include <linux/device.h>
  6. #include <linux/delay.h>
  7. #include <mt_spi.h>
  8. #include <linux/dma-mapping.h>
  9. #include <linux/sched.h>
  10. #include "mt_spi_hal.h"
  11. #include <linux/kthread.h>
  12. #ifdef CONFIG_TRUSTONIC_TEE_SUPPORT
  13. #define SPI_TRUSTONIC_TEE_SUPPORT
  14. #endif
  15. #ifdef SPI_TRUSTONIC_TEE_SUPPORT
  16. #include <mobicore_driver_api.h>
  17. #include <tlspi_Api.h>
  18. #endif
  19. /*#define SPIDEV_LOG(fmt, args...) printk("[SPI-UT]: [%s]:[%d]" fmt, __func__, __LINE__, ##args)*/
  20. /*#define SPIDEV_MSG(fmt, args...) printk(KERN_ERR fmt, ##args )*/
  21. #define SPIDEV_LOG(fmt, args...) pr_debug("[SPI-UT]: [%s]:[%d]" fmt, __func__, __LINE__, ##args)
  22. #define SPIDEV_MSG(fmt, args...) pr_debug(fmt, ##args)
  23. #define SPI_STRESS_MAX 1
  24. DECLARE_COMPLETION(mt_spi_done);
  25. static u32 stress_err;
  26. static struct task_struct *spi_concur1;
  27. static struct task_struct *spi_concur2;
  28. static struct task_struct *spi_concur3;
  29. static struct task_struct *spi_concur4;
  30. static struct spi_transfer stress_xfer[SPI_STRESS_MAX];
  31. static struct spi_transfer stress_xfer_con[SPI_STRESS_MAX];
  32. static struct spi_message stress_msg[SPI_STRESS_MAX];
  33. /*static struct spi_device *spi_test;*/
  34. static int spi_setup_xfer(struct device *dev, struct spi_transfer *xfer, u32 len, u32 flag)
  35. {
  36. u32 tx_buffer = 0x12345678;
  37. u32 cnt, i;
  38. #if 0
  39. u8 *p;
  40. #endif
  41. #define SPI_CROSS_ALIGN_OFFSET 1008
  42. xfer->len = len;
  43. xfer->tx_buf = kzalloc(len, GFP_KERNEL);
  44. xfer->rx_buf = kzalloc(len, GFP_KERNEL);
  45. if ((xfer->tx_buf == NULL) || (xfer->rx_buf == NULL))
  46. return -1;
  47. cnt = (len % 4) ? (len / 4 + 1) : (len / 4);
  48. if (flag == 0) {
  49. for (i = 0; i < cnt; i++)
  50. *((u32 *) xfer->tx_buf + i) = tx_buffer;
  51. } else if (flag == 1) {
  52. for (i = 0; i < cnt; i++)
  53. *((u32 *) xfer->tx_buf + i) = tx_buffer + i;
  54. } else if (flag == 2) { /*cross 1 K boundary*/
  55. if (len < 2048)
  56. return -EINVAL;
  57. for (i = 0; i < cnt; i++)
  58. *((u32 *) xfer->tx_buf + i) = tx_buffer + i;
  59. xfer->tx_dma = dma_map_single(dev, (void *)xfer->tx_buf, xfer->len, DMA_TO_DEVICE);
  60. if (dma_mapping_error(dev, xfer->tx_dma)) {
  61. SPIDEV_LOG("dma mapping tx_buf error.\n");
  62. return -ENOMEM;
  63. }
  64. xfer->rx_dma = dma_map_single(dev, (void *)xfer->rx_buf, xfer->len, DMA_TO_DEVICE);
  65. if (dma_mapping_error(dev, xfer->rx_dma)) {
  66. SPIDEV_LOG("dma mapping rx_buf error.\n");
  67. return -ENOMEM;
  68. }
  69. #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
  70. SPIDEV_LOG("Transfer addr:Tx:0x%llx, Rx:0x%llx, before\n", xfer->tx_dma, xfer->rx_dma);
  71. #else
  72. SPIDEV_LOG("Transfer addr:Tx:0x%x, Rx:0x%x, before\n", xfer->tx_dma, xfer->rx_dma);
  73. #endif
  74. xfer->len = 32;
  75. #if 0
  76. p = (u8 *) xfer->tx_dma;
  77. xfer->tx_dma = (u32) (p + SPI_CROSS_ALIGN_OFFSET);
  78. p = (u8 *) xfer->rx_dma;
  79. xfer->rx_dma = (u32) (p + SPI_CROSS_ALIGN_OFFSET);
  80. p = (u8 *) xfer->tx_buf;
  81. xfer->tx_buf = (u32 *) (p + SPI_CROSS_ALIGN_OFFSET);
  82. p = (u8 *) xfer->rx_buf;
  83. xfer->rx_buf = (u32 *) (p + SPI_CROSS_ALIGN_OFFSET);
  84. #else
  85. xfer->tx_dma += SPI_CROSS_ALIGN_OFFSET;
  86. xfer->rx_dma += SPI_CROSS_ALIGN_OFFSET;
  87. xfer->tx_buf += SPI_CROSS_ALIGN_OFFSET;
  88. xfer->rx_buf += SPI_CROSS_ALIGN_OFFSET;
  89. #endif
  90. #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
  91. SPIDEV_LOG("Transfer addr:Tx:0x%llx, Rx:0x%llx\n", xfer->tx_dma, xfer->rx_dma);
  92. #else
  93. SPIDEV_LOG("Transfer addr:Tx:0x%x, Rx:0x%x\n", xfer->tx_dma, xfer->rx_dma);
  94. #endif
  95. SPIDEV_LOG("Transfer addr:Tx:0x%p, Rx:0x%p\n", xfer->tx_buf, xfer->rx_buf);
  96. } else {
  97. return -EINVAL;
  98. }
  99. return 0;
  100. }
  101. static inline int is_last_xfer(struct spi_message *msg, struct spi_transfer *xfer)
  102. {
  103. return msg->transfers.prev == &xfer->transfer_list;
  104. }
  105. static int spi_recv_check(struct spi_message *msg)
  106. {
  107. struct spi_transfer *xfer;
  108. u32 cnt, i, err = 0;
  109. list_for_each_entry(xfer, &msg->transfers, transfer_list) {
  110. if (!xfer) {
  111. SPIDEV_MSG("rv msg is NULL.\n");
  112. return -1;
  113. }
  114. /*SPIDEV_LOG("xfer:0x%p, length is:%d\n", xfer,xfer->len);*/
  115. cnt = (xfer->len % 4) ? (xfer->len / 4 + 1) : (xfer->len / 4);
  116. for (i = 0; i < cnt; i++) {
  117. if (*((u32 *) xfer->rx_buf + i) != *((u32 *) xfer->tx_buf + i)) {
  118. SPIDEV_LOG("tx xfer %d is:%.8x\n", i, *((u32 *) xfer->tx_buf + i));
  119. SPIDEV_LOG("rx xfer %d is:%.8x\n", i, *((u32 *) xfer->rx_buf + i));
  120. /*SPIDEV_LOG("tx xfer %d dma is:%.8x\n",i, ( ( u32 * )xfer->tx_dma + i ) );*/
  121. /*SPIDEV_LOG("rx xfer %d dma is:%.8x\n",i, ( ( u32 * )xfer->rx_dma + i ) );*/
  122. SPIDEV_LOG("\n");
  123. err++;
  124. }
  125. }
  126. /*memset(xfer->tx_buf,0,xfer->len);*/
  127. /*memset(xfer->rx_buf,0,xfer->len);*/
  128. kfree(xfer->tx_buf);
  129. kfree(xfer->rx_buf);
  130. }
  131. SPIDEV_LOG("Message:0x%p,error %d,actual xfer length is:%d\n", msg, err, msg->actual_length);
  132. return err;
  133. }
  134. static int spi_recv_check_all(struct spi_device *spi, struct spi_message *msg)
  135. {
  136. struct spi_transfer *xfer;
  137. u32 i, err = 0;
  138. int j;
  139. u8 rec_cac = 0;
  140. struct mt_chip_conf *chip_config;
  141. chip_config = (struct mt_chip_conf *)spi->controller_data;
  142. list_for_each_entry(xfer, &msg->transfers, transfer_list) {
  143. if (!xfer) {
  144. SPIDEV_MSG("rv msg is NULL.\n");
  145. return -1;
  146. }
  147. for (i = 0; i < xfer->len; i++) {
  148. if (chip_config->tx_mlsb ^ chip_config->rx_mlsb) {
  149. rec_cac = 0;
  150. for (j = 7; j >= 0; j--)
  151. rec_cac |= ((*((u8 *) xfer->tx_buf + i) & (1 << j)) >> j) << (7 - j);
  152. } else
  153. rec_cac = *((u8 *) xfer->tx_buf + i);
  154. if (*((u8 *) xfer->rx_buf + i) != rec_cac) {
  155. SPIDEV_LOG("tx xfer %d is:%x\n", i, *((u8 *) xfer->tx_buf + i));
  156. SPIDEV_LOG("rx xfer %d is:%x\n", i, *((u8 *) xfer->rx_buf + i));
  157. err++;
  158. }
  159. }
  160. kfree(xfer->tx_buf);
  161. kfree(xfer->rx_buf);
  162. }
  163. SPIDEV_LOG("Message:0x%p,error %d,actual xfer length is:%d\n", msg, err, msg->actual_length);
  164. return err;
  165. }
  166. static void spi_complete(void *arg)
  167. {
  168. static u32 i;
  169. stress_err += spi_recv_check((struct spi_message *)arg);
  170. if (stress_err > 0)
  171. SPIDEV_LOG("Message transfer err:%d\n", stress_err);
  172. if (++i == SPI_STRESS_MAX) {
  173. i = 0;
  174. complete(&mt_spi_done);
  175. }
  176. }
  177. static int threadfunc1(void *data)
  178. {
  179. struct spi_transfer transfer;
  180. struct spi_message msg;
  181. struct spi_device *spi = (struct spi_device *)data;
  182. u32 len = 8;
  183. int ret;
  184. while (1) {
  185. spi_message_init(&msg);
  186. set_current_state(TASK_INTERRUPTIBLE);
  187. if (kthread_should_stop())
  188. break;
  189. spi_setup_xfer(&spi->dev, &transfer, len, 0);
  190. spi_message_add_tail(&transfer, &msg);
  191. ret = spi_sync(spi, &msg);
  192. if (ret < 0) {
  193. stress_err++;
  194. SPIDEV_LOG("Message transfer err:%d\n", ret);
  195. } else {
  196. ret = spi_recv_check(&msg);
  197. if (ret != 0) {
  198. stress_err += ret;
  199. SPIDEV_LOG("thread Message transfer err:%d\n", ret);
  200. }
  201. }
  202. schedule_timeout(HZ);
  203. }
  204. return 0;
  205. }
  206. static int threadfunc2(void *data)
  207. {
  208. struct spi_transfer transfer;
  209. struct spi_message msg;
  210. struct spi_device *spi = (struct spi_device *)data;
  211. u32 len = 128;
  212. int ret;
  213. while (1) {
  214. spi_message_init(&msg);
  215. set_current_state(TASK_INTERRUPTIBLE);
  216. if (kthread_should_stop())
  217. break;
  218. spi_setup_xfer(&spi->dev, &transfer, len, 0);
  219. spi_message_add_tail(&transfer, &msg);
  220. ret = spi_sync(spi, &msg);
  221. if (ret < 0) {
  222. stress_err++;
  223. SPIDEV_LOG("Message transfer err:%d\n", ret);
  224. } else {
  225. ret = spi_recv_check(&msg);
  226. if (ret != 0) {
  227. stress_err += ret;
  228. SPIDEV_LOG("thread Message transfer err:%d\n", ret);
  229. }
  230. }
  231. schedule_timeout(HZ);
  232. }
  233. return 0;
  234. }
  235. static int threadfunc3(void *data)
  236. {
  237. struct spi_message msg;
  238. struct spi_device *spi = (struct spi_device *)data;
  239. static struct spi_message *p;
  240. u32 len = 64;
  241. int ret;
  242. u16 i;
  243. while (1) {
  244. spi_message_init(&msg);
  245. set_current_state(TASK_INTERRUPTIBLE);
  246. if (kthread_should_stop())
  247. break;
  248. p = stress_msg;
  249. for (i = 0; i < SPI_STRESS_MAX; i++) {
  250. spi_message_init(p);
  251. ret = spi_setup_xfer(&spi->dev, &stress_xfer[i], len, 0);
  252. if (ret != 0)
  253. SPIDEV_LOG("xfer set up err:%d\n", ret);
  254. spi_message_add_tail(&stress_xfer[i], p);
  255. p->complete = spi_complete;
  256. p->context = p;
  257. ret = spi_async(spi, p);
  258. if (ret < 0)
  259. SPIDEV_LOG("Message %d transfer err:%d\n", i, ret);
  260. p++;
  261. }
  262. wait_for_completion(&mt_spi_done);
  263. schedule_timeout(5 * HZ);
  264. }
  265. return 0;
  266. }
  267. static int threadfunc4(void *data)
  268. {
  269. struct spi_message msg;
  270. struct spi_device *spi = (struct spi_device *)data;
  271. u32 len = 32;
  272. int ret;
  273. u16 i;
  274. while (1) {
  275. spi_message_init(&msg);
  276. set_current_state(TASK_INTERRUPTIBLE);
  277. if (kthread_should_stop())
  278. break;
  279. for (i = 0; i < SPI_STRESS_MAX; i++) {
  280. ret = spi_setup_xfer(&spi->dev, &stress_xfer_con[i], len, 1);
  281. if (ret != 0)
  282. SPIDEV_LOG("Message set up err:%d\n", ret);
  283. spi_message_add_tail(&stress_xfer_con[i], &msg);
  284. }
  285. ret = spi_sync(spi, &msg);
  286. if (ret < 0) {
  287. SPIDEV_LOG("Message transfer err:%d\n", ret);
  288. } else {
  289. ret = spi_recv_check(&msg);
  290. if (ret != 0) {
  291. ret -= ret;
  292. stress_err += ret;
  293. SPIDEV_LOG("Message transfer err:%d\n", ret);
  294. }
  295. /*SPIDEV_LOG("Message multi xfer stress pass\n");*/
  296. }
  297. schedule_timeout(2 * HZ);
  298. }
  299. return 0;
  300. }
  301. #ifdef SPI_TRUSTONIC_TEE_SUPPORT
  302. #define DEFAULT_HANDLES_NUM (64)
  303. #define MAX_OPEN_SESSIONS (0xffffffff - 1)
  304. static const struct mc_uuid_t secspi_uuid = { TL_SPI_UUID };
  305. static struct mc_session_handle secspi_session = { 0 };
  306. static u32 secspi_session_ref;
  307. static u32 secspi_devid = MC_DEVICE_ID_DEFAULT;
  308. static tciSpiMessage_t *secspi_tci;
  309. static DEFINE_MUTEX(secspi_lock);
  310. int secspi_session_open(void)
  311. {
  312. enum mc_result mc_ret = MC_DRV_OK;
  313. mutex_lock(&secspi_lock);
  314. SPIDEV_MSG("secspi_session_open start\n");
  315. do {
  316. /* sessions reach max numbers ? */
  317. if (secspi_session_ref > MAX_OPEN_SESSIONS) {
  318. SPIDEV_MSG("secspi_session > 0x%x\n", MAX_OPEN_SESSIONS);
  319. break;
  320. }
  321. if (secspi_session_ref > 0) {
  322. secspi_session_ref++;
  323. break;
  324. }
  325. /* open device */
  326. mc_ret = mc_open_device(secspi_devid);
  327. if (MC_DRV_OK != mc_ret) {
  328. SPIDEV_MSG("mc_open_device failed: %d\n", mc_ret);
  329. break;
  330. }
  331. /* allocating WSM for DCI */
  332. mc_ret = mc_malloc_wsm(secspi_devid, 0, sizeof(tciSpiMessage_t), (uint8_t **)&secspi_tci, 0);
  333. if (MC_DRV_OK != mc_ret) {
  334. SPIDEV_MSG("mc_malloc_wsm failed: %d\n", mc_ret);
  335. mc_close_device(secspi_devid);
  336. break;
  337. }
  338. /* open session */
  339. secspi_session.device_id = secspi_devid;
  340. mc_ret = mc_open_session(&secspi_session, &secspi_uuid, (uint8_t *)secspi_tci, sizeof(tciSpiMessage_t));
  341. if (MC_DRV_OK != mc_ret) {
  342. SPIDEV_MSG("secspi_session_open fail: %d\n", mc_ret);
  343. mc_free_wsm(secspi_devid, (uint8_t *) secspi_tci);
  344. mc_close_device(secspi_devid);
  345. secspi_tci = NULL;
  346. break;
  347. }
  348. secspi_session_ref = 1;
  349. } while (0);
  350. SPIDEV_MSG("secspi_session_open: ret=%d, ref=%d\n", mc_ret, secspi_session_ref);
  351. mutex_unlock(&secspi_lock);
  352. SPIDEV_MSG("secspi_session_open end\n");
  353. if (MC_DRV_OK != mc_ret)
  354. return -ENXIO;
  355. return 0;
  356. }
  357. int secspi_execute(u32 cmd, tciSpiMessage_t *param, struct mt_spi_t *ms)
  358. {
  359. enum mc_result mc_ret;
  360. SPIDEV_MSG("secspi_execute\n");
  361. mutex_lock(&secspi_lock);
  362. if (NULL == secspi_tci) {
  363. mutex_unlock(&secspi_lock);
  364. SPIDEV_MSG("secspi_tci not exist\n");
  365. return -ENODEV;
  366. }
  367. /*set transfer data para */
  368. if (NULL == param) {
  369. SPIDEV_MSG("secspi_execute parameter is NULL !!\n");
  370. } else {
  371. secspi_tci->tx_buf = param->tx_buf;
  372. secspi_tci->rx_buf = param->rx_buf;
  373. secspi_tci->len = param->len;
  374. secspi_tci->is_dma_used = param->is_dma_used;
  375. secspi_tci->tx_dma = param->tx_dma;
  376. secspi_tci->rx_dma = param->rx_dma;
  377. secspi_tci->tl_chip_config = param->tl_chip_config;
  378. }
  379. secspi_tci->cmd_spi.header.commandId = (tciCommandId_t) cmd;
  380. secspi_tci->cmd_spi.len = 0;
  381. SPIDEV_MSG("mc_notify\n");
  382. /*enable_clock(MT_CG_PERI_SPI0, "spi"); */
  383. mt_spi_enable_clk(ms);
  384. mc_ret = mc_notify(&secspi_session);
  385. if (MC_DRV_OK != mc_ret) {
  386. SPIDEV_MSG("mc_notify failed: %d", mc_ret);
  387. goto exit;
  388. }
  389. SPIDEV_MSG("SPI mc_wait_notification\n");
  390. mc_ret = mc_wait_notification(&secspi_session, -1);
  391. if (MC_DRV_OK != mc_ret) {
  392. SPIDEV_MSG("SPI mc_wait_notification failed: %d", mc_ret);
  393. goto exit;
  394. }
  395. exit:
  396. mutex_unlock(&secspi_lock);
  397. if (MC_DRV_OK != mc_ret)
  398. return -ENOSPC;
  399. return 0;
  400. }
  401. static int secspi_session_close(void)
  402. {
  403. enum mc_result mc_ret = MC_DRV_OK;
  404. mutex_lock(&secspi_lock);
  405. do {
  406. /* session is already closed ? */
  407. if (secspi_session_ref == 0) {
  408. SPIDEV_MSG("spi_session already closed\n");
  409. break;
  410. }
  411. if (secspi_session_ref > 1) {
  412. secspi_session_ref--;
  413. break;
  414. }
  415. /* close session */
  416. mc_ret = mc_close_session(&secspi_session);
  417. if (MC_DRV_OK != mc_ret) {
  418. SPIDEV_MSG("SPI mc_close_session failed: %d\n", mc_ret);
  419. break;
  420. }
  421. /* free WSM for DCI */
  422. mc_ret = mc_free_wsm(secspi_devid, (uint8_t *) secspi_tci);
  423. if (MC_DRV_OK != mc_ret) {
  424. SPIDEV_MSG("SPI mc_free_wsm failed: %d\n", mc_ret);
  425. break;
  426. }
  427. secspi_tci = NULL;
  428. secspi_session_ref = 0;
  429. /* close device */
  430. mc_ret = mc_close_device(secspi_devid);
  431. if (MC_DRV_OK != mc_ret)
  432. SPIDEV_MSG("SPI mc_close_device failed: %d\n", mc_ret);
  433. } while (0);
  434. SPIDEV_MSG("secspi_session_close: ret=%d, ref=%d\n", mc_ret, secspi_session_ref);
  435. mutex_unlock(&secspi_lock);
  436. if (MC_DRV_OK != mc_ret)
  437. return -ENXIO;
  438. return 0;
  439. }
  440. #endif
  441. static ssize_t spi_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
  442. {
  443. struct spi_device *spi;
  444. struct mt_chip_conf *chip_config;
  445. u32 setuptime, holdtime, high_time, low_time;
  446. u32 cs_idletime, ulthgh_thrsh;
  447. int cpol, cpha, tx_mlsb, rx_mlsb, tx_endian, sample_sel, cs_pol;
  448. int rx_endian, com_mod, pause, finish_intr;
  449. int deassert, tckdly, ulthigh;
  450. struct spi_master *master;
  451. struct mt_spi_t *ms;
  452. spi = container_of(dev, struct spi_device, dev);
  453. master = spi->master;
  454. ms = spi_master_get_devdata(master);
  455. SPIDEV_LOG("SPIDEV name is:%s\n", spi->modalias);
  456. chip_config = (struct mt_chip_conf *)spi->controller_data;
  457. if (!chip_config) {
  458. SPIDEV_LOG("chip_config is NULL.\n");
  459. chip_config = kzalloc(sizeof(struct mt_chip_conf), GFP_KERNEL);
  460. if (!chip_config)
  461. return -ENOMEM;
  462. }
  463. #ifdef CONFIG_TRUSTONIC_TEE_SUPPORT
  464. if (!strncmp(buf, "-1", 2)) {
  465. /*TRANSFER*/ SPIDEV_MSG("start to access TL SPI driver.\n");
  466. secspi_session_open();
  467. secspi_execute(1, NULL, ms);
  468. SPIDEV_MSG("secspi_execute 1 finished!!!\n");
  469. } else if (!strncmp(buf, "-2", 2)) { /*HW CONFIG */
  470. SPIDEV_MSG("start to access TL SPI driver.\n");
  471. secspi_session_open();
  472. secspi_execute(2, NULL, ms);
  473. SPIDEV_MSG("secspi_execute 2 finished!!!\n");
  474. } else if (!strncmp(buf, "-3", 2)) {
  475. /*DEBUG*/ SPIDEV_MSG("start to access TL SPI driver.\n");
  476. secspi_session_open();
  477. secspi_execute(3, NULL, ms);
  478. SPIDEV_MSG("secspi_execute 3 finished!!!\n");
  479. } else if (!strncmp(buf, "-4", 2)) {
  480. /*TEST*/ SPIDEV_MSG("start to access TL SPI driver.\n");
  481. secspi_session_open();
  482. secspi_execute(4, NULL, ms);
  483. SPIDEV_MSG("secspi_execute 4 finished!!!\n");
  484. #else
  485. if (!strncmp(buf, "-h", 2)) {
  486. SPIDEV_MSG("Please input the parameters for this device.\n");
  487. #endif
  488. } else if (!strncmp(buf, "-w", 2)) {
  489. buf += 3;
  490. if (!buf) {
  491. SPIDEV_LOG("buf is NULL.\n");
  492. goto out;
  493. }
  494. if (!strncmp(buf, "setuptime=", 10) && (1 == sscanf(buf + 10, "%d", &setuptime))) {
  495. SPIDEV_MSG("setuptime is:%d\n", setuptime);
  496. chip_config->setuptime = setuptime;
  497. } else if (!strncmp(buf, "holdtime=", 9) && (1 == sscanf(buf + 9, "%d", &holdtime))) {
  498. SPIDEV_MSG("Set holdtime is:%d\n", holdtime);
  499. chip_config->holdtime = holdtime;
  500. } else if (!strncmp(buf, "high_time=", 10) && (1 == sscanf(buf + 10, "%d", &high_time))) {
  501. SPIDEV_MSG("Set high_time is:%d\n", high_time);
  502. chip_config->high_time = high_time;
  503. } else if (!strncmp(buf, "low_time=", 9) && (1 == sscanf(buf + 9, "%d", &low_time))) {
  504. SPIDEV_MSG("Set low_time is:%d\n", low_time);
  505. chip_config->low_time = low_time;
  506. } else if (!strncmp(buf, "cs_idletime=", 12) && (1 == sscanf(buf + 12, "%d", &cs_idletime))) {
  507. SPIDEV_MSG("Set cs_idletime is:%d\n", cs_idletime);
  508. chip_config->cs_idletime = cs_idletime;
  509. } else if (!strncmp(buf, "ulthgh_thrsh=", 13) && (1 == sscanf(buf + 13, "%d", &ulthgh_thrsh))) {
  510. SPIDEV_MSG("Set slwdown_thrsh is:%d\n", ulthgh_thrsh);
  511. chip_config->ulthgh_thrsh = ulthgh_thrsh;
  512. } else if (!strncmp(buf, "cpol=", 5) && (1 == sscanf(buf + 5, "%d", &cpol))) {
  513. SPIDEV_MSG("Set cpol is:%d\n", cpol);
  514. chip_config->cpol = cpol;
  515. } else if (!strncmp(buf, "cpha=", 5) && (1 == sscanf(buf + 5, "%d", &cpha))) {
  516. SPIDEV_MSG("Set cpha is:%d\n", cpha);
  517. chip_config->cpha = cpha;
  518. } else if (!strncmp(buf, "tx_mlsb=", 8) && (1 == sscanf(buf + 8, "%d", &tx_mlsb))) {
  519. SPIDEV_MSG("Set tx_mlsb is:%d\n", tx_mlsb);
  520. chip_config->tx_mlsb = tx_mlsb;
  521. } else if (!strncmp(buf, "rx_mlsb=", 8) && (1 == sscanf(buf + 8, "%d", &rx_mlsb))) {
  522. SPIDEV_MSG("Set rx_mlsb is:%d\n", rx_mlsb);
  523. chip_config->rx_mlsb = rx_mlsb;
  524. } else if (!strncmp(buf, "tx_endian=", 10) && (1 == sscanf(buf + 10, "%d", &tx_endian))) {
  525. SPIDEV_MSG("Set tx_endian is:%d\n", tx_endian);
  526. chip_config->tx_endian = tx_endian;
  527. } else if (!strncmp(buf, "rx_endian=", 10) && (1 == sscanf(buf + 10, "%d", &rx_endian))) {
  528. SPIDEV_MSG("Set rx_endian is:%d\n", rx_endian);
  529. chip_config->rx_endian = rx_endian;
  530. } else if (!strncmp(buf, "com_mod=", 8) && (1 == sscanf(buf + 8, "%d", &com_mod))) {
  531. chip_config->com_mod = com_mod;
  532. SPIDEV_MSG("Set com_mod is:%d\n", com_mod);
  533. } else if (!strncmp(buf, "pause=", 6) && (1 == sscanf(buf + 6, "%d", &pause))) {
  534. SPIDEV_MSG("Set pause is:%d\n", pause);
  535. chip_config->pause = pause;
  536. } else if (!strncmp(buf, "finish_intr=", 12) && (1 == sscanf(buf + 12, "%d", &finish_intr))) {
  537. SPIDEV_MSG("Set finish_intr is:%d\n", finish_intr);
  538. chip_config->finish_intr = finish_intr;
  539. } else if (!strncmp(buf, "deassert=", 9) && (1 == sscanf(buf + 9, "%d", &deassert))) {
  540. SPIDEV_MSG("Set deassert is:%d\n", deassert);
  541. chip_config->deassert = deassert;
  542. } else if (!strncmp(buf, "ulthigh=", 8) && (1 == sscanf(buf + 8, "%d", &ulthigh))) {
  543. SPIDEV_MSG("Set ulthigh is:%d\n", ulthigh);
  544. chip_config->ulthigh = ulthigh;
  545. } else if (!strncmp(buf, "tckdly=", 7) && (1 == sscanf(buf + 7, "%d", &tckdly))) {
  546. SPIDEV_MSG("Set tckdly is:%d\n", tckdly);
  547. chip_config->tckdly = tckdly;
  548. } else if (!strncmp(buf, "sample_sel=", 11) && (1 == sscanf(buf + 11, "%d", &sample_sel))) {
  549. SPIDEV_MSG("Set sample_sel is:%d\n", sample_sel);
  550. chip_config->sample_sel = sample_sel;
  551. } else if (!strncmp(buf, "cs_pol=", 7) && (1 == sscanf(buf + 7, "%d", &cs_pol))) {
  552. SPIDEV_MSG("Set cs_pol is:%d\n", cs_pol);
  553. chip_config->cs_pol = cs_pol;
  554. } else {
  555. SPIDEV_LOG("Wrong parameters.\n");
  556. goto out;
  557. }
  558. spi->controller_data = chip_config;
  559. /*spi_setup(spi);*/
  560. }
  561. out:
  562. return count;
  563. }
  564. static int tc_spi_cross_1k(struct spi_device *spi)
  565. {
  566. int ret = 0;
  567. /*struct spi_transfer transfer;
  568. struct spi_message msg;
  569. spi_setup_xfer(&transfer,2048,2);
  570. spi_message_add_tail ( &transfer, &msg );
  571. msg.is_dma_mapped=1;
  572. ret = spi_sync ( spi_test, &msg );
  573. if(ret < 0){
  574. SPIDEV_LOG("Message transfer err:%d\n", ret);
  575. }else{
  576. ret = spi_recv_check(&msg);
  577. }*/
  578. return ret;
  579. }
  580. static ssize_t spi_msg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
  581. {
  582. struct spi_message *p;
  583. int ret = 0;
  584. struct spi_device *spi;
  585. struct spi_transfer transfer;
  586. struct spi_transfer transfer2;
  587. struct spi_transfer transfer3;
  588. struct spi_message msg;
  589. struct mt_chip_conf *chip_config;
  590. u32 i, len = 4;
  591. u32 tx_buffer = 0x12345678;
  592. u32 rx_buffer = 0xaaaaaaaa;
  593. transfer.tx_buf = &tx_buffer;
  594. transfer.rx_buf = &rx_buffer;
  595. transfer.len = 4;
  596. spi = container_of(dev, struct spi_device, dev);
  597. if (unlikely(!spi)) {
  598. SPIDEV_LOG("spi device is invalid\n");
  599. goto out;
  600. }
  601. if (unlikely(!buf)) {
  602. SPIDEV_LOG("buf is invalid\n");
  603. goto out;
  604. }
  605. spi_message_init(&msg);
  606. if (!strncmp(buf, "-h", 2)) {
  607. SPIDEV_MSG("Please input the message of this device to send and receive.\n");
  608. } else if (!strncmp(buf, "-w", 2)) {
  609. buf += 3;
  610. if (!buf) {
  611. SPIDEV_LOG("Parameter is not enough.\n");
  612. goto out;
  613. }
  614. if (!strncmp(buf, "len=", 4) && 1 == sscanf(buf + 4, "%d", &len)) {
  615. spi_setup_xfer(&spi->dev, &transfer, len, 0);
  616. spi_message_add_tail(&transfer, &msg);
  617. ret = spi_sync(spi, &msg);
  618. if (ret < 0) {
  619. SPIDEV_LOG("Message transfer err:%d\n", ret);
  620. } else {
  621. ret = spi_recv_check_all(spi, &msg);
  622. if (ret != 0) {
  623. ret = -ret;
  624. SPIDEV_LOG("Message transfer err:%d\n", ret);
  625. goto out;
  626. }
  627. }
  628. }
  629. } else if (!strncmp(buf, "-func", 5)) {
  630. buf += 6;
  631. if (!buf) {
  632. SPIDEV_LOG("Parameter is not enough.\n");
  633. goto out;
  634. }
  635. if (!strncmp(buf, "len=", 4) && 1 == sscanf(buf + 4, "%d", &len)) {
  636. spi_setup_xfer(&spi->dev, &transfer, len, 1);
  637. spi_message_add_tail(&transfer, &msg);
  638. ret = spi_sync(spi, &msg);
  639. if (ret < 0) {
  640. SPIDEV_LOG("Message transfer err:%d\n", ret);
  641. } else {
  642. ret = spi_recv_check(&msg);
  643. if (ret != 0) {
  644. ret = -ret;
  645. SPIDEV_LOG("Message transfer err:%d\n", ret);
  646. goto out;
  647. }
  648. }
  649. }
  650. if (!strncmp(buf, "cross", 5)) {
  651. ret = tc_spi_cross_1k(spi);
  652. if (ret < 0) {
  653. SPIDEV_LOG("Message transfer err:%d\n", ret);
  654. } else if (ret != 0) {
  655. ret = -ret;
  656. SPIDEV_LOG("Message transfer err:%d\n", ret);
  657. goto out;
  658. }
  659. }
  660. } else if (!strncmp(buf, "-err", 4)) {
  661. buf += 5;
  662. chip_config = (struct mt_chip_conf *)spi->controller_data;
  663. if (!strncmp(buf, "buf", 3)) { /*case: tx_buf = NULL,rx_buf = NULL*/
  664. transfer.len = 8;
  665. transfer.tx_buf = NULL;
  666. transfer.rx_buf = NULL;
  667. } else if (!strncmp(buf, "len", 3)) { /*case: tx_buf != NULL,rx_buf != NULL, len = 0*/
  668. transfer.len = 0;
  669. transfer.tx_buf = kzalloc(8, GFP_KERNEL);
  670. transfer.rx_buf = kzalloc(8, GFP_KERNEL);
  671. } else if (!strncmp(buf, "nomem", 5)) { /*case: DMA mapping error*/
  672. spi_setup_xfer(&spi->dev, &transfer, 8, 0);
  673. } else if (!strncmp(buf, "fifo_len", 8)) { /*case: len exceed FIFO size*/
  674. chip_config->com_mod = 0;
  675. spi_setup_xfer(&spi->dev, &transfer, 33, 0);
  676. } else if (!strncmp(buf, "dma_len", 7)) { /*case: len exceed DMA size*/
  677. chip_config->com_mod = 1;
  678. spi_setup_xfer(&spi->dev, &transfer, 1025, 0);
  679. } else if (!strncmp(buf, "xfer", 4)) { /*case: len exceed DMA size*/
  680. ;
  681. } else if (!strncmp(buf, "msg", 3)) { /*case: len exceed DMA size*/
  682. ;
  683. } else {
  684. SPIDEV_LOG("Error test Wrong parameters.\n");
  685. ret = -1;
  686. goto out;
  687. }
  688. if (strncmp(buf, "xfer", 4)) { /*case: MSG empty*/
  689. spi_message_add_tail(&transfer, &msg);
  690. }
  691. if (!strncmp(buf, "msg", 3)) { /*case: message = NULL*/
  692. ret = spi_sync(spi, NULL);
  693. } else {
  694. ret = spi_sync(spi, &msg);
  695. }
  696. if (ret != -EINVAL)
  697. return -100;
  698. SPIDEV_LOG("Message transfer error test passed ret:%d\n", ret);
  699. } else if (!strncmp(buf, "-pause", 6)) {
  700. spi_setup_xfer(&spi->dev, &transfer, 32, 0);
  701. spi_message_add_tail(&transfer, &msg);
  702. spi_setup_xfer(&spi->dev, &transfer2, 1024, 0);
  703. spi_message_add_tail(&transfer2, &msg);
  704. spi_setup_xfer(&spi->dev, &transfer3, 32, 0);
  705. spi_message_add_tail(&transfer3, &msg);
  706. ret = spi_sync(spi, &msg);
  707. if (ret < 0)
  708. SPIDEV_LOG("Message transfer err:%d\n", ret);
  709. else {
  710. ret = spi_recv_check(&msg);
  711. if (ret != 0) {
  712. ret = -ret;
  713. SPIDEV_LOG("Message transfer err:%d\n", ret);
  714. }
  715. }
  716. } else if (!strncmp(buf, "-stress", 7) && 1 == sscanf(buf + 8, "%d", &len)) {
  717. stress_err = 0;
  718. if (len == 0) {
  719. /*xfer = kzalloc(SPI_STRESS_MAX*sizeof( struct spi_transfer) , GFP_KERNEL);*/
  720. /*will release in spi_recv_check() function*/
  721. SPIDEV_LOG("Message multi xfer stress start\n");
  722. for (i = 0; i < SPI_STRESS_MAX; i++) {
  723. ret = spi_setup_xfer(&spi->dev, &stress_xfer[i], 32, 0);
  724. if (ret != 0)
  725. SPIDEV_LOG("Message set up err:%d\n", ret);
  726. spi_message_add_tail(&stress_xfer[i], &msg);
  727. }
  728. ret = spi_sync(spi, &msg);
  729. if (ret < 0) {
  730. SPIDEV_LOG("Message transfer err:%d\n", ret);
  731. } else {
  732. ret = spi_recv_check(&msg);
  733. if (ret != 0) {
  734. ret = -ret;
  735. SPIDEV_LOG("Message transfer err:%d\n", ret);
  736. } else {
  737. SPIDEV_LOG("Message multi xfer stress pass\n");
  738. }
  739. }
  740. } else if (len == 1) {
  741. int loop_count = 0;
  742. /*loop_count =250, take aboat half a hour.*/
  743. for (loop_count = 0; loop_count <= 5000; loop_count++) {
  744. /*msg_str = kzalloc(SPI_STRESS_MAX * sizeof(struct spi_message), GFP_KERNEL);*/
  745. /*xfer = kzalloc(SPI_STRESS_MAX * sizeof(struct spi_transfer) , GFP_KERNEL);*/
  746. SPIDEV_LOG("Message multi msg stress start\n");
  747. p = stress_msg;
  748. for (i = 0; i < SPI_STRESS_MAX; i++) {
  749. spi_message_init(p);
  750. ret = spi_setup_xfer(&spi->dev, &stress_xfer[i], 32, 0);
  751. if (ret != 0)
  752. SPIDEV_LOG("xfer set up err:%d\n", ret);
  753. spi_message_add_tail(&stress_xfer[i], p);
  754. p->complete = spi_complete;
  755. p->context = p;
  756. p++;
  757. }
  758. p = stress_msg;
  759. for (i = 0; i < SPI_STRESS_MAX; i++) {
  760. ret = spi_async(spi, p);
  761. if (ret < 0)
  762. SPIDEV_LOG("Message %d transfer err:%d\n", i, ret);
  763. p++;
  764. }
  765. wait_for_completion(&mt_spi_done);
  766. }
  767. /*kfree(msg_str);*/
  768. if (stress_err != 0) {
  769. ret = -stress_err;
  770. stress_err = 0;
  771. SPIDEV_LOG("Message stress err:%d\n", ret);
  772. } else {
  773. SPIDEV_LOG("Message stress Pass\n");
  774. ret = 0;
  775. }
  776. } else {
  777. }
  778. } else if (!strncmp(buf, "-concurrent", 11)) {
  779. stress_err = 0;
  780. spi_concur1 = kthread_run(threadfunc1, (void *)spi, "spi_concrrent1");
  781. if (IS_ERR(spi_concur1)) {
  782. SPIDEV_LOG("Unable to start kernelthread 1\n");
  783. ret = -5;
  784. goto out;
  785. }
  786. spi_concur2 = kthread_run(threadfunc2, (void *)spi, "spi_concrrent2");
  787. if (IS_ERR(spi_concur2)) {
  788. SPIDEV_LOG("Unable to start kernelthread 2\n");
  789. ret = -5;
  790. goto out;
  791. }
  792. spi_concur3 = kthread_run(threadfunc3, (void *)spi, "spi_concrrent3");
  793. if (IS_ERR(spi_concur3)) {
  794. SPIDEV_LOG("Unable to start kernelthread 3\n");
  795. ret = -5;
  796. goto out;
  797. }
  798. spi_concur4 = kthread_run(threadfunc4, (void *)spi, "spi_concrrent4");
  799. if (IS_ERR(spi_concur4)) {
  800. SPIDEV_LOG("Unable to start kernelthread 4\n");
  801. ret = -5;
  802. goto out;
  803. }
  804. msleep(10000);
  805. SPIDEV_LOG("stop kernelthread\n");
  806. kthread_stop(spi_concur1);
  807. kthread_stop(spi_concur2);
  808. kthread_stop(spi_concur3);
  809. kthread_stop(spi_concur4);
  810. ret = -stress_err;
  811. stress_err = 0;
  812. SPIDEV_LOG("concurrent test done %d\n\n\n", ret);
  813. } else {
  814. SPIDEV_LOG("Wrong parameters.\n");
  815. ret = -1;
  816. goto out;
  817. }
  818. ret = count;
  819. out:
  820. return ret;
  821. }
  822. static DEVICE_ATTR(spi, 0200, NULL, spi_store);
  823. static DEVICE_ATTR(spi_msg, 0200, NULL, spi_msg_store);
  824. static struct device_attribute *spi_attribute[] = {
  825. &dev_attr_spi,
  826. &dev_attr_spi_msg,
  827. };
  828. static int spi_create_attribute(struct device *dev)
  829. {
  830. int num, idx;
  831. int err = 0;
  832. num = (int)(sizeof(spi_attribute) / sizeof(spi_attribute[0]));
  833. for (idx = 0; idx < num; idx++) {
  834. err = device_create_file(dev, spi_attribute[idx]);
  835. if (err)
  836. break;
  837. }
  838. return err;
  839. }
  840. static void spi_remove_attribute(struct device *dev)
  841. {
  842. int num, idx;
  843. num = (int)(sizeof(spi_attribute) / sizeof(spi_attribute[0]));
  844. for (idx = 0; idx < num; idx++)
  845. device_remove_file(dev, spi_attribute[idx]);
  846. }
  847. static int spi_test_remove(struct spi_device *spi)
  848. {
  849. SPIDEV_LOG("spi_test_remove.\n");
  850. spi_remove_attribute(&spi->dev);
  851. return 0;
  852. }
  853. static int __init spi_test_probe(struct spi_device *spi)
  854. {
  855. SPIDEV_LOG("spi test probe enter\n");
  856. /*spi_test = spi;*/
  857. spi->mode = SPI_MODE_3;
  858. spi->bits_per_word = 32;
  859. return spi_create_attribute(&spi->dev);
  860. return 0;
  861. }
  862. struct spi_device_id spi_id_table = { "spi-ut", 0 };
  863. static struct spi_driver spi_test_driver = {
  864. .driver = {
  865. .name = "test_spi",
  866. .bus = &spi_bus_type,
  867. .owner = THIS_MODULE,
  868. },
  869. .probe = spi_test_probe,
  870. .remove = spi_test_remove,
  871. .id_table = &spi_id_table,
  872. };
  873. static struct spi_board_info spi_board_devs[] __initdata = {
  874. [0] = {
  875. .modalias = "spi-ut",
  876. .bus_num = 0,
  877. .chip_select = 1,
  878. .mode = SPI_MODE_3,
  879. },
  880. };
  881. static int __init spi_dev_init(void)
  882. {
  883. SPIDEV_LOG("SPI_DEV_INIT.\n");
  884. spi_register_board_info(spi_board_devs, ARRAY_SIZE(spi_board_devs));
  885. return spi_register_driver(&spi_test_driver);
  886. }
  887. static void __exit spi_test_exit(void)
  888. {
  889. SPIDEV_LOG("SPI_DEV_EXIT.\n");
  890. spi_unregister_driver(&spi_test_driver);
  891. }
  892. module_init(spi_dev_init);
  893. module_exit(spi_test_exit);
  894. MODULE_DESCRIPTION("mt SPI test device driver");
  895. MODULE_AUTHOR("Ranran Lu <ranran.lu@mediatek.com>");
  896. MODULE_LICENSE("GPL");