hwio.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. /*
  2. * Low-level device IO routines for ST-Ericsson CW1200 drivers
  3. *
  4. * Copyright (c) 2010, ST-Ericsson
  5. * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
  6. *
  7. * Based on:
  8. * ST-Ericsson UMAC CW1200 driver, which is
  9. * Copyright (c) 2010, ST-Ericsson
  10. * Author: Ajitpal Singh <ajitpal.singh@lockless.no>
  11. *
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License version 2 as
  14. * published by the Free Software Foundation.
  15. */
  16. #include <linux/types.h>
  17. #include "cw1200.h"
  18. #include "hwio.h"
  19. #include "hwbus.h"
  20. /* Sdio addr is 4*spi_addr */
  21. #define SPI_REG_ADDR_TO_SDIO(spi_reg_addr) ((spi_reg_addr) << 2)
  22. #define SDIO_ADDR17BIT(buf_id, mpf, rfu, reg_id_ofs) \
  23. ((((buf_id) & 0x1F) << 7) \
  24. | (((mpf) & 1) << 6) \
  25. | (((rfu) & 1) << 5) \
  26. | (((reg_id_ofs) & 0x1F) << 0))
  27. #define MAX_RETRY 3
  28. static int __cw1200_reg_read(struct cw1200_common *priv, u16 addr,
  29. void *buf, size_t buf_len, int buf_id)
  30. {
  31. u16 addr_sdio;
  32. u32 sdio_reg_addr_17bit;
  33. /* Check if buffer is aligned to 4 byte boundary */
  34. if (WARN_ON(((unsigned long)buf & 3) && (buf_len > 4))) {
  35. pr_err("buffer is not aligned.\n");
  36. return -EINVAL;
  37. }
  38. /* Convert to SDIO Register Address */
  39. addr_sdio = SPI_REG_ADDR_TO_SDIO(addr);
  40. sdio_reg_addr_17bit = SDIO_ADDR17BIT(buf_id, 0, 0, addr_sdio);
  41. return priv->hwbus_ops->hwbus_memcpy_fromio(priv->hwbus_priv,
  42. sdio_reg_addr_17bit,
  43. buf, buf_len);
  44. }
  45. static int __cw1200_reg_write(struct cw1200_common *priv, u16 addr,
  46. const void *buf, size_t buf_len, int buf_id)
  47. {
  48. u16 addr_sdio;
  49. u32 sdio_reg_addr_17bit;
  50. /* Convert to SDIO Register Address */
  51. addr_sdio = SPI_REG_ADDR_TO_SDIO(addr);
  52. sdio_reg_addr_17bit = SDIO_ADDR17BIT(buf_id, 0, 0, addr_sdio);
  53. return priv->hwbus_ops->hwbus_memcpy_toio(priv->hwbus_priv,
  54. sdio_reg_addr_17bit,
  55. buf, buf_len);
  56. }
  57. static inline int __cw1200_reg_read_32(struct cw1200_common *priv,
  58. u16 addr, u32 *val)
  59. {
  60. int i = __cw1200_reg_read(priv, addr, val, sizeof(*val), 0);
  61. *val = le32_to_cpu(*val);
  62. return i;
  63. }
  64. static inline int __cw1200_reg_write_32(struct cw1200_common *priv,
  65. u16 addr, u32 val)
  66. {
  67. val = cpu_to_le32(val);
  68. return __cw1200_reg_write(priv, addr, &val, sizeof(val), 0);
  69. }
  70. static inline int __cw1200_reg_read_16(struct cw1200_common *priv,
  71. u16 addr, u16 *val)
  72. {
  73. int i = __cw1200_reg_read(priv, addr, val, sizeof(*val), 0);
  74. *val = le16_to_cpu(*val);
  75. return i;
  76. }
  77. static inline int __cw1200_reg_write_16(struct cw1200_common *priv,
  78. u16 addr, u16 val)
  79. {
  80. val = cpu_to_le16(val);
  81. return __cw1200_reg_write(priv, addr, &val, sizeof(val), 0);
  82. }
  83. int cw1200_reg_read(struct cw1200_common *priv, u16 addr, void *buf,
  84. size_t buf_len)
  85. {
  86. int ret;
  87. priv->hwbus_ops->lock(priv->hwbus_priv);
  88. ret = __cw1200_reg_read(priv, addr, buf, buf_len, 0);
  89. priv->hwbus_ops->unlock(priv->hwbus_priv);
  90. return ret;
  91. }
  92. int cw1200_reg_write(struct cw1200_common *priv, u16 addr, const void *buf,
  93. size_t buf_len)
  94. {
  95. int ret;
  96. priv->hwbus_ops->lock(priv->hwbus_priv);
  97. ret = __cw1200_reg_write(priv, addr, buf, buf_len, 0);
  98. priv->hwbus_ops->unlock(priv->hwbus_priv);
  99. return ret;
  100. }
  101. int cw1200_data_read(struct cw1200_common *priv, void *buf, size_t buf_len)
  102. {
  103. int ret, retry = 1;
  104. int buf_id_rx = priv->buf_id_rx;
  105. priv->hwbus_ops->lock(priv->hwbus_priv);
  106. while (retry <= MAX_RETRY) {
  107. ret = __cw1200_reg_read(priv,
  108. ST90TDS_IN_OUT_QUEUE_REG_ID, buf,
  109. buf_len, buf_id_rx + 1);
  110. if (!ret) {
  111. buf_id_rx = (buf_id_rx + 1) & 3;
  112. priv->buf_id_rx = buf_id_rx;
  113. break;
  114. } else {
  115. retry++;
  116. mdelay(1);
  117. pr_err("error :[%d]\n", ret);
  118. }
  119. }
  120. priv->hwbus_ops->unlock(priv->hwbus_priv);
  121. return ret;
  122. }
  123. int cw1200_data_write(struct cw1200_common *priv, const void *buf,
  124. size_t buf_len)
  125. {
  126. int ret, retry = 1;
  127. int buf_id_tx = priv->buf_id_tx;
  128. priv->hwbus_ops->lock(priv->hwbus_priv);
  129. while (retry <= MAX_RETRY) {
  130. ret = __cw1200_reg_write(priv,
  131. ST90TDS_IN_OUT_QUEUE_REG_ID, buf,
  132. buf_len, buf_id_tx);
  133. if (!ret) {
  134. buf_id_tx = (buf_id_tx + 1) & 31;
  135. priv->buf_id_tx = buf_id_tx;
  136. break;
  137. } else {
  138. retry++;
  139. mdelay(1);
  140. pr_err("error :[%d]\n", ret);
  141. }
  142. }
  143. priv->hwbus_ops->unlock(priv->hwbus_priv);
  144. return ret;
  145. }
  146. int cw1200_indirect_read(struct cw1200_common *priv, u32 addr, void *buf,
  147. size_t buf_len, u32 prefetch, u16 port_addr)
  148. {
  149. u32 val32 = 0;
  150. int i, ret;
  151. if ((buf_len / 2) >= 0x1000) {
  152. pr_err("Can't read more than 0xfff words.\n");
  153. return -EINVAL;
  154. goto out;
  155. }
  156. priv->hwbus_ops->lock(priv->hwbus_priv);
  157. /* Write address */
  158. ret = __cw1200_reg_write_32(priv, ST90TDS_SRAM_BASE_ADDR_REG_ID, addr);
  159. if (ret < 0) {
  160. pr_err("Can't write address register.\n");
  161. goto out;
  162. }
  163. /* Read CONFIG Register Value - We will read 32 bits */
  164. ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
  165. if (ret < 0) {
  166. pr_err("Can't read config register.\n");
  167. goto out;
  168. }
  169. /* Set PREFETCH bit */
  170. ret = __cw1200_reg_write_32(priv, ST90TDS_CONFIG_REG_ID,
  171. val32 | prefetch);
  172. if (ret < 0) {
  173. pr_err("Can't write prefetch bit.\n");
  174. goto out;
  175. }
  176. /* Check for PRE-FETCH bit to be cleared */
  177. for (i = 0; i < 20; i++) {
  178. ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
  179. if (ret < 0) {
  180. pr_err("Can't check prefetch bit.\n");
  181. goto out;
  182. }
  183. if (!(val32 & prefetch))
  184. break;
  185. mdelay(i);
  186. }
  187. if (val32 & prefetch) {
  188. pr_err("Prefetch bit is not cleared.\n");
  189. goto out;
  190. }
  191. /* Read data port */
  192. ret = __cw1200_reg_read(priv, port_addr, buf, buf_len, 0);
  193. if (ret < 0) {
  194. pr_err("Can't read data port.\n");
  195. goto out;
  196. }
  197. out:
  198. priv->hwbus_ops->unlock(priv->hwbus_priv);
  199. return ret;
  200. }
  201. int cw1200_apb_write(struct cw1200_common *priv, u32 addr, const void *buf,
  202. size_t buf_len)
  203. {
  204. int ret;
  205. if ((buf_len / 2) >= 0x1000) {
  206. pr_err("Can't write more than 0xfff words.\n");
  207. return -EINVAL;
  208. }
  209. priv->hwbus_ops->lock(priv->hwbus_priv);
  210. /* Write address */
  211. ret = __cw1200_reg_write_32(priv, ST90TDS_SRAM_BASE_ADDR_REG_ID, addr);
  212. if (ret < 0) {
  213. pr_err("Can't write address register.\n");
  214. goto out;
  215. }
  216. /* Write data port */
  217. ret = __cw1200_reg_write(priv, ST90TDS_SRAM_DPORT_REG_ID,
  218. buf, buf_len, 0);
  219. if (ret < 0) {
  220. pr_err("Can't write data port.\n");
  221. goto out;
  222. }
  223. out:
  224. priv->hwbus_ops->unlock(priv->hwbus_priv);
  225. return ret;
  226. }
  227. int __cw1200_irq_enable(struct cw1200_common *priv, int enable)
  228. {
  229. u32 val32;
  230. u16 val16;
  231. int ret;
  232. if (HIF_8601_SILICON == priv->hw_type) {
  233. ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
  234. if (ret < 0) {
  235. pr_err("Can't read config register.\n");
  236. return ret;
  237. }
  238. if (enable)
  239. val32 |= ST90TDS_CONF_IRQ_RDY_ENABLE;
  240. else
  241. val32 &= ~ST90TDS_CONF_IRQ_RDY_ENABLE;
  242. ret = __cw1200_reg_write_32(priv, ST90TDS_CONFIG_REG_ID, val32);
  243. if (ret < 0) {
  244. pr_err("Can't write config register.\n");
  245. return ret;
  246. }
  247. } else {
  248. ret = __cw1200_reg_read_16(priv, ST90TDS_CONFIG_REG_ID, &val16);
  249. if (ret < 0) {
  250. pr_err("Can't read control register.\n");
  251. return ret;
  252. }
  253. if (enable)
  254. val16 |= ST90TDS_CONT_IRQ_RDY_ENABLE;
  255. else
  256. val16 &= ~ST90TDS_CONT_IRQ_RDY_ENABLE;
  257. ret = __cw1200_reg_write_16(priv, ST90TDS_CONFIG_REG_ID, val16);
  258. if (ret < 0) {
  259. pr_err("Can't write control register.\n");
  260. return ret;
  261. }
  262. }
  263. return 0;
  264. }