spi-mt65xx-dev.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813
  1. /*
  2. * Copyright (C) 2016 MediaTek Inc.
  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 version 2 as
  6. * published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
  12. */
  13. #include <linux/spi/spi.h>
  14. #include <linux/init.h>
  15. #include <linux/module.h>
  16. #include <linux/types.h>
  17. #include <linux/device.h>
  18. #include <linux/delay.h>
  19. #include <linux/platform_data/spi-mt65xx.h>
  20. #include <linux/dma-mapping.h>
  21. #include <linux/sched.h>
  22. #include <linux/kthread.h>
  23. #include <linux/clk.h>
  24. #if 0
  25. /* #ifdef CONFIG_TRUSTONIC_TEE_SUPPORT */
  26. #define SPI_TRUSTONIC_TEE_SUPPORT
  27. #endif
  28. #ifdef SPI_TRUSTONIC_TEE_SUPPORT
  29. #include <mobicore_driver_api.h>
  30. #include <tlspi_Api.h>
  31. #endif
  32. static struct spi_device *spi_test;
  33. u32 speed = 10000000;
  34. struct mtk_spi {
  35. void __iomem *base;
  36. u32 state;
  37. int pad_num;
  38. u32 *pad_sel;
  39. struct clk *parent_clk, *sel_clk, *spi_clk;
  40. struct spi_transfer *cur_transfer;
  41. u32 xfer_len;
  42. u32 num_xfered;
  43. struct scatterlist *tx_sgl, *rx_sgl;
  44. u32 tx_sgl_len, rx_sgl_len;
  45. const struct mtk_spi_compatible *dev_comp;
  46. };
  47. static struct mtk_chip_config mtk_test_chip_info = {
  48. .rx_mlsb = 0,
  49. .tx_mlsb = 0,
  50. .sample_sel = 0,
  51. .cs_setuptime = 0,
  52. .cs_holdtime = 0,
  53. .cs_idletime = 0,
  54. .deassert_mode = 0,
  55. .tick_delay = 0,
  56. };
  57. #define SPI_CFG0_REG 0x0000
  58. #define SPI_CFG1_REG 0x0004
  59. #define SPI_TX_SRC_REG 0x0008
  60. #define SPI_RX_DST_REG 0x000c
  61. #define SPI_TX_DATA_REG 0x0010
  62. #define SPI_RX_DATA_REG 0x0014
  63. #define SPI_CMD_REG 0x0018
  64. #define SPI_STATUS0_REG 0x001c
  65. #define SPI_STATUS1_REG 0x0020
  66. #define SPI_PAD_SEL_REG 0x0024
  67. #define SPI_CFG2_REG 0x0028
  68. #define SPI_TX_SRC_REG_64 0x002c
  69. #define SPI_RX_DST_REG_64 0x0030
  70. #define SPI_CFG1_CS_IDLE_OFFSET 0
  71. #define SPI_CFG1_GET_TICK_DLY_OFFSET 29
  72. #ifdef SPI_TRUSTONIC_TEE_SUPPORT
  73. #define DEFAULT_HANDLES_NUM (64)
  74. #define MAX_OPEN_SESSIONS (0xffffffff - 1)
  75. /*
  76. * Trustlet UUID.
  77. */
  78. u8 spi_uuid[10][16] = {
  79. {0x09, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  80. 0x00, 0x00, 0x00, 0x00, 0x00},
  81. {0x09, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  82. 0x00, 0x00, 0x00, 0x00, 0x00},
  83. {0x09, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  84. 0x00, 0x00, 0x00, 0x00, 0x00},
  85. {0x09, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  86. 0x00, 0x00, 0x00, 0x00, 0x00},
  87. {0x09, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  88. 0x00, 0x00, 0x00, 0x00, 0x00},
  89. {0x09, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  90. 0x00, 0x00, 0x00, 0x00, 0x00},
  91. {0x09, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  92. 0x00, 0x00, 0x00, 0x00, 0x00},
  93. {0x09, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  94. 0x00, 0x00, 0x00, 0x00, 0x00},
  95. {0x09, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  96. 0x00, 0x00, 0x00, 0x00, 0x00},
  97. {0x09, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  98. 0x00, 0x00, 0x00, 0x00, 0x00} };
  99. static struct mc_session_handle secspi_session = { 0 };
  100. static u32 secspi_session_ref;
  101. static u32 secspi_devid = MC_DEVICE_ID_DEFAULT;
  102. static tciSpiMessage_t *secspi_tci;
  103. static DEFINE_MUTEX(secspi_lock);
  104. int secspi_session_open(u32 spinum)
  105. {
  106. enum mc_result mc_ret = MC_DRV_OK;
  107. mutex_lock(&secspi_lock);
  108. pr_info("%s() start\n", __func__);
  109. do {
  110. /* sessions reach max numbers ? */
  111. if (secspi_session_ref > MAX_OPEN_SESSIONS) {
  112. pr_notice("%s() err: secspi_session(0x%x)>MAX(0x%x)\n",
  113. __func__, secspi_session_ref, MAX_OPEN_SESSIONS);
  114. break;
  115. }
  116. if (secspi_session_ref > 0) {
  117. secspi_session_ref++;
  118. break;
  119. }
  120. /* open device */
  121. mc_ret = mc_open_device(secspi_devid);
  122. if (mc_ret != MC_DRV_OK) {
  123. pr_notice("%s() mc_open_device failed: %d\n", __func__,
  124. mc_ret);
  125. break;
  126. }
  127. /* allocating WSM for DCI */
  128. mc_ret = mc_malloc_wsm(secspi_devid, 0,
  129. sizeof(tciSpiMessage_t), (uint8_t **) &secspi_tci, 0);
  130. if (mc_ret != MC_DRV_OK) {
  131. pr_notice("%s() mc_malloc_wsm failed: %d\n", __func__,
  132. mc_ret);
  133. mc_close_device(secspi_devid);
  134. break;
  135. }
  136. /* open session */
  137. secspi_session.device_id = secspi_devid;
  138. mc_ret = mc_open_session(&secspi_session,
  139. (struct mc_uuid_t *)&spi_uuid[spinum][0],
  140. (uint8_t *)secspi_tci, sizeof(tciSpiMessage_t));
  141. if (mc_ret != MC_DRV_OK) {
  142. pr_notice("%s() mc_open_session fail: %d\n", __func__,
  143. mc_ret);
  144. mc_free_wsm(secspi_devid, (uint8_t *) secspi_tci);
  145. mc_close_device(secspi_devid);
  146. secspi_tci = NULL;
  147. break;
  148. }
  149. secspi_session_ref = 1;
  150. } while (0);
  151. mutex_unlock(&secspi_lock);
  152. if (mc_ret != MC_DRV_OK) {
  153. pr_notice("%s() Done. Fail! ret=%d, ref=%d\n", __func__,
  154. mc_ret, secspi_session_ref);
  155. return -ENXIO;
  156. }
  157. pr_info("%s() Done. Success! ret=%d, ref=%d\n", __func__, mc_ret,
  158. secspi_session_ref);
  159. return 0;
  160. }
  161. static int secspi_session_close(void)
  162. {
  163. enum mc_result mc_ret = MC_DRV_OK;
  164. mutex_lock(&secspi_lock);
  165. do {
  166. /* session is already closed ? */
  167. if (secspi_session_ref == 0) {
  168. pr_notice("%s() spi_session already closed\n",
  169. __func__);
  170. break;
  171. }
  172. if (secspi_session_ref > 1) {
  173. secspi_session_ref--;
  174. break;
  175. }
  176. /* close session */
  177. mc_ret = mc_close_session(&secspi_session);
  178. if (mc_ret != MC_DRV_OK) {
  179. pr_notice("%s() mc_close_session failed: %d\n",
  180. __func__, mc_ret);
  181. break;
  182. }
  183. /* free WSM for DCI */
  184. mc_ret = mc_free_wsm(secspi_devid, (uint8_t *) secspi_tci);
  185. if (mc_ret != MC_DRV_OK) {
  186. pr_notice("%s() mc_free_wsm failed: %d\n", __func__,
  187. mc_ret);
  188. break;
  189. }
  190. secspi_tci = NULL;
  191. secspi_session_ref = 0;
  192. /* close device */
  193. mc_ret = mc_close_device(secspi_devid);
  194. if (mc_ret != MC_DRV_OK)
  195. pr_notice("%s() mc_close_device failed: %d\n",
  196. __func__, mc_ret);
  197. } while (0);
  198. mutex_unlock(&secspi_lock);
  199. if (mc_ret != MC_DRV_OK) {
  200. pr_notice("%s() Done. Fail! ret=%d, ref=%d\n", __func__,
  201. mc_ret, secspi_session_ref);
  202. return -ENXIO;
  203. }
  204. pr_info("%s() Done. Success! ret=%d, ref=%d\n", __func__, mc_ret,
  205. secspi_session_ref);
  206. return 0;
  207. }
  208. void secspi_enable_clk(struct spi_device *spidev)
  209. {
  210. int ret;
  211. struct spi_master *master;
  212. struct mtk_spi *ms;
  213. master = spidev->master;
  214. ms = spi_master_get_devdata(master);
  215. /*
  216. * prepare the clock source
  217. */
  218. ret = clk_prepare_enable(ms->spi_clk);
  219. }
  220. int secspi_execute(u32 cmd, tciSpiMessage_t *param)
  221. {
  222. enum mc_result mc_ret;
  223. pr_info("%s() start.\n", __func__);
  224. mutex_lock(&secspi_lock);
  225. if (secspi_tci == NULL) {
  226. mutex_unlock(&secspi_lock);
  227. pr_notice("%s() secspi_tci not exist\n", __func__);
  228. return -ENODEV;
  229. }
  230. /*set transfer data para */
  231. if (param == NULL) {
  232. pr_notice("%s() parameter is NULL !!\n", __func__);
  233. } else {
  234. secspi_tci->tx_buf = param->tx_buf;
  235. secspi_tci->rx_buf = param->rx_buf;
  236. secspi_tci->len = param->len;
  237. secspi_tci->is_dma_used = param->is_dma_used;
  238. secspi_tci->tx_dma = param->tx_dma;
  239. secspi_tci->rx_dma = param->rx_dma;
  240. secspi_tci->tl_chip_config = param->tl_chip_config;
  241. }
  242. secspi_tci->cmd_spi.header.commandId = (tciCommandId_t) cmd;
  243. secspi_tci->cmd_spi.len = 0;
  244. /* enable_clock(MT_CG_PERI_SPI0, "spi"); */
  245. /* enable_clk(ms); */
  246. mc_ret = mc_notify(&secspi_session);
  247. if (mc_ret != MC_DRV_OK) {
  248. pr_notice("%s() mc_notify failed: %d", __func__, mc_ret);
  249. goto exit;
  250. }
  251. mc_ret = mc_wait_notification(&secspi_session, -1);
  252. if (mc_ret != MC_DRV_OK) {
  253. pr_notice("%s() SPI mc_wait_notification failed: %d", __func__,
  254. mc_ret);
  255. goto exit;
  256. }
  257. exit:
  258. mutex_unlock(&secspi_lock);
  259. if (mc_ret != MC_DRV_OK) {
  260. pr_notice("%s() Done. Fail. ret:%d\n", __func__, mc_ret);
  261. return -ENOSPC;
  262. }
  263. pr_info("%s() Done. Success. ret:%d\n", __func__, mc_ret);
  264. return 0;
  265. }
  266. /*used for REE to detach IRQ of TEE*/
  267. void spi_detach_irq_tee(u32 spinum)
  268. {
  269. secspi_session_open(spinum);
  270. secspi_execute(2, NULL);
  271. pr_info("%s() Done.\n", __func__);
  272. }
  273. #endif
  274. void mt_spi_disable_master_clk(struct spi_device *spidev)
  275. {
  276. struct mtk_spi *ms;
  277. ms = spi_master_get_devdata(spidev->master);
  278. clk_disable_unprepare(ms->spi_clk);
  279. }
  280. EXPORT_SYMBOL(mt_spi_disable_master_clk);
  281. void mt_spi_enable_master_clk(struct spi_device *spidev)
  282. {
  283. int ret;
  284. struct mtk_spi *ms;
  285. ms = spi_master_get_devdata(spidev->master);
  286. ret = clk_prepare_enable(ms->spi_clk);
  287. }
  288. EXPORT_SYMBOL(mt_spi_enable_master_clk);
  289. static int spi_setup_xfer(struct device *dev, struct spi_transfer *xfer,
  290. u32 len, u32 flag)
  291. {
  292. u32 tx_buffer = 0x12345678;
  293. u32 cnt, i;
  294. xfer->speed_hz = speed;
  295. pr_info("%s() flag:%d speed:%d\n", __func__, flag, xfer->speed_hz);
  296. /* Instead of using kzalloc, if using below
  297. * dma_alloc_coherent to allocate tx_dma/rx_dma, remember:
  298. * 1. remove kfree in spi_recv_check_all, otherwise KE reboot
  299. * 2. set msg.is_dma_mapped = 1 before calling spi_sync();
  300. */
  301. if ((xfer->tx_buf == NULL) || (xfer->rx_buf == NULL))
  302. return -1;
  303. cnt = (len%4)?(len/4 + 1):(len/4);
  304. if (flag == 0)
  305. for (i = 0; i < cnt; i++)
  306. *((u32 *)xfer->tx_buf + i) = tx_buffer;
  307. else if (flag == 1)
  308. for (i = 0; i < cnt; i++)
  309. *((u32 *)xfer->tx_buf + i) = tx_buffer + i;
  310. else
  311. return -EINVAL;
  312. return 0;
  313. }
  314. static int spi_recv_check(struct spi_device *spi, struct spi_message *msg)
  315. {
  316. struct mtk_chip_config *chip_config;
  317. struct spi_transfer *xfer;
  318. u32 i, err = 0;
  319. int j;
  320. u8 t, rec_cac;
  321. chip_config = (struct mtk_chip_config *) spi->controller_data;
  322. list_for_each_entry(xfer, &msg->transfers, transfer_list) {
  323. if (!xfer) {
  324. pr_notice("%s() rv msg is NULL.\n", __func__);
  325. return -1;
  326. }
  327. pr_info("%s xfer->len:%d chip_config->tx_mlsb:%d rx_mlsb:%d\n",
  328. __func__, xfer->len, chip_config->tx_mlsb,
  329. chip_config->rx_mlsb);
  330. for (i = 0; i < xfer->len; i++) {
  331. if (chip_config->tx_mlsb ^ chip_config->rx_mlsb) {
  332. rec_cac = 0;
  333. for (j = 7; j >= 0; j--) {
  334. t = *((u8 *)xfer->tx_buf + i) & (1<<j);
  335. t = (t >> j) << (7-j);
  336. rec_cac |= t;
  337. }
  338. } else
  339. rec_cac = *((u8 *) xfer->tx_buf + i);
  340. if (*((u8 *) xfer->rx_buf + i) != rec_cac) {
  341. pr_notice("%s() tx xfer %d is:%x\n", __func__,
  342. i, *((u8 *) xfer->tx_buf + i));
  343. pr_notice("%s() rx xfer %d is:%x\n", __func__,
  344. i, *((u8 *) xfer->rx_buf + i));
  345. err++;
  346. }
  347. }
  348. }
  349. pr_info("%s() Done. error %d,actual xfer len:%d\n", __func__, err,
  350. msg->actual_length);
  351. return err;
  352. }
  353. static ssize_t spi_store(struct device *dev, struct device_attribute *attr,
  354. const char *buf, size_t count)
  355. {
  356. struct spi_device *spi;
  357. struct mtk_spi *mdata = NULL;
  358. struct mtk_chip_config *chip_config;
  359. u32 cs_idletime, pad_sel;
  360. int cpol, cpha, tx_mlsb, rx_mlsb;
  361. int sample_sel, tckdly;
  362. u32 reg_val;
  363. int dump_all, dump;
  364. int index;
  365. #if 0
  366. /* #ifdef CONFIG_TRUSTONIC_TEE_SUPPORT */
  367. u32 spinum;
  368. #endif
  369. spi = container_of(dev, struct spi_device, dev);
  370. pr_info("%s() SPIDEV name is:%s\n", __func__, spi->modalias);
  371. chip_config = (struct mtk_chip_config *) spi->controller_data;
  372. if (!chip_config) {
  373. pr_notice("%s() chip_config is NULL.\n", __func__);
  374. chip_config = kzalloc(sizeof(struct mtk_chip_config),
  375. GFP_KERNEL);
  376. if (!chip_config)
  377. return -ENOMEM;
  378. }
  379. if (!buf) {
  380. pr_notice("%s() buf is NULL.Exit!\n", __func__);
  381. goto out;
  382. }
  383. #if 0
  384. /* #ifdef CONFIG_TRUSTONIC_TEE_SUPPORT */
  385. if (!strncmp(buf, "send", 4)) {
  386. if (sscanf(buf + 4, "%d", &spinum) == 1) {
  387. pr_info("%s() start to access TL SPI driver.\n",
  388. __func__);
  389. secspi_session_open(spinum);
  390. secspi_enable_clk(spi);
  391. secspi_execute(1, NULL);
  392. secspi_session_close();
  393. pr_info("%s() secspi_execute 1 finished!\n", __func__);
  394. }
  395. } else if (!strncmp(buf, "config", 6)) {
  396. if (sscanf(buf + 6, "%d", &spinum) == 1) {
  397. pr_info("start to access TL SPI driver.\n");
  398. secspi_session_open(spinum);
  399. secspi_execute(2, NULL);
  400. secspi_session_close();
  401. pr_info("secspi_execute 2 finished!!!\n");
  402. }
  403. } else if (!strncmp(buf, "debug", 5)) {
  404. if (sscanf(buf + 5, "%d", &spinum) == 1) {
  405. pr_info("start to access TL SPI driver.\n");
  406. secspi_session_open(spinum);
  407. secspi_execute(3, NULL);
  408. secspi_session_close();
  409. pr_info("secspi_execute 3 finished!!!\n");
  410. }
  411. } else if (!strncmp(buf, "test", 4)) {
  412. if (sscanf(buf + 4, "%d", &spinum) == 1) {
  413. pr_info("start to access TL SPI driver.\n");
  414. secspi_session_open(spinum);
  415. secspi_execute(4, NULL);
  416. secspi_session_close();
  417. pr_info("secspi_execute 4 finished!!!\n");
  418. }
  419. }
  420. #endif
  421. else if (!strncmp(buf, "-w", 2))
  422. goto set;
  423. else
  424. goto out;
  425. set:
  426. buf += 3;
  427. mdata = spi_master_get_devdata(spi->master);
  428. mt_spi_enable_master_clk(spi);
  429. if (!strncmp(buf, "setuptime=", 10))
  430. pr_info("%s() setuptime cannot be set by cmd.\n", __func__);
  431. else if (!strncmp(buf, "holdtime=", 9))
  432. pr_info("%s() holdtime cannot be set by cmd.\n", __func__);
  433. else if (!strncmp(buf, "high_time=", 10))
  434. pr_info("%s() high_time cannot be set by cmd.\n", __func__);
  435. else if (!strncmp(buf, "low_time=", 9))
  436. pr_info("%s() low_time cannot be set by cmd.\n", __func__);
  437. else if (!strncmp(buf, "tckdly=", 7)) {
  438. if (sscanf(buf+7, "%d", &tckdly) == 1) {
  439. pr_info("%s() set tckdly=%d to SPI_CFG1_REG.\n",
  440. __func__, tckdly);
  441. reg_val = readl(mdata->base + SPI_CFG1_REG);
  442. reg_val &= 0x1FFFFFFF;
  443. reg_val |= (tckdly << SPI_CFG1_GET_TICK_DLY_OFFSET);
  444. writel(reg_val, mdata->base + SPI_CFG1_REG);
  445. reg_val = readl(mdata->base + SPI_CFG1_REG);
  446. pr_info("%s() now SPI_CFG1_REG=0x%x.\n", __func__,
  447. reg_val);
  448. }
  449. } else if (!strncmp(buf, "cs_idletime=", 12)) {
  450. if (sscanf(buf+12, "%d", &cs_idletime) == 1) {
  451. pr_info("%s() set cs_idletime=%d to SPI_CFG1_REG\n",
  452. __func__, cs_idletime);
  453. reg_val = readl(mdata->base + SPI_CFG1_REG);
  454. reg_val &= 0xFFFFFF00;
  455. reg_val |= (cs_idletime << SPI_CFG1_CS_IDLE_OFFSET);
  456. writel(reg_val, mdata->base + SPI_CFG1_REG);
  457. reg_val = readl(mdata->base + SPI_CFG1_REG);
  458. pr_info("%s() now SPI_CFG1_REG=0x%x.\n", __func__,
  459. reg_val);
  460. }
  461. } else if (!strncmp(buf, "cpol=", 5)) {
  462. if (sscanf(buf+5, "%d", &cpol) == 1) {
  463. pr_info("%s() Set cpol=%d to spi->mode.\n", __func__,
  464. cpol);
  465. spi->mode &= 0xFD;
  466. spi->mode |= cpol<<1;
  467. pr_info("%s() mow spi->mode:0x%.4x\n", __func__,
  468. spi->mode);
  469. }
  470. } else if (!strncmp(buf, "cpha=", 5)) {
  471. if (sscanf(buf+5, "%d", &cpha) == 1) {
  472. pr_info("%s() Set cpha=%d to spi->mode.\n", __func__,
  473. cpha);
  474. spi->mode &= 0xFE;
  475. spi->mode |= cpha;
  476. pr_info("%s() mow spi->mode:0x%.4x\n", __func__,
  477. spi->mode);
  478. }
  479. } else if (!strncmp(buf, "tx_mlsb=", 8)) {
  480. if (sscanf(buf+8, "%d", &tx_mlsb) == 1) {
  481. pr_info("%s() Set tx_mlsb=%d to chip_config\n",
  482. __func__, tx_mlsb);
  483. chip_config->tx_mlsb = tx_mlsb;
  484. }
  485. } else if (!strncmp(buf, "rx_mlsb=", 8)) {
  486. if (sscanf(buf+8, "%d", &rx_mlsb) == 1) {
  487. pr_info("%s() Set rx_mlsb=%d to chip_config\n",
  488. __func__, rx_mlsb);
  489. chip_config->rx_mlsb = rx_mlsb;
  490. }
  491. } else if (!strncmp(buf, "tx_endian=", 10))
  492. pr_info("%s() tx_endian cannot be set.See __LTTTLE_ENDIAN\n",
  493. __func__);
  494. else if (!strncmp(buf, "rx_endian=", 10))
  495. pr_info("%s() rx_endian cannot be set.See __LTTTLE_ENDIAN\n",
  496. __func__);
  497. else if (!strncmp(buf, "pause=", 6))
  498. pr_info("%s() pause cannot be set due to sw auto select\n",
  499. __func__);
  500. else if (!strncmp(buf, "deassert=", 9))
  501. pr_info("%s() deassert cannot be set, sw default disable\n",
  502. __func__);
  503. else if (!strncmp(buf, "sample_sel=", 11)) {
  504. if (sscanf(buf + 11, "%d", &sample_sel) == 1) {
  505. pr_info("%s() Set sample_sel=%d to chip_config\n",
  506. __func__, sample_sel);
  507. chip_config->sample_sel = sample_sel;
  508. }
  509. } else if (!strncmp(buf, "pad_sel=", 8)) {
  510. if (sscanf(buf + 8, "%d", &pad_sel) == 1) {
  511. pr_info("%s() Set pad select=%d to mdata->pad_sel.\n",
  512. __func__, pad_sel);
  513. mdata->pad_sel[spi->chip_select] = pad_sel;
  514. }
  515. } else if (!strncmp(buf, "speed=", 6)) {
  516. if (sscanf(buf + 6, "%d", &speed) == 1)
  517. pr_info("%s() Set speed=%d as global parameter.\n",
  518. __func__, speed);
  519. } else if (!strncmp(buf, "dump_all=", 9)) {
  520. if (sscanf(buf + 9, "%d", &dump_all) == 1) {
  521. pr_info("%s() dump all register.\n", __func__);
  522. pr_info("||* spi_dump_reg *******************||\n");
  523. pr_info("cfg0:0x%.8x\n",
  524. readl(mdata->base + SPI_CFG0_REG));
  525. pr_info("cfg1:0x%.8x\n",
  526. readl(mdata->base + SPI_CFG1_REG));
  527. pr_info("tx_s:0x%.8x\n",
  528. readl(mdata->base + SPI_TX_SRC_REG));
  529. pr_info("rx_d:0x%.8x\n",
  530. readl(mdata->base + SPI_RX_DST_REG));
  531. pr_info("tx_data:0x%.8x\n",
  532. readl(mdata->base + SPI_TX_DATA_REG));
  533. pr_info("rx_data:0x%.8x\n",
  534. readl(mdata->base + SPI_RX_DATA_REG));
  535. pr_info("cmd :0x%.8x\n",
  536. readl(mdata->base + SPI_CMD_REG));
  537. pr_info("status0:0x%.8x\n",
  538. readl(mdata->base + SPI_STATUS0_REG));
  539. pr_info("status1:0x%.8x\n",
  540. readl(mdata->base + SPI_STATUS1_REG));
  541. pr_info("pad_sel:0x%.8x\n",
  542. readl(mdata->base + SPI_PAD_SEL_REG));
  543. pr_info("cfg2:0x%.8x\n",
  544. readl(mdata->base + SPI_CFG2_REG));
  545. pr_info("tx_s64:0x%.8x\n",
  546. readl(mdata->base + SPI_TX_SRC_REG_64));
  547. pr_info("rx_d64:0x%.8x\n",
  548. readl(mdata->base + SPI_RX_DST_REG_64));
  549. pr_info("||*****************************************||\n");
  550. }
  551. } else if (!strncmp(buf, "dump=", 5)) {
  552. if (sscanf(buf + 5, "%d", &dump) == 1) {
  553. pr_info("%s() dump TX FIFO.\n", __func__);
  554. for (index = 1; index <= 8; index++)
  555. pr_info("%d tx_data:0x%.8x\n",
  556. index, readl(mdata->base + SPI_TX_DATA_REG));
  557. pr_info("%s() dump RX FIFO.\n", __func__);
  558. for (index = 1; index <= 8; index++)
  559. pr_info("%d rx_data:0x%.8x\n",
  560. index, readl(mdata->base + SPI_RX_DATA_REG));
  561. }
  562. } else {
  563. pr_notice("%s() Wrong parameters.Do nothing.\n", __func__);
  564. mt_spi_disable_master_clk(spi);
  565. goto out;
  566. }
  567. mt_spi_disable_master_clk(spi);
  568. out:
  569. if (!spi->controller_data)
  570. kfree(chip_config);
  571. return count;
  572. }
  573. static ssize_t
  574. spi_msg_store(struct device *dev, struct device_attribute *attr,
  575. const char *buf, size_t count)
  576. {
  577. int ret = 0;
  578. struct spi_device *spi;
  579. struct spi_transfer transfer = {0,};
  580. struct spi_message msg;
  581. u32 len = 4;
  582. spi = container_of(dev, struct spi_device, dev);
  583. if (unlikely(!spi)) {
  584. pr_notice("%s() spi device is invalid\n", __func__);
  585. goto out;
  586. }
  587. if (unlikely(!buf)) {
  588. pr_notice("%s() buf is invalid\n", __func__);
  589. goto out;
  590. }
  591. spi_message_init(&msg);
  592. if (strncmp(buf, "-func", 5)) {
  593. pr_notice("%s() Wrong parameters.Do nothing.\n", __func__);
  594. ret = -1;
  595. goto out;
  596. }
  597. buf += 6;
  598. if (!strncmp(buf, "len=", 4) && 1 == sscanf(buf + 4, "%d", &len)) {
  599. pr_info("%s() start transfer,dataLen=%d.-----------------\n",
  600. __func__, len);
  601. transfer.len = len;
  602. transfer.tx_buf = kzalloc(len, GFP_KERNEL);
  603. transfer.rx_buf = kzalloc(len, GFP_KERNEL);
  604. pr_info("%s() transfer.tx_buf:%p, transfer.rx_buf:%p\n",
  605. __func__, transfer.tx_buf, transfer.rx_buf);
  606. spi_setup_xfer(&spi->dev, &transfer, len, 1);
  607. spi_message_add_tail(&transfer, &msg);
  608. ret = spi_sync(spi, &msg);
  609. if (ret < 0) {
  610. pr_notice("%s() spi_sync err:%d\n", __func__, ret);
  611. } else {
  612. ret = spi_recv_check(spi, &msg);
  613. kfree(transfer.tx_buf);
  614. kfree(transfer.rx_buf);
  615. if (ret != 0) {
  616. ret = -ret;
  617. pr_notice("%s Message transfer err:%d\n",
  618. __func__, ret);
  619. goto out;
  620. }
  621. }
  622. pr_info("%s() spi transfer Done.-----------------\n",
  623. __func__);
  624. }
  625. ret = count;
  626. out:
  627. return count;
  628. //return ret;
  629. }
  630. static DEVICE_ATTR(spi, 0200, NULL, spi_store);
  631. static DEVICE_ATTR(spi_msg, 0200, NULL, spi_msg_store);
  632. static struct device_attribute *spi_attribute[] = {
  633. &dev_attr_spi,
  634. &dev_attr_spi_msg,
  635. };
  636. static int spi_create_attribute(struct device *dev)
  637. {
  638. int num, idx;
  639. int err = 0;
  640. num = (int)ARRAY_SIZE(spi_attribute);
  641. for (idx = 0; idx < num; idx++) {
  642. err = device_create_file(dev, spi_attribute[idx]);
  643. if (err)
  644. break;
  645. }
  646. return err;
  647. }
  648. static void spi_remove_attribute(struct device *dev)
  649. {
  650. int num, idx;
  651. num = (int)ARRAY_SIZE(spi_attribute);
  652. for (idx = 0; idx < num; idx++)
  653. device_remove_file(dev, spi_attribute[idx]);
  654. }
  655. static int spi_test_remove(struct spi_device *spi)
  656. {
  657. pr_info("%s().\n", __func__);
  658. spi_remove_attribute(&spi->dev);
  659. return 0;
  660. }
  661. static int spi_test_probe(struct spi_device *spi)
  662. {
  663. pr_info("%s() enter.\n", __func__);
  664. spi_test = spi;
  665. spi->mode = SPI_MODE_3;
  666. spi->bits_per_word = 8;
  667. spi->controller_data = (void *)&mtk_test_chip_info;
  668. return spi_create_attribute(&spi->dev);
  669. }
  670. struct spi_device_id spi_id_table[] = {
  671. {"spi-ut", 0},
  672. {},
  673. };
  674. static const struct of_device_id spidev_dt_ids[] = {
  675. { .compatible = "mediatek,spi-mt65xx-test" },
  676. {},
  677. };
  678. MODULE_DEVICE_TABLE(of, spidev_dt_ids);
  679. static struct spi_driver spi_test_driver = {
  680. .driver = {
  681. .name = "test_spi",
  682. .bus = &spi_bus_type,
  683. .owner = THIS_MODULE,
  684. .of_match_table = spidev_dt_ids,
  685. },
  686. .probe = spi_test_probe,
  687. .remove = spi_test_remove,
  688. .id_table = spi_id_table,
  689. };
  690. static int __init spi_dev_init(void)
  691. {
  692. pr_info("%s().\n", __func__);
  693. return spi_register_driver(&spi_test_driver);
  694. }
  695. static void __exit spi_test_exit(void)
  696. {
  697. pr_info("%s().\n", __func__);
  698. spi_unregister_driver(&spi_test_driver);
  699. }
  700. module_init(spi_dev_init);
  701. module_exit(spi_test_exit);
  702. MODULE_DESCRIPTION("mt SPI test device driver");
  703. MODULE_AUTHOR("ZH Chen <zh.chen@mediatek.com>");
  704. MODULE_LICENSE("GPL");