fc8080_spi.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. /*****************************************************************************
  2. Copyright(c) 2013 FCI Inc. All Rights Reserved
  3. File name : fc8080_spi.c
  4. Description : spi interface source file
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. History :
  17. ----------------------------------------------------------------------
  18. *******************************************************************************/
  19. #include <linux/input.h>
  20. #include <linux/spi/spi.h>
  21. #include <linux/cache.h>
  22. #include "fci_types.h"
  23. #include "fc8080_regs.h"
  24. #include "fci_oal.h"
  25. #include "fc8080_spi.h"
  26. #include "tdmb.h"
  27. #define SPI_BMODE 0x00
  28. #define SPI_WMODE 0x04
  29. #define SPI_LMODE 0x08
  30. #define SPI_RD_THRESH 0x30
  31. #define SPI_RD_REG 0x20
  32. #define SPI_READ 0x40
  33. #define SPI_WRITE 0x00
  34. #define SPI_AINC 0x80
  35. #define CHIPID 0
  36. #define DRIVER_NAME "fc8080_spi"
  37. u32 fc8080_spi;
  38. static u8 tx_data[32] __cacheline_aligned;
  39. static DEFINE_MUTEX(lock);
  40. int fc8080_spi_write_then_read(
  41. struct spi_device *spi
  42. , u8 *txbuf
  43. , u16 tx_length
  44. , u8 *rxbuf
  45. , u16 rx_length)
  46. {
  47. s32 res;
  48. struct spi_message message;
  49. struct spi_transfer x;
  50. spi_message_init(&message);
  51. memset(&x, 0, sizeof x);
  52. spi_message_add_tail(&x, &message);
  53. x.tx_buf = txbuf;
  54. x.rx_buf = txbuf;
  55. x.len = tx_length + rx_length;
  56. res = spi_sync(spi, &message);
  57. memcpy(rxbuf, x.rx_buf + tx_length, rx_length);
  58. return res;
  59. }
  60. int fc8080_spi_write_then_burstread(
  61. struct spi_device *spi
  62. , u8 *txbuf
  63. , u16 tx_length
  64. , u8 *rxbuf
  65. , u16 rx_length)
  66. {
  67. s32 res;
  68. struct spi_message message;
  69. struct spi_transfer x;
  70. spi_message_init(&message);
  71. memset(&x, 0, sizeof x);
  72. spi_message_add_tail(&x, &message);
  73. x.tx_buf = txbuf;
  74. x.rx_buf = rxbuf;
  75. x.len = tx_length + rx_length;
  76. res = spi_sync(spi, &message);
  77. return res;
  78. }
  79. static s32 spi_bulkread(HANDLE handle, u16 addr, u8 command, u8 *data,
  80. u16 length)
  81. {
  82. s32 res = BBM_OK;
  83. tx_data[0] = (u8) (addr & 0xff);
  84. tx_data[1] = (u8) ((addr >> 8) & 0xff);
  85. tx_data[2] = (u8) ((command & 0xfc) | CHIPID);
  86. tx_data[3] = (u8) (length & 0xff);
  87. res = fc8080_spi_write_then_read(
  88. (struct spi_device *)fc8080_spi, &tx_data[0], 4, &data[0], length);
  89. if (res) {
  90. print_log(0, "fc8080_spi_bulkread fail : %d\n", res);
  91. return BBM_NOK;
  92. }
  93. return BBM_OK;
  94. }
  95. static s32 spi_bulkwrite(HANDLE handle, u16 addr, u8 command, u8 *data,
  96. u16 length)
  97. {
  98. s32 res = BBM_OK;
  99. s32 i = 0;
  100. tx_data[0] = (u8) (addr & 0xff);
  101. tx_data[1] = (u8) ((addr >> 8) & 0xff);
  102. tx_data[2] = (u8) ((command & 0xfc) | CHIPID);
  103. tx_data[3] = (u8) (length & 0xff);
  104. for (i = 0; i < length; i++)
  105. tx_data[4+i] = data[i];
  106. res = fc8080_spi_write_then_read(
  107. (struct spi_device *)fc8080_spi, &tx_data[0], length+4, NULL, 0);
  108. if (res) {
  109. print_log(0, "fc8080_spi_bulkwrite fail : %d\n", res);
  110. return BBM_NOK;
  111. }
  112. return BBM_OK;
  113. }
  114. static s32 spi_dataread(HANDLE handle, u16 addr, u8 command, u8 *data,
  115. u32 length)
  116. {
  117. s32 res = BBM_OK;
  118. tx_data[0] = (u8) (addr & 0xff);
  119. tx_data[1] = (u8) ((addr >> 8) & 0xff);
  120. tx_data[2] = (u8) ((command & 0xfc) | CHIPID);
  121. tx_data[3] = (u8) (length & 0xff);
  122. res = fc8080_spi_write_then_burstread(
  123. (struct spi_device *)fc8080_spi, &tx_data[0], 4, &data[0], length);
  124. if (res) {
  125. print_log(0, "fc8080_spi_dataread fail : %d\n", res);
  126. return BBM_NOK;
  127. }
  128. return BBM_OK;
  129. }
  130. s32 fc8080_spi_init(HANDLE handle, u16 param1, u16 param2)
  131. {
  132. fc8080_spi = param2;
  133. fc8080_spi <<= 16;
  134. fc8080_spi |= param1;
  135. DPRINTK("%s : 0x%p\n", __func__, (struct spi_device *)fc8080_spi);
  136. return BBM_OK;
  137. }
  138. s32 fc8080_spi_byteread(HANDLE handle, u16 addr, u8 *data)
  139. {
  140. s32 res;
  141. u8 command = SPI_READ;
  142. mutex_lock(&lock);
  143. res = spi_bulkread(handle, addr, command, data, 1);
  144. mutex_unlock(&lock);
  145. return res;
  146. }
  147. s32 fc8080_spi_wordread(HANDLE handle, u16 addr, u16 *data)
  148. {
  149. s32 res;
  150. u8 command = SPI_READ | SPI_AINC;
  151. mutex_lock(&lock);
  152. res = spi_bulkread(handle, addr, command, (u8 *) data, 2);
  153. mutex_unlock(&lock);
  154. return res;
  155. }
  156. s32 fc8080_spi_longread(HANDLE handle, u16 addr, u32 *data)
  157. {
  158. s32 res;
  159. u8 command = SPI_READ | SPI_AINC;
  160. mutex_lock(&lock);
  161. res = spi_bulkread(handle, addr, command, (u8 *) data, 4);
  162. mutex_unlock(&lock);
  163. return res;
  164. }
  165. s32 fc8080_spi_bulkread(HANDLE handle, u16 addr, u8 *data, u16 length)
  166. {
  167. s32 i;
  168. u16 x, y;
  169. s32 res = BBM_OK;
  170. u8 command = SPI_READ | SPI_AINC;
  171. x = length / 255;
  172. y = length % 255;
  173. mutex_lock(&lock);
  174. for (i = 0; i < x; i++, addr += 255)
  175. res |= spi_bulkread(handle, addr, command, &data[i * 255], 255);
  176. if (y)
  177. res |= spi_bulkread(handle, addr, command, &data[x * 255], y);
  178. mutex_unlock(&lock);
  179. return res;
  180. }
  181. s32 fc8080_spi_bytewrite(HANDLE handle, u16 addr, u8 data)
  182. {
  183. s32 res;
  184. u8 command = SPI_WRITE;
  185. mutex_lock(&lock);
  186. res = spi_bulkwrite(handle, addr, command, (u8 *) &data, 1);
  187. mutex_unlock(&lock);
  188. return res;
  189. }
  190. s32 fc8080_spi_wordwrite(HANDLE handle, u16 addr, u16 data)
  191. {
  192. s32 res;
  193. u8 command = SPI_WRITE;
  194. if ((addr & 0xff00) != 0x0f00)
  195. command |= SPI_AINC;
  196. mutex_lock(&lock);
  197. res = spi_bulkwrite(handle, addr, command, (u8 *) &data, 2);
  198. mutex_unlock(&lock);
  199. return res;
  200. }
  201. s32 fc8080_spi_longwrite(HANDLE handle, u16 addr, u32 data)
  202. {
  203. s32 res;
  204. u8 command = SPI_WRITE | SPI_AINC;
  205. mutex_lock(&lock);
  206. res = spi_bulkwrite(handle, addr, command, (u8 *) &data, 4);
  207. mutex_unlock(&lock);
  208. return res;
  209. }
  210. s32 fc8080_spi_bulkwrite(HANDLE handle, u16 addr, u8 *data, u16 length)
  211. {
  212. s32 i;
  213. u16 x, y;
  214. s32 res = BBM_OK;
  215. u8 command = SPI_WRITE | SPI_AINC;
  216. x = length / 255;
  217. y = length % 255;
  218. mutex_lock(&lock);
  219. for (i = 0; i < x; i++, addr += 255)
  220. res |= spi_bulkwrite(handle, addr, command, &data[i * 255],
  221. 255);
  222. if (y)
  223. res |= spi_bulkwrite(handle, addr, command, &data[x * 255], y);
  224. mutex_unlock(&lock);
  225. return res;
  226. }
  227. s32 fc8080_spi_dataread(HANDLE handle, u16 addr, u8 *data, u32 length)
  228. {
  229. s32 res;
  230. u8 command = SPI_READ | SPI_RD_THRESH;
  231. mutex_lock(&lock);
  232. res = spi_dataread(handle, addr, command, data, length);
  233. mutex_unlock(&lock);
  234. return res;
  235. }
  236. s32 fc8080_spi_deinit(HANDLE handle)
  237. {
  238. fc8080_spi = 0;
  239. return BBM_OK;
  240. }