fc8150_spi.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. /*****************************************************************************
  2. Copyright(c) 2012 FCI Inc. All Rights Reserved
  3. File name : fc8150_spi.c
  4. Description : fc8150 host interface
  5. *******************************************************************************/
  6. #include <linux/module.h>
  7. #include <linux/spi/spi.h>
  8. #include <linux/slab.h>
  9. #include "fci_types.h"
  10. #include "fc8150_regs.h"
  11. #include "fci_oal.h"
  12. #define SPI_BMODE 0x00
  13. #define SPI_WMODE 0x10
  14. #define SPI_LMODE 0x20
  15. #define SPI_READ 0x40
  16. #define SPI_WRITE 0x00
  17. #define SPI_AINC 0x80
  18. #define CHIPID (0 << 3)
  19. #define DRIVER_NAME "fc8150_spi"
  20. #define DMA_OFFSET_ALIGN 64
  21. struct spi_device *fc8150_spi;
  22. static u8 tx_data[10];
  23. static u8 rdata_buf[8192];
  24. static u8 wdata_buf[8192];
  25. static DEFINE_MUTEX(lock);
  26. static int __devinit fc8150_spi_probe(struct spi_device *spi)
  27. {
  28. s32 ret;
  29. PRINTF(0, "(SJINU) fc8150_spi_probe\n");
  30. spi->max_speed_hz = 24000000;
  31. spi->bits_per_word = 8;
  32. spi->mode = SPI_MODE_0;
  33. ret = spi_setup(spi);
  34. if (ret < 0)
  35. return ret;
  36. fc8150_spi = spi;
  37. return ret;
  38. }
  39. static int fc8150_spi_remove(struct spi_device *spi)
  40. {
  41. return 0;
  42. }
  43. static struct spi_driver fc8150_spi_driver = {
  44. .driver = {
  45. .name = DRIVER_NAME,
  46. .owner = THIS_MODULE,
  47. },
  48. .probe = fc8150_spi_probe,
  49. .remove = __devexit_p(fc8150_spi_remove),
  50. };
  51. static int fc8150_spi_write_then_read(struct spi_device *spi
  52. , u8 *txbuf, u16 tx_length, u8 *rxbuf, u16 rx_length)
  53. {
  54. int res = 0;
  55. int offsetRx =0, offsetTx = 0;
  56. struct spi_message message;
  57. struct spi_transfer x;
  58. spi_message_init(&message);
  59. memset(&x, 0, sizeof x);
  60. spi_message_add_tail(&x, &message);
  61. offsetRx = DMA_OFFSET_ALIGN - (((unsigned int)&rdata_buf[0]) % DMA_OFFSET_ALIGN);
  62. offsetTx = DMA_OFFSET_ALIGN - (((unsigned int)&wdata_buf[0]) % DMA_OFFSET_ALIGN);
  63. memcpy(&wdata_buf[offsetTx], txbuf, tx_length);
  64. x.tx_buf = &wdata_buf[offsetTx];
  65. x.rx_buf = &rdata_buf[offsetRx];
  66. // PRINTF(0, "(SJINU %s) wdatabuf = %x, rdatabuf = %x\n", __func__, &wdata_buf[offsetTx], &rdata_buf[offsetRx]);
  67. x.len = tx_length + rx_length;
  68. x.cs_change = 0;
  69. x.bits_per_word = 8;
  70. res = spi_sync(spi, &message);
  71. memcpy(rxbuf, x.rx_buf + tx_length, rx_length);
  72. return res;
  73. }
  74. static int spi_bulkread(HANDLE hDevice, u16 addr
  75. , u8 command, u8 *data, u16 length)
  76. {
  77. int res;
  78. tx_data[0] = addr & 0xff;
  79. tx_data[1] = (addr >> 8) & 0xff;
  80. tx_data[2] = (command & 0xf0) | CHIPID | ((length >> 16) & 0x07);
  81. tx_data[3] = (length >> 8) & 0xff;
  82. tx_data[4] = length & 0xff;
  83. res = fc8150_spi_write_then_read(fc8150_spi, &tx_data[0]
  84. , 5, data, length);
  85. if (res) {
  86. PRINTF(0, "fc8150_spi_bulkread fail : %d\n", res);
  87. return BBM_NOK;
  88. }
  89. return BBM_OK;
  90. }
  91. static int spi_bulkwrite(HANDLE hDevice, u16 addr
  92. , u8 command, u8 *data, u16 length)
  93. {
  94. int i;
  95. int res;
  96. tx_data[0] = addr & 0xff;
  97. tx_data[1] = (addr >> 8) & 0xff;
  98. tx_data[2] = (command & 0xf0) | CHIPID | ((length >> 16) & 0x07);
  99. tx_data[3] = (length >> 8) & 0xff;
  100. tx_data[4] = length & 0xff;
  101. for (i = 0; i < length; i++)
  102. tx_data[5+i] = data[i];
  103. res = fc8150_spi_write_then_read(fc8150_spi
  104. , &tx_data[0], length+5, NULL, 0);
  105. if (res) {
  106. PRINTF(0, "fc8150_spi_bulkwrite fail : %d\n", res);
  107. return BBM_NOK;
  108. }
  109. return BBM_OK;
  110. }
  111. static int spi_dataread(HANDLE hDevice, u16 addr
  112. , u8 command, u8 *data, u32 length)
  113. {
  114. int res;
  115. tx_data[0] = addr & 0xff;
  116. tx_data[1] = (addr >> 8) & 0xff;
  117. tx_data[2] = (command & 0xf0) | CHIPID | ((length >> 16) & 0x07);
  118. tx_data[3] = (length >> 8) & 0xff;
  119. tx_data[4] = length & 0xff;
  120. res = fc8150_spi_write_then_read(fc8150_spi
  121. , &tx_data[0], 5, data, length);
  122. if (res) {
  123. PRINTF(0, "(SJINU) fc8150_spi_dataread fail : %d\n", res);
  124. return BBM_NOK;
  125. }
  126. return BBM_OK;
  127. }
  128. int fc8150_spi_init(HANDLE hDevice, u16 param1, u16 param2)
  129. {
  130. int res = 0;
  131. PRINTF(0, "fc8150_spi_init : %d\n", res);
  132. res = spi_register_driver(&fc8150_spi_driver);
  133. if (res) {
  134. PRINTF(0, "fc8150_spi register fail : %d\n", res);
  135. return BBM_NOK;
  136. }
  137. return res;
  138. }
  139. int fc8150_spi_byteread(HANDLE hDevice, u16 addr, u8 *data)
  140. {
  141. int res;
  142. u8 command = SPI_READ;
  143. mutex_lock(&lock);
  144. res = spi_bulkread(hDevice, addr, command, data, 1);
  145. mutex_unlock(&lock);
  146. return res;
  147. }
  148. int fc8150_spi_wordread(HANDLE hDevice, u16 addr, u16 *data)
  149. {
  150. int res;
  151. u8 command = SPI_READ | SPI_AINC;
  152. mutex_lock(&lock);
  153. res = spi_bulkread(hDevice, addr, command, (u8 *)data, 2);
  154. mutex_unlock(&lock);
  155. // PRINTF(0, "(SJINU) fc8150_spi_wordread : value=%x res=%d\n", *data, res);
  156. return res;
  157. }
  158. int fc8150_spi_longread(HANDLE hDevice, u16 addr, u32 *data)
  159. {
  160. int res;
  161. u8 command = SPI_READ | SPI_AINC;
  162. mutex_lock(&lock);
  163. res = spi_bulkread(hDevice, addr, command, (u8 *)data, 4);
  164. mutex_unlock(&lock);
  165. return res;
  166. }
  167. int fc8150_spi_bulkread(HANDLE hDevice, u16 addr, u8 *data, u16 length)
  168. {
  169. int res;
  170. u8 command = SPI_READ | SPI_AINC;
  171. mutex_lock(&lock);
  172. res = spi_bulkread(hDevice, addr, command, data, length);
  173. mutex_unlock(&lock);
  174. return res;
  175. }
  176. int fc8150_spi_bytewrite(HANDLE hDevice, u16 addr, u8 data)
  177. {
  178. int res;
  179. u8 command = SPI_WRITE;
  180. mutex_lock(&lock);
  181. res = spi_bulkwrite(hDevice, addr, command, (u8 *)&data, 1);
  182. mutex_unlock(&lock);
  183. return res;
  184. }
  185. int fc8150_spi_wordwrite(HANDLE hDevice, u16 addr, u16 data)
  186. {
  187. int res;
  188. u8 command = SPI_WRITE | SPI_AINC;
  189. mutex_lock(&lock);
  190. res = spi_bulkwrite(hDevice, addr, command, (u8 *)&data, 2);
  191. mutex_unlock(&lock);
  192. // PRINTF(0, "(SJINU) fc8150_spi_wordwrite : %d\n", res);
  193. return res;
  194. }
  195. int fc8150_spi_longwrite(HANDLE hDevice, u16 addr, u32 data)
  196. {
  197. int res;
  198. u8 command = SPI_WRITE | SPI_AINC;
  199. mutex_lock(&lock);
  200. res = spi_bulkwrite(hDevice, addr, command, (u8 *)&data, 4);
  201. mutex_unlock(&lock);
  202. return res;
  203. }
  204. int fc8150_spi_bulkwrite(HANDLE hDevice, u16 addr, u8 *data, u16 length)
  205. {
  206. int res;
  207. u8 command = SPI_WRITE | SPI_AINC;
  208. mutex_lock(&lock);
  209. res = spi_bulkwrite(hDevice, addr, command, data, length);
  210. mutex_unlock(&lock);
  211. return res;
  212. }
  213. int fc8150_spi_dataread(HANDLE hDevice, u16 addr, u8 *data, u32 length)
  214. {
  215. int res;
  216. u8 command = SPI_READ;
  217. // PRINTF(0, "(SJINU) %s entered\n", __func__);
  218. mutex_lock(&lock);
  219. res = spi_dataread(hDevice, addr, command, data, length);
  220. mutex_unlock(&lock);
  221. return res;
  222. }
  223. int fc8150_spi_deinit(HANDLE hDevice)
  224. {
  225. return BBM_OK;
  226. }