ssi.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878
  1. /*
  2. * This file is part of FH8620 BSP for RT-Thread distribution.
  3. *
  4. * Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
  5. * All rights reserved
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program; if not, write to the Free Software Foundation, Inc.,
  19. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20. *
  21. * Visit http://www.fullhan.com to get contact with Fullhan.
  22. *
  23. * Change Logs:
  24. * Date Author Notes
  25. */
  26. #include <rtdevice.h>
  27. #include <drivers/spi.h>
  28. #include "fh_arch.h"
  29. #include "board_info.h"
  30. #include "ssi.h"
  31. #include "gpio.h"
  32. #include "inc/fh_driverlib.h"
  33. #include "dma.h"
  34. #include "dma_mem.h"
  35. #include "mmu.h"
  36. //#define FH_SPI_DEBUG
  37. #ifdef FH_SPI_DEBUG
  38. #define PRINT_SPI_DBG(fmt, args...) \
  39. do \
  40. { \
  41. rt_kprintf("FH_SPI_DEBUG: "); \
  42. rt_kprintf(fmt, ## args); \
  43. } \
  44. while(0)
  45. #else
  46. #define PRINT_SPI_DBG(fmt, args...) do { } while (0)
  47. #endif
  48. #define RX_DMA_CHANNEL AUTO_FIND_CHANNEL
  49. #define TX_DMA_CHANNEL AUTO_FIND_CHANNEL
  50. #define DMA_OR_ISR_THRESHOLD 20
  51. #define MALLOC_DMA_MEM_SIZE 0x1000
  52. //static rt_uint32_t allign_func(rt_uint32_t in_addr,rt_uint32_t allign_size){
  53. // return (in_addr + allign_size-1) & (~(allign_size - 1));
  54. //}
  55. void * fh_get_spi_dev_pri_data(struct rt_spi_device* device){
  56. return device->parent.user_data;
  57. }
  58. static rt_err_t fh_spi_configure(struct rt_spi_device* device,
  59. struct rt_spi_configuration* configuration)
  60. {
  61. struct spi_slave_info *spi_slave;
  62. struct spi_controller *spi_control;
  63. struct fh_spi_obj *spi_obj;
  64. struct spi_config *config;
  65. rt_uint32_t status;
  66. rt_uint32_t spi_hz;
  67. spi_slave = ( struct spi_slave_info *)fh_get_spi_dev_pri_data(device);
  68. spi_control = spi_slave->control;
  69. spi_obj = &spi_control->obj;
  70. config = &spi_obj->config;
  71. PRINT_SPI_DBG("configuration: \n");
  72. PRINT_SPI_DBG("\tmode: 0x%x\n", configuration->mode);
  73. PRINT_SPI_DBG("\tdata_width: 0x%x\n", configuration->data_width);
  74. PRINT_SPI_DBG("\tmax_hz: 0x%x\n", configuration->max_hz);
  75. do{
  76. status = SPI_ReadStatus(spi_obj);
  77. }
  78. while(status & SPI_STATUS_BUSY);
  79. /* data_width */
  80. if(configuration->data_width <= 8){
  81. config->data_size = SPI_DATA_SIZE_8BIT;
  82. }
  83. else if(configuration->data_width <= 16){
  84. config->data_size = SPI_DATA_SIZE_16BIT;
  85. }
  86. else{
  87. return -RT_ERROR;
  88. }
  89. if(configuration->max_hz > spi_control->max_hz)
  90. spi_hz = spi_control->max_hz;
  91. else
  92. spi_hz = configuration->max_hz;
  93. //fixme: div
  94. config->clk_div = spi_control->clk_in/spi_hz;
  95. //config->clk_div = 8;
  96. PRINT_SPI_DBG("config hz:%d spi div:%d\n",spi_hz,config->clk_div);
  97. /* CPOL */
  98. if(configuration->mode & RT_SPI_CPOL){
  99. config->clk_polarity = SPI_POLARITY_HIGH;
  100. }
  101. else{
  102. config->clk_polarity = SPI_POLARITY_LOW;
  103. }
  104. /* CPHA */
  105. if(configuration->mode & RT_SPI_CPHA){
  106. config->clk_phase = SPI_PHASE_TX_FIRST;
  107. }
  108. else{
  109. config->clk_phase = SPI_PHASE_RX_FIRST;
  110. }
  111. config->frame_format = SPI_FORMAT_MOTOROLA;
  112. config->transfer_mode = SPI_MODE_TX_RX;
  113. SPI_Enable(spi_obj, 0);
  114. SPI_SetParameter(spi_obj);
  115. SPI_DisableInterrupt(spi_obj, SPI_IRQ_ALL);
  116. SPI_Enable(spi_obj, 1);
  117. return RT_EOK;
  118. }
  119. static void xfer_dma_done(void *arg)
  120. {
  121. struct spi_controller *spi_control = (struct spi_controller *)arg;
  122. spi_control->dma_complete_times++;
  123. struct fh_spi_obj *spi_obj;
  124. int ret;
  125. rt_uint32_t slave_id;
  126. spi_obj = &spi_control->obj;
  127. //rt_kprintf("spi dma isr done.....\n");
  128. if (spi_control->dma_complete_times == 2) {
  129. spi_control->dma_complete_times = 0;
  130. //add memcpy to user buff
  131. if(spi_control->current_message->recv_buf){
  132. rt_memcpy((void*)spi_control->current_message->recv_buf,(void*)spi_control->dma.rx_dummy_buff,spi_control->current_message->length);
  133. }
  134. SPI_Enable(spi_obj,0);
  135. SPI_DisableDma(spi_obj,SPI_TX_DMA|SPI_RX_DMA);
  136. SPI_Enable(spi_obj,1);
  137. rt_completion_done(&spi_control->transfer_completion);
  138. }
  139. }
  140. void dma_set_tx_data(struct spi_controller *spi_control){
  141. struct dma_transfer *trans;
  142. rt_uint32_t hs_no;
  143. struct rt_spi_message* current_message = spi_control->current_message;
  144. trans = &spi_control->dma.tx_trans;
  145. hs_no = spi_control->dma.tx_hs;
  146. struct fh_spi_obj *spi_obj;
  147. spi_obj = &spi_control->obj;
  148. if(current_message->length > MALLOC_DMA_MEM_SIZE){
  149. rt_kprintf("[spi_dma]message len too large..\n");
  150. rt_kprintf("[spi_dma] message len is %d,max len is %d\n",current_message->length,MALLOC_DMA_MEM_SIZE);
  151. RT_ASSERT(current_message->length <= MALLOC_DMA_MEM_SIZE);
  152. }
  153. rt_memset((void*)spi_control->dma.tx_dummy_buff,0xff,current_message->length);
  154. //copy tx data....
  155. if(current_message->send_buf){
  156. rt_memcpy(spi_control->dma.tx_dummy_buff,current_message->send_buf,current_message->length);
  157. }
  158. trans->dma_number = 0;
  159. trans->dst_add = (rt_uint32_t)(spi_obj->base + OFFSET_SPI_DR);
  160. trans->dst_hs = DMA_HW_HANDSHAKING;
  161. trans->dst_inc_mode = DW_DMA_SLAVE_FIX;
  162. trans->dst_msize = DW_DMA_SLAVE_MSIZE_1;
  163. trans->dst_per = hs_no;
  164. trans->dst_width = DW_DMA_SLAVE_WIDTH_8BIT;
  165. trans->fc_mode = DMA_M2P;
  166. trans->src_add = (rt_uint32_t)spi_control->dma.tx_dummy_buff;
  167. trans->src_inc_mode = DW_DMA_SLAVE_INC;
  168. trans->src_msize = DW_DMA_SLAVE_MSIZE_1;
  169. trans->src_width = DW_DMA_SLAVE_WIDTH_8BIT;
  170. trans->trans_len = current_message->length;
  171. trans->complete_callback = (void *)xfer_dma_done;
  172. trans->complete_para = (void *)spi_control;
  173. }
  174. void dma_set_rx_data(struct spi_controller *spi_control){
  175. struct dma_transfer *trans;
  176. rt_uint32_t hs_no;
  177. struct rt_spi_message* current_message = spi_control->current_message;
  178. trans = &spi_control->dma.rx_trans;
  179. hs_no = spi_control->dma.rx_hs;
  180. struct fh_spi_obj *spi_obj;
  181. spi_obj = &spi_control->obj;
  182. if(current_message->length > MALLOC_DMA_MEM_SIZE){
  183. rt_kprintf("[spi_dma]message len too large..len is %d\n",current_message->length);
  184. RT_ASSERT(current_message->length <= MALLOC_DMA_MEM_SIZE);
  185. }
  186. //rt_memset((void *)spi_control->dma.rx_dummy_buff,0,MALLOC_DMA_MEM_SIZE);
  187. trans->dma_number = 0;
  188. trans->fc_mode = DMA_P2M;
  189. trans->dst_add = (rt_uint32_t)spi_control->dma.rx_dummy_buff;
  190. trans->dst_inc_mode = DW_DMA_SLAVE_INC;
  191. trans->dst_msize = DW_DMA_SLAVE_MSIZE_1;
  192. trans->dst_width = DW_DMA_SLAVE_WIDTH_8BIT;
  193. trans->src_add = (rt_uint32_t)(spi_obj->base + OFFSET_SPI_DR);
  194. trans->src_inc_mode = DW_DMA_SLAVE_FIX;
  195. trans->src_msize = DW_DMA_SLAVE_MSIZE_1;
  196. trans->src_width = DW_DMA_SLAVE_WIDTH_8BIT;
  197. trans->src_hs = DMA_HW_HANDSHAKING;
  198. trans->src_per = hs_no;
  199. trans->trans_len = current_message->length;
  200. trans->complete_callback = (void *)xfer_dma_done;
  201. trans->complete_para = (void *)spi_control;
  202. }
  203. rt_uint32_t xfer_data_dma(struct spi_controller *spi_control){
  204. int ret;
  205. struct fh_spi_obj *spi_obj;
  206. spi_obj = &spi_control->obj;
  207. struct rt_dma_device *dma_dev = spi_control->dma.dma_dev;
  208. //tx data prepare
  209. dma_set_tx_data(spi_control);
  210. //rx data prepare
  211. dma_set_rx_data(spi_control);
  212. //dma go...
  213. SPI_Enable(spi_obj,0);
  214. //SPI_WriteTxDmaLevel(spi_obj,SPI_FIFO_DEPTH / 4);
  215. SPI_WriteTxDmaLevel(spi_obj,1);
  216. //SPI_WriteTxDmaLevel(spi_obj,0);
  217. SPI_WriteRxDmaLevel(spi_obj,0);
  218. SPI_EnableDma(spi_obj,SPI_TX_DMA|SPI_RX_DMA);
  219. SPI_Enable(spi_obj,1);
  220. dma_dev->ops->control(dma_dev,RT_DEVICE_CTRL_DMA_SINGLE_TRANSFER,(void *)&spi_control->dma.rx_trans);
  221. dma_dev->ops->control(dma_dev,RT_DEVICE_CTRL_DMA_SINGLE_TRANSFER,(void *)&spi_control->dma.tx_trans);
  222. ret = rt_completion_wait(&spi_control->transfer_completion, RT_TICK_PER_SECOND*50);
  223. //release channel..
  224. //dma_dev->ops->control(dma_dev,RT_DEVICE_CTRL_DMA_RELEASE_CHANNEL,(void *)&spi_control->dma.tx_trans);
  225. //dma_dev->ops->control(dma_dev,RT_DEVICE_CTRL_DMA_RELEASE_CHANNEL,(void *)&spi_control->dma.rx_trans);
  226. if(ret)
  227. {
  228. rt_kprintf("ERROR: %s, transfer timeout\n", __func__);
  229. return -RT_ETIMEOUT;
  230. }
  231. return RT_EOK;
  232. }
  233. rt_uint32_t xfer_data_isr(struct spi_controller *spi_control){
  234. int ret;
  235. struct fh_spi_obj *spi_obj;
  236. spi_obj = &spi_control->obj;
  237. SPI_SetTxLevel(spi_obj, SPI_FIFO_DEPTH / 2);
  238. SPI_EnableInterrupt(spi_obj, SPI_IRQ_TXEIM);
  239. ret = rt_completion_wait(&spi_control->transfer_completion, RT_TICK_PER_SECOND*50);
  240. if(ret)
  241. {
  242. rt_kprintf("ERROR: %s, transfer timeout\n", __func__);
  243. return -RT_ETIMEOUT;
  244. }
  245. return RT_EOK;
  246. }
  247. void fix_spi_xfer_mode(struct spi_controller *spi_control){
  248. //switch dma or isr....first check dma ...is error .use isr xfer...
  249. struct rt_dma_device * rt_dma_dev;
  250. struct dma_transfer *tx_trans;
  251. struct dma_transfer *rx_trans;
  252. int ret;
  253. //retry to check if the dma status...
  254. if(spi_control->dma.dma_flag == DMA_BIND_OK){
  255. //if transfer data too short...use isr..
  256. if(spi_control->current_message->length < DMA_OR_ISR_THRESHOLD){
  257. spi_control->xfer_mode = XFER_USE_ISR;
  258. return;
  259. }
  260. #if(0)
  261. rt_dma_dev = spi_control->dma.dma_dev;
  262. //first request channel
  263. tx_trans = &spi_control->dma.tx_trans;
  264. rx_trans = &spi_control->dma.rx_trans;
  265. tx_trans->channel_number = TX_DMA_CHANNEL;
  266. rx_trans->channel_number = RX_DMA_CHANNEL;
  267. ret = rt_dma_dev->ops->control(rt_dma_dev,RT_DEVICE_CTRL_DMA_REQUEST_CHANNEL,(void *)tx_trans);
  268. if(ret != RT_EOK){
  269. spi_control->xfer_mode = XFER_USE_ISR;
  270. return;
  271. }
  272. ret = rt_dma_dev->ops->control(rt_dma_dev,RT_DEVICE_CTRL_DMA_REQUEST_CHANNEL,(void *)rx_trans);
  273. if(ret != RT_EOK){
  274. //release tx channel...
  275. rt_dma_dev->ops->control(rt_dma_dev,RT_DEVICE_CTRL_DMA_RELEASE_CHANNEL,(void *)&tx_trans);
  276. spi_control->xfer_mode = XFER_USE_ISR;
  277. return;
  278. }
  279. #endif
  280. spi_control->xfer_mode = XFER_USE_DMA;
  281. //if error use isr mode
  282. }
  283. else
  284. spi_control->xfer_mode = XFER_USE_ISR;
  285. }
  286. static rt_uint32_t fh_spi_xfer(struct rt_spi_device* device, struct rt_spi_message* message)
  287. {
  288. struct spi_slave_info *spi_slave;
  289. struct spi_controller *spi_control;
  290. struct fh_spi_obj *spi_obj;
  291. int ret;
  292. rt_uint32_t slave_id;
  293. spi_slave = ( struct spi_slave_info *)fh_get_spi_dev_pri_data(device);
  294. spi_control = spi_slave->control;
  295. spi_obj = &spi_control->obj;
  296. spi_control->transfered_len = 0;
  297. spi_control->received_len = 0;
  298. rt_sem_take(&spi_control->xfer_lock, RT_WAITING_FOREVER);
  299. rt_completion_init(&spi_control->transfer_completion);
  300. spi_control->current_message = message;
  301. /* take CS */
  302. if(message->cs_take)
  303. {
  304. if(spi_slave->plat_slave.actice_level == ACTIVE_LOW)
  305. gpio_direction_output(spi_slave->plat_slave.cs_pin, 0);
  306. else
  307. gpio_direction_output(spi_slave->plat_slave.cs_pin, 1);
  308. //here will always use the slave_0 because that the cs is gpio...
  309. SPI_EnableSlaveen(spi_obj, 0);
  310. }
  311. //fix transfer mode .....
  312. fix_spi_xfer_mode(spi_control);
  313. switch(spi_control->xfer_mode){
  314. case XFER_USE_DMA:
  315. PRINT_SPI_DBG("use dma xfer.....###############\n");
  316. ret = xfer_data_dma(spi_control);
  317. if(ret == RT_EOK){
  318. break;
  319. }
  320. else{
  321. //use the isr mode to transfer
  322. spi_control->xfer_mode = XFER_USE_ISR;
  323. rt_kprintf("%s dma transfer error no:%x\n",__func__,ret);
  324. }
  325. case XFER_USE_ISR:
  326. PRINT_SPI_DBG("use isr xfer.....&&&&&&&&&&&&&\n");
  327. ret = xfer_data_isr(spi_control);
  328. if(ret != RT_EOK)
  329. rt_kprintf("%s isr transfer error no:%x\n",__func__,ret);
  330. break;
  331. default:
  332. rt_kprintf("%s unknow xfer func...\n",__func__);
  333. while(1)
  334. ;
  335. }
  336. /* release CS */
  337. if(message->cs_release)
  338. {
  339. if(spi_slave->plat_slave.actice_level == ACTIVE_LOW)
  340. gpio_direction_output(spi_slave->plat_slave.cs_pin, 1);
  341. else
  342. gpio_direction_output(spi_slave->plat_slave.cs_pin, 0);
  343. SPI_DisableSlaveen(spi_obj, 0);
  344. }
  345. rt_sem_release(&spi_control->xfer_lock);
  346. PRINT_SPI_DBG("%s end\n", __func__);
  347. return message->length;
  348. }
  349. static struct rt_spi_ops fh_spi_ops =
  350. {
  351. .configure = fh_spi_configure,
  352. .xfer = fh_spi_xfer,
  353. };
  354. static void fh_spi_interrupt(int irq, void *param)
  355. {
  356. struct spi_controller *spi_control;
  357. struct fh_spi_obj *spi_obj;
  358. spi_control = (struct spi_controller *)param;
  359. spi_obj = &spi_control->obj;
  360. rt_uint32_t rx_fifo_capability,tx_fifo_capability;
  361. rt_uint8_t data = 0;
  362. rt_uint8_t *p;
  363. rt_uint32_t status;
  364. //
  365. if(spi_control->current_message == RT_NULL){
  366. rt_kprintf("ERROR: %s, current_message is incorrect\n", __func__);
  367. }
  368. status = SPI_InterruptStatus(spi_obj);
  369. PRINT_SPI_DBG("status: 0x%x\n", status);
  370. //fixme: ??recv overflow, underflow; tran overflow??
  371. if(status & SPI_ISR_ERROR){
  372. rt_kprintf("ERROR: %s, status=%d\n", __func__, status);
  373. SPI_ClearInterrupt(spi_obj);
  374. //fixme: handle error
  375. return;
  376. }
  377. rx_fifo_capability = SPI_ReadRxFifoLevel(spi_obj);
  378. tx_fifo_capability = MIN(
  379. (SPI_FIFO_DEPTH - SPI_ReadTxFifoLevel(spi_obj)) / 2,
  380. (spi_control->current_message->length - spi_control->transfered_len));
  381. PRINT_SPI_DBG("rx_fifo_capability=%d\n", rx_fifo_capability);
  382. //rx
  383. spi_control->received_len += rx_fifo_capability;
  384. while(rx_fifo_capability)
  385. {
  386. data = SPI_ReadData(spi_obj);
  387. if(spi_control->current_message->recv_buf){
  388. *(rt_uint8_t *)spi_control->current_message->recv_buf++ = data;
  389. }
  390. PRINT_SPI_DBG("rx, data: 0x%x\n", data);
  391. //rt_kprintf("rx, data: 0x%x\n", data);
  392. rx_fifo_capability--;
  393. }
  394. if(spi_control->received_len == spi_control->current_message->length)
  395. {
  396. //rt_kprintf("asdasdq4902834908dklfkldjsdhgkljshfgljkhsgfkljhsdfkljghklj");
  397. SPI_DisableInterrupt(spi_obj, SPI_ISR_FLAG);
  398. PRINT_SPI_DBG("finished, length=%d, received_len=%d\n", spi_control->current_message->length, spi_control->received_len);
  399. rt_completion_done(&spi_control->transfer_completion);
  400. return;
  401. }
  402. //tx
  403. spi_control->transfered_len +=tx_fifo_capability;
  404. if(spi_control->current_message->send_buf){
  405. p = (rt_uint8_t *)spi_control->current_message->send_buf;
  406. while(tx_fifo_capability){
  407. PRINT_SPI_DBG("tx, data: 0x%x\n", *p);
  408. //rt_kprintf("tx, data: 0x%x\n", *p);
  409. SPI_WriteData(spi_obj, *p++);
  410. tx_fifo_capability--;
  411. }
  412. spi_control->current_message->send_buf = p;
  413. }
  414. else{
  415. while(tx_fifo_capability){
  416. SPI_WriteData(spi_obj, 0xff);
  417. tx_fifo_capability--;
  418. }
  419. }
  420. }
  421. int fh_spi_probe(void *priv_data)
  422. {
  423. char spi_dev_name[20] = {0};
  424. char spi_bus_name[20] = {0};
  425. char spi_isr_name[20] = {0};
  426. char spi_lock_name[20] = {0};
  427. struct spi_slave_info *spi_slave;
  428. struct spi_slave_info *next_slave;
  429. struct spi_slave_info **control_slave;
  430. struct spi_controller *spi_control;
  431. struct spi_control_platform_data *plat_data;
  432. int i,ret;
  433. struct rt_dma_device * rt_dma_dev;
  434. struct dma_transfer *tx_trans;
  435. struct dma_transfer *rx_trans;
  436. //check data...
  437. plat_data = (struct spi_control_platform_data *)priv_data;
  438. if(!plat_data){
  439. rt_kprintf("ERROR:platform data null...\n");
  440. return -RT_ENOMEM;
  441. }
  442. if(plat_data->slave_no > FH_SPI_SLAVE_MAX_NO){
  443. rt_kprintf("ERROR:spi controller not support %d slave..\n",plat_data->slave_no);
  444. return -RT_ENOMEM;
  445. }
  446. //malloc data
  447. spi_control = (struct spi_controller*)rt_malloc(sizeof(struct spi_controller));
  448. if(!spi_control){
  449. rt_kprintf("ERROR:no mem for malloc the spi controller..\n");
  450. goto error_malloc_bus;
  451. }
  452. rt_memset(spi_control, 0, sizeof(struct spi_controller));
  453. //parse platform control data
  454. spi_control->base = plat_data->base;
  455. spi_control->id = plat_data->id;
  456. spi_control->irq = plat_data->irq;
  457. spi_control->max_hz = plat_data->max_hz;
  458. spi_control->slave_no = plat_data->slave_no;
  459. spi_control->obj.base = plat_data->base;
  460. spi_control->clk_in = plat_data->clk_in;
  461. spi_control->plat_data = plat_data;
  462. rt_sprintf(spi_lock_name, "%s%d", "spi_lock", spi_control->id);
  463. rt_sem_init(&spi_control->xfer_lock, spi_lock_name, 1, RT_IPC_FLAG_FIFO);
  464. rt_sprintf(spi_bus_name, "%s%d", "spi_bus", spi_control->id);
  465. ret = rt_spi_bus_register(&spi_control->spi_bus, spi_bus_name, &fh_spi_ops);
  466. PRINT_SPI_DBG("bus name is :%s\n",spi_bus_name);
  467. //isr...
  468. rt_sprintf(spi_isr_name, "%s%d", "ssi_isr", spi_control->id);
  469. rt_hw_interrupt_install(spi_control->irq, fh_spi_interrupt,
  470. (void *)spi_control, spi_isr_name);
  471. rt_hw_interrupt_umask(spi_control->irq);
  472. PRINT_SPI_DBG("isr name is :%s\n",spi_isr_name);
  473. //check dma ....
  474. if(plat_data->transfer_mode == USE_DMA_TRANSFER){
  475. spi_control->dma.dma_dev = (struct rt_dma_device *)rt_device_find(plat_data->dma_name);
  476. if(spi_control->dma.dma_dev == RT_NULL){
  477. rt_kprintf("can't find dma dev\n");
  478. //goto error_malloc_slave;
  479. //spi_control->dma_xfer_flag = USE_ISR_TRANSFER;
  480. // spi_control->dma.dma_flag = DMA_BIND_ERROR;
  481. // spi_control->xfer_mode = XFER_USE_ISR;
  482. goto BIND_DMA_ERROR;
  483. }
  484. else{
  485. spi_control->dma.control = spi_control;
  486. spi_control->dma.rx_hs = plat_data->rx_hs_no;
  487. spi_control->dma.tx_hs = plat_data->tx_hs_no;
  488. spi_control->dma.dma_name = plat_data->dma_name;
  489. spi_control->dma.rx_dummy_buff = fh_dma_mem_malloc(MALLOC_DMA_MEM_SIZE);
  490. if(!spi_control->dma.rx_dummy_buff){
  491. rt_kprintf("malloc rx dma buff failed...\n");
  492. //spi_control->xfer_mode = XFER_USE_ISR;
  493. goto BIND_DMA_ERROR;
  494. }
  495. spi_control->dma.tx_dummy_buff = fh_dma_mem_malloc(MALLOC_DMA_MEM_SIZE);
  496. if(!spi_control->dma.tx_dummy_buff){
  497. rt_kprintf("malloc tx dma buff failed...\n");
  498. fh_dma_mem_free(spi_control->dma.rx_dummy_buff);
  499. //spi_control->xfer_mode = XFER_USE_ISR;
  500. goto BIND_DMA_ERROR;
  501. }
  502. if(((rt_uint32_t)spi_control->dma.tx_dummy_buff % 4)||((rt_uint32_t)spi_control->dma.rx_dummy_buff % 4)){
  503. rt_kprintf("dma malloc buff not allign..\n");
  504. fh_dma_mem_free(spi_control->dma.rx_dummy_buff);
  505. fh_dma_mem_free(spi_control->dma.tx_dummy_buff);
  506. goto BIND_DMA_ERROR;
  507. }
  508. //open dma dev.
  509. spi_control->dma.dma_dev->ops->control(spi_control->dma.dma_dev,RT_DEVICE_CTRL_DMA_OPEN,RT_NULL);
  510. //request channel
  511. rt_dma_dev = spi_control->dma.dma_dev;
  512. //first request channel
  513. tx_trans = &spi_control->dma.tx_trans;
  514. rx_trans = &spi_control->dma.rx_trans;
  515. tx_trans->channel_number = TX_DMA_CHANNEL;
  516. rx_trans->channel_number = RX_DMA_CHANNEL;
  517. ret = rt_dma_dev->ops->control(rt_dma_dev,RT_DEVICE_CTRL_DMA_REQUEST_CHANNEL,(void *)tx_trans);
  518. if(ret != RT_EOK){
  519. goto BIND_DMA_ERROR;
  520. }
  521. ret = rt_dma_dev->ops->control(rt_dma_dev,RT_DEVICE_CTRL_DMA_REQUEST_CHANNEL,(void *)rx_trans);
  522. if(ret != RT_EOK){
  523. //release tx channel...
  524. rt_dma_dev->ops->control(rt_dma_dev,RT_DEVICE_CTRL_DMA_RELEASE_CHANNEL,(void *)&tx_trans);
  525. goto BIND_DMA_ERROR;
  526. }
  527. //spi_control->xfer_mode = XFER_USE_DMA;
  528. spi_control->dma.dma_flag = DMA_BIND_OK;
  529. }
  530. }
  531. else{
  532. BIND_DMA_ERROR:
  533. spi_control->dma.dma_flag = DMA_BIND_ERROR;
  534. //spi_control->xfer_mode = XFER_USE_ISR;
  535. }
  536. control_slave = &spi_control->spi_slave;
  537. for(i=0;i<plat_data->slave_no;i++){
  538. spi_slave = (struct spi_slave_info*)rt_malloc(sizeof(struct spi_slave_info));
  539. if(!spi_slave){
  540. rt_kprintf("ERROR:no mem for malloc the spi_slave%d..\n",i);
  541. goto error_malloc_slave;
  542. }
  543. rt_memset(spi_slave, 0, sizeof(struct spi_slave_info));
  544. //parse platform data...
  545. spi_slave->id = i;
  546. //bind to the spi control....will easy to find all the data...
  547. spi_slave->control = spi_control;
  548. spi_slave->plat_slave.cs_pin = plat_data->plat_slave[i].cs_pin;
  549. spi_slave->plat_slave.actice_level = plat_data->plat_slave[i].actice_level;
  550. rt_sprintf(spi_dev_name, "%s%d%s%d", "ssi", spi_control->id,"_",spi_slave->id);
  551. *control_slave = spi_slave;
  552. control_slave = &spi_slave->next;
  553. //register slave dev...
  554. ret = rt_spi_bus_attach_device(&spi_slave->spi_device,spi_dev_name,spi_bus_name,spi_slave);
  555. if(ret != RT_EOK){
  556. rt_kprintf("register dev to bus failed...\n");
  557. goto error_malloc_slave;
  558. }
  559. }
  560. //request gpio...
  561. spi_slave = spi_control->spi_slave;
  562. while(spi_slave != RT_NULL)
  563. {
  564. next_slave = spi_slave->next;
  565. ret = gpio_request(spi_slave->plat_slave.cs_pin);
  566. if(ret!=0){
  567. rt_kprintf("request gpio_%d failed...\n",spi_slave->plat_slave.cs_pin);
  568. goto error_malloc_slave;
  569. }
  570. PRINT_SPI_DBG("spi_slave info addr:%x,id:%d,cs:%d,active:%d\n",(rt_uint32_t)spi_slave, spi_slave->id,
  571. spi_slave->plat_slave.cs_pin,
  572. spi_slave->plat_slave.actice_level);
  573. spi_slave = next_slave;
  574. }
  575. //this will be used in platform exit..
  576. plat_data->control = spi_control;
  577. return RT_EOK;
  578. error_malloc_slave:
  579. //free the slaveinfo already malloc
  580. spi_slave = spi_control->spi_slave;
  581. while(spi_slave != RT_NULL)
  582. {
  583. next_slave = spi_slave->next;
  584. gpio_release(spi_slave->plat_slave.cs_pin);
  585. rt_free(spi_slave);
  586. spi_slave = next_slave;
  587. }
  588. //mask isr
  589. rt_hw_interrupt_mask(spi_control->irq);
  590. //release sem ..
  591. rt_sem_detach(&spi_control->xfer_lock);
  592. //free the control malloc .
  593. rt_free(spi_control);
  594. //fixme:unregister spi_bus...
  595. error_malloc_bus:
  596. return -RT_ENOMEM;
  597. }
  598. int fh_spi_exit(void *priv_data)
  599. {
  600. struct spi_controller *spi_control;
  601. struct spi_control_platform_data *plat_data;
  602. struct spi_slave_info *spi_slave;
  603. struct spi_slave_info *next_slave;
  604. plat_data = (struct spi_control_platform_data *)priv_data;
  605. spi_control = plat_data->control;
  606. spi_slave = spi_control->spi_slave;
  607. while(spi_slave != RT_NULL)
  608. {
  609. next_slave = spi_slave->next;
  610. gpio_release(spi_slave->plat_slave.cs_pin);
  611. rt_free(spi_slave);
  612. spi_slave = next_slave;
  613. }
  614. //mask isr
  615. rt_hw_interrupt_mask(spi_control->irq);
  616. //release sem ..
  617. rt_sem_detach(&spi_control->xfer_lock);
  618. //free the control malloc .
  619. rt_free(spi_control);
  620. //fixme free all the malloc data ...
  621. return 0;
  622. }
  623. struct fh_board_ops spi_driver_ops =
  624. {
  625. .probe = fh_spi_probe,
  626. .exit = fh_spi_exit,
  627. };
  628. void rt_hw_spi_init(void)
  629. {
  630. int ret;
  631. // rt_kprintf("%s start\n", __func__);
  632. PRINT_SPI_DBG("%s start\n", __func__);
  633. fh_board_driver_register("spi", &spi_driver_ops);
  634. PRINT_SPI_DBG("%s end\n", __func__);
  635. //fixme: never release?
  636. }
  637. #if(0)
  638. #define TEST_SPI_BUFF_SIZE 0x100
  639. static rt_uint8_t tx_buf[TEST_SPI_BUFF_SIZE] = {0};
  640. static rt_uint8_t rx_buf[TEST_SPI_BUFF_SIZE] = {0};
  641. int ssi_test(void){
  642. struct rt_spi_device * rt_spi_device;
  643. int ret;
  644. rt_spi_device = (struct rt_spi_device *)rt_device_find("ssi1_0");
  645. if(rt_spi_device == RT_NULL)
  646. {
  647. rt_kprintf("%s spi device %s not found!\r\n",__func__ ,"ssi1_0");
  648. return -RT_ENOSYS;
  649. }
  650. /* config spi */
  651. {
  652. struct rt_spi_configuration cfg;
  653. cfg.data_width = 8;
  654. cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0 and Mode 3 */
  655. cfg.max_hz = 50 * 1000 * 1000; /* 50M */
  656. rt_spi_configure(rt_spi_device, &cfg);
  657. }
  658. rt_memset(tx_buf,0x55,TEST_SPI_BUFF_SIZE);
  659. rt_spi_transfer(rt_spi_device,tx_buf,rx_buf,TEST_SPI_BUFF_SIZE);
  660. ret = rt_memcmp(tx_buf,rx_buf,TEST_SPI_BUFF_SIZE);
  661. if(ret != 0){
  662. rt_kprintf("compare error ..error data %x\n",ret);
  663. }
  664. rt_kprintf("test done \n");
  665. return 0;
  666. }
  667. #ifdef RT_USING_FINSH
  668. #include <finsh.h>
  669. FINSH_FUNCTION_EXPORT(ssi_test, fh_ssi_test);
  670. #endif
  671. #endif