wl1271_spi.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /*
  2. * This file is part of wl1271
  3. *
  4. * Copyright (C) 2008-2009 Nokia Corporation
  5. *
  6. * Contact: Luciano Coelho <luciano.coelho@nokia.com>
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * version 2 as published by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20. * 02110-1301 USA
  21. *
  22. */
  23. #include <linux/module.h>
  24. #include <linux/platform_device.h>
  25. #include <linux/crc7.h>
  26. #include <linux/spi/spi.h>
  27. #include "wl1271.h"
  28. #include "wl12xx_80211.h"
  29. #include "wl1271_spi.h"
  30. void wl1271_spi_reset(struct wl1271 *wl)
  31. {
  32. u8 *cmd;
  33. struct spi_transfer t;
  34. struct spi_message m;
  35. cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
  36. if (!cmd) {
  37. wl1271_error("could not allocate cmd for spi reset");
  38. return;
  39. }
  40. memset(&t, 0, sizeof(t));
  41. spi_message_init(&m);
  42. memset(cmd, 0xff, WSPI_INIT_CMD_LEN);
  43. t.tx_buf = cmd;
  44. t.len = WSPI_INIT_CMD_LEN;
  45. spi_message_add_tail(&t, &m);
  46. spi_sync(wl->spi, &m);
  47. wl1271_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN);
  48. }
  49. void wl1271_spi_init(struct wl1271 *wl)
  50. {
  51. u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd;
  52. struct spi_transfer t;
  53. struct spi_message m;
  54. cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
  55. if (!cmd) {
  56. wl1271_error("could not allocate cmd for spi init");
  57. return;
  58. }
  59. memset(crc, 0, sizeof(crc));
  60. memset(&t, 0, sizeof(t));
  61. spi_message_init(&m);
  62. /*
  63. * Set WSPI_INIT_COMMAND
  64. * the data is being send from the MSB to LSB
  65. */
  66. cmd[2] = 0xff;
  67. cmd[3] = 0xff;
  68. cmd[1] = WSPI_INIT_CMD_START | WSPI_INIT_CMD_TX;
  69. cmd[0] = 0;
  70. cmd[7] = 0;
  71. cmd[6] |= HW_ACCESS_WSPI_INIT_CMD_MASK << 3;
  72. cmd[6] |= HW_ACCESS_WSPI_FIXED_BUSY_LEN & WSPI_INIT_CMD_FIXEDBUSY_LEN;
  73. if (HW_ACCESS_WSPI_FIXED_BUSY_LEN == 0)
  74. cmd[5] |= WSPI_INIT_CMD_DIS_FIXEDBUSY;
  75. else
  76. cmd[5] |= WSPI_INIT_CMD_EN_FIXEDBUSY;
  77. cmd[5] |= WSPI_INIT_CMD_IOD | WSPI_INIT_CMD_IP | WSPI_INIT_CMD_CS
  78. | WSPI_INIT_CMD_WSPI | WSPI_INIT_CMD_WS;
  79. crc[0] = cmd[1];
  80. crc[1] = cmd[0];
  81. crc[2] = cmd[7];
  82. crc[3] = cmd[6];
  83. crc[4] = cmd[5];
  84. cmd[4] |= crc7(0, crc, WSPI_INIT_CMD_CRC_LEN) << 1;
  85. cmd[4] |= WSPI_INIT_CMD_END;
  86. t.tx_buf = cmd;
  87. t.len = WSPI_INIT_CMD_LEN;
  88. spi_message_add_tail(&t, &m);
  89. spi_sync(wl->spi, &m);
  90. wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);
  91. }
  92. #define WL1271_BUSY_WORD_TIMEOUT 1000
  93. /* FIXME: Check busy words, removed due to SPI bug */
  94. #if 0
  95. static void wl1271_spi_read_busy(struct wl1271 *wl, void *buf, size_t len)
  96. {
  97. struct spi_transfer t[1];
  98. struct spi_message m;
  99. u32 *busy_buf;
  100. int num_busy_bytes = 0;
  101. wl1271_info("spi read BUSY!");
  102. /*
  103. * Look for the non-busy word in the read buffer, and if found,
  104. * read in the remaining data into the buffer.
  105. */
  106. busy_buf = (u32 *)buf;
  107. for (; (u32)busy_buf < (u32)buf + len; busy_buf++) {
  108. num_busy_bytes += sizeof(u32);
  109. if (*busy_buf & 0x1) {
  110. spi_message_init(&m);
  111. memset(t, 0, sizeof(t));
  112. memmove(buf, busy_buf, len - num_busy_bytes);
  113. t[0].rx_buf = buf + (len - num_busy_bytes);
  114. t[0].len = num_busy_bytes;
  115. spi_message_add_tail(&t[0], &m);
  116. spi_sync(wl->spi, &m);
  117. return;
  118. }
  119. }
  120. /*
  121. * Read further busy words from SPI until a non-busy word is
  122. * encountered, then read the data itself into the buffer.
  123. */
  124. wl1271_info("spi read BUSY-polling needed!");
  125. num_busy_bytes = WL1271_BUSY_WORD_TIMEOUT;
  126. busy_buf = wl->buffer_busyword;
  127. while (num_busy_bytes) {
  128. num_busy_bytes--;
  129. spi_message_init(&m);
  130. memset(t, 0, sizeof(t));
  131. t[0].rx_buf = busy_buf;
  132. t[0].len = sizeof(u32);
  133. spi_message_add_tail(&t[0], &m);
  134. spi_sync(wl->spi, &m);
  135. if (*busy_buf & 0x1) {
  136. spi_message_init(&m);
  137. memset(t, 0, sizeof(t));
  138. t[0].rx_buf = buf;
  139. t[0].len = len;
  140. spi_message_add_tail(&t[0], &m);
  141. spi_sync(wl->spi, &m);
  142. return;
  143. }
  144. }
  145. /* The SPI bus is unresponsive, the read failed. */
  146. memset(buf, 0, len);
  147. wl1271_error("SPI read busy-word timeout!\n");
  148. }
  149. #endif
  150. void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf,
  151. size_t len, bool fixed)
  152. {
  153. struct spi_transfer t[3];
  154. struct spi_message m;
  155. u32 *busy_buf;
  156. u32 *cmd;
  157. cmd = &wl->buffer_cmd;
  158. busy_buf = wl->buffer_busyword;
  159. *cmd = 0;
  160. *cmd |= WSPI_CMD_READ;
  161. *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
  162. *cmd |= addr & WSPI_CMD_BYTE_ADDR;
  163. if (fixed)
  164. *cmd |= WSPI_CMD_FIXED;
  165. spi_message_init(&m);
  166. memset(t, 0, sizeof(t));
  167. t[0].tx_buf = cmd;
  168. t[0].len = 4;
  169. spi_message_add_tail(&t[0], &m);
  170. /* Busy and non busy words read */
  171. t[1].rx_buf = busy_buf;
  172. t[1].len = WL1271_BUSY_WORD_LEN;
  173. spi_message_add_tail(&t[1], &m);
  174. t[2].rx_buf = buf;
  175. t[2].len = len;
  176. spi_message_add_tail(&t[2], &m);
  177. spi_sync(wl->spi, &m);
  178. /* FIXME: Check busy words, removed due to SPI bug */
  179. /* if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1))
  180. wl1271_spi_read_busy(wl, buf, len); */
  181. wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd));
  182. wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);
  183. }
  184. void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf,
  185. size_t len, bool fixed)
  186. {
  187. struct spi_transfer t[2];
  188. struct spi_message m;
  189. u32 *cmd;
  190. cmd = &wl->buffer_cmd;
  191. *cmd = 0;
  192. *cmd |= WSPI_CMD_WRITE;
  193. *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
  194. *cmd |= addr & WSPI_CMD_BYTE_ADDR;
  195. if (fixed)
  196. *cmd |= WSPI_CMD_FIXED;
  197. spi_message_init(&m);
  198. memset(t, 0, sizeof(t));
  199. t[0].tx_buf = cmd;
  200. t[0].len = sizeof(*cmd);
  201. spi_message_add_tail(&t[0], &m);
  202. t[1].tx_buf = buf;
  203. t[1].len = len;
  204. spi_message_add_tail(&t[1], &m);
  205. spi_sync(wl->spi, &m);
  206. wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd));
  207. wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
  208. }