wl1271_spi.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  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 <linux/slab.h>
  28. #include "wl1271.h"
  29. #include "wl12xx_80211.h"
  30. #include "wl1271_spi.h"
  31. void wl1271_spi_reset(struct wl1271 *wl)
  32. {
  33. u8 *cmd;
  34. struct spi_transfer t;
  35. struct spi_message m;
  36. cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
  37. if (!cmd) {
  38. wl1271_error("could not allocate cmd for spi reset");
  39. return;
  40. }
  41. memset(&t, 0, sizeof(t));
  42. spi_message_init(&m);
  43. memset(cmd, 0xff, WSPI_INIT_CMD_LEN);
  44. t.tx_buf = cmd;
  45. t.len = WSPI_INIT_CMD_LEN;
  46. spi_message_add_tail(&t, &m);
  47. spi_sync(wl->spi, &m);
  48. wl1271_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN);
  49. }
  50. void wl1271_spi_init(struct wl1271 *wl)
  51. {
  52. u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd;
  53. struct spi_transfer t;
  54. struct spi_message m;
  55. cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
  56. if (!cmd) {
  57. wl1271_error("could not allocate cmd for spi init");
  58. return;
  59. }
  60. memset(crc, 0, sizeof(crc));
  61. memset(&t, 0, sizeof(t));
  62. spi_message_init(&m);
  63. /*
  64. * Set WSPI_INIT_COMMAND
  65. * the data is being send from the MSB to LSB
  66. */
  67. cmd[2] = 0xff;
  68. cmd[3] = 0xff;
  69. cmd[1] = WSPI_INIT_CMD_START | WSPI_INIT_CMD_TX;
  70. cmd[0] = 0;
  71. cmd[7] = 0;
  72. cmd[6] |= HW_ACCESS_WSPI_INIT_CMD_MASK << 3;
  73. cmd[6] |= HW_ACCESS_WSPI_FIXED_BUSY_LEN & WSPI_INIT_CMD_FIXEDBUSY_LEN;
  74. if (HW_ACCESS_WSPI_FIXED_BUSY_LEN == 0)
  75. cmd[5] |= WSPI_INIT_CMD_DIS_FIXEDBUSY;
  76. else
  77. cmd[5] |= WSPI_INIT_CMD_EN_FIXEDBUSY;
  78. cmd[5] |= WSPI_INIT_CMD_IOD | WSPI_INIT_CMD_IP | WSPI_INIT_CMD_CS
  79. | WSPI_INIT_CMD_WSPI | WSPI_INIT_CMD_WS;
  80. crc[0] = cmd[1];
  81. crc[1] = cmd[0];
  82. crc[2] = cmd[7];
  83. crc[3] = cmd[6];
  84. crc[4] = cmd[5];
  85. cmd[4] |= crc7(0, crc, WSPI_INIT_CMD_CRC_LEN) << 1;
  86. cmd[4] |= WSPI_INIT_CMD_END;
  87. t.tx_buf = cmd;
  88. t.len = WSPI_INIT_CMD_LEN;
  89. spi_message_add_tail(&t, &m);
  90. spi_sync(wl->spi, &m);
  91. wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);
  92. }
  93. #define WL1271_BUSY_WORD_TIMEOUT 1000
  94. /* FIXME: Check busy words, removed due to SPI bug */
  95. #if 0
  96. static void wl1271_spi_read_busy(struct wl1271 *wl, void *buf, size_t len)
  97. {
  98. struct spi_transfer t[1];
  99. struct spi_message m;
  100. u32 *busy_buf;
  101. int num_busy_bytes = 0;
  102. wl1271_info("spi read BUSY!");
  103. /*
  104. * Look for the non-busy word in the read buffer, and if found,
  105. * read in the remaining data into the buffer.
  106. */
  107. busy_buf = (u32 *)buf;
  108. for (; (u32)busy_buf < (u32)buf + len; busy_buf++) {
  109. num_busy_bytes += sizeof(u32);
  110. if (*busy_buf & 0x1) {
  111. spi_message_init(&m);
  112. memset(t, 0, sizeof(t));
  113. memmove(buf, busy_buf, len - num_busy_bytes);
  114. t[0].rx_buf = buf + (len - num_busy_bytes);
  115. t[0].len = num_busy_bytes;
  116. spi_message_add_tail(&t[0], &m);
  117. spi_sync(wl->spi, &m);
  118. return;
  119. }
  120. }
  121. /*
  122. * Read further busy words from SPI until a non-busy word is
  123. * encountered, then read the data itself into the buffer.
  124. */
  125. wl1271_info("spi read BUSY-polling needed!");
  126. num_busy_bytes = WL1271_BUSY_WORD_TIMEOUT;
  127. busy_buf = wl->buffer_busyword;
  128. while (num_busy_bytes) {
  129. num_busy_bytes--;
  130. spi_message_init(&m);
  131. memset(t, 0, sizeof(t));
  132. t[0].rx_buf = busy_buf;
  133. t[0].len = sizeof(u32);
  134. spi_message_add_tail(&t[0], &m);
  135. spi_sync(wl->spi, &m);
  136. if (*busy_buf & 0x1) {
  137. spi_message_init(&m);
  138. memset(t, 0, sizeof(t));
  139. t[0].rx_buf = buf;
  140. t[0].len = len;
  141. spi_message_add_tail(&t[0], &m);
  142. spi_sync(wl->spi, &m);
  143. return;
  144. }
  145. }
  146. /* The SPI bus is unresponsive, the read failed. */
  147. memset(buf, 0, len);
  148. wl1271_error("SPI read busy-word timeout!\n");
  149. }
  150. #endif
  151. void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf,
  152. size_t len, bool fixed)
  153. {
  154. struct spi_transfer t[3];
  155. struct spi_message m;
  156. u32 *busy_buf;
  157. u32 *cmd;
  158. cmd = &wl->buffer_cmd;
  159. busy_buf = wl->buffer_busyword;
  160. *cmd = 0;
  161. *cmd |= WSPI_CMD_READ;
  162. *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
  163. *cmd |= addr & WSPI_CMD_BYTE_ADDR;
  164. if (fixed)
  165. *cmd |= WSPI_CMD_FIXED;
  166. spi_message_init(&m);
  167. memset(t, 0, sizeof(t));
  168. t[0].tx_buf = cmd;
  169. t[0].len = 4;
  170. spi_message_add_tail(&t[0], &m);
  171. /* Busy and non busy words read */
  172. t[1].rx_buf = busy_buf;
  173. t[1].len = WL1271_BUSY_WORD_LEN;
  174. spi_message_add_tail(&t[1], &m);
  175. t[2].rx_buf = buf;
  176. t[2].len = len;
  177. spi_message_add_tail(&t[2], &m);
  178. spi_sync(wl->spi, &m);
  179. /* FIXME: Check busy words, removed due to SPI bug */
  180. /* if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1))
  181. wl1271_spi_read_busy(wl, buf, len); */
  182. wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd));
  183. wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);
  184. }
  185. void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf,
  186. size_t len, bool fixed)
  187. {
  188. struct spi_transfer t[2];
  189. struct spi_message m;
  190. u32 *cmd;
  191. cmd = &wl->buffer_cmd;
  192. *cmd = 0;
  193. *cmd |= WSPI_CMD_WRITE;
  194. *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
  195. *cmd |= addr & WSPI_CMD_BYTE_ADDR;
  196. if (fixed)
  197. *cmd |= WSPI_CMD_FIXED;
  198. spi_message_init(&m);
  199. memset(t, 0, sizeof(t));
  200. t[0].tx_buf = cmd;
  201. t[0].len = sizeof(*cmd);
  202. spi_message_add_tail(&t[0], &m);
  203. t[1].tx_buf = buf;
  204. t[1].len = len;
  205. spi_message_add_tail(&t[1], &m);
  206. spi_sync(wl->spi, &m);
  207. wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd));
  208. wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
  209. }