mxc_spi.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /*
  2. * Copyright (C) 2008, Guennadi Liakhovetski <lg@denx.de>
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of
  7. * the License, or (at your option) any later version.
  8. *
  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. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  17. * MA 02111-1307 USA
  18. *
  19. */
  20. #include <common.h>
  21. #include <malloc.h>
  22. #include <spi.h>
  23. #include <asm/errno.h>
  24. #include <asm/io.h>
  25. #ifdef CONFIG_MX27
  26. /* i.MX27 has a completely wrong register layout and register definitions in the
  27. * datasheet, the correct one is in the Freescale's Linux driver */
  28. #error "i.MX27 CSPI not supported due to drastic differences in register definisions" \
  29. "See linux mxc_spi driver from Freescale for details."
  30. #else
  31. #include <asm/arch/mx31.h>
  32. #define MXC_CSPIRXDATA 0x00
  33. #define MXC_CSPITXDATA 0x04
  34. #define MXC_CSPICTRL 0x08
  35. #define MXC_CSPIINT 0x0C
  36. #define MXC_CSPIDMA 0x10
  37. #define MXC_CSPISTAT 0x14
  38. #define MXC_CSPIPERIOD 0x18
  39. #define MXC_CSPITEST 0x1C
  40. #define MXC_CSPIRESET 0x00
  41. #define MXC_CSPICTRL_EN (1 << 0)
  42. #define MXC_CSPICTRL_MODE (1 << 1)
  43. #define MXC_CSPICTRL_XCH (1 << 2)
  44. #define MXC_CSPICTRL_SMC (1 << 3)
  45. #define MXC_CSPICTRL_POL (1 << 4)
  46. #define MXC_CSPICTRL_PHA (1 << 5)
  47. #define MXC_CSPICTRL_SSCTL (1 << 6)
  48. #define MXC_CSPICTRL_SSPOL (1 << 7)
  49. #define MXC_CSPICTRL_CHIPSELECT(x) (((x) & 0x3) << 24)
  50. #define MXC_CSPICTRL_BITCOUNT(x) (((x) & 0x1f) << 8)
  51. #define MXC_CSPICTRL_DATARATE(x) (((x) & 0x7) << 16)
  52. #define MXC_CSPIPERIOD_32KHZ (1 << 15)
  53. static unsigned long spi_bases[] = {
  54. 0x43fa4000,
  55. 0x50010000,
  56. 0x53f84000,
  57. };
  58. #endif
  59. struct mxc_spi_slave {
  60. struct spi_slave slave;
  61. unsigned long base;
  62. u32 ctrl_reg;
  63. int gpio;
  64. };
  65. static inline struct mxc_spi_slave *to_mxc_spi_slave(struct spi_slave *slave)
  66. {
  67. return container_of(slave, struct mxc_spi_slave, slave);
  68. }
  69. static inline u32 reg_read(unsigned long addr)
  70. {
  71. return *(volatile unsigned long*)addr;
  72. }
  73. static inline void reg_write(unsigned long addr, u32 val)
  74. {
  75. *(volatile unsigned long*)addr = val;
  76. }
  77. static u32 spi_xchg_single(struct spi_slave *slave, u32 data, int bitlen,
  78. unsigned long flags)
  79. {
  80. struct mxc_spi_slave *mxcs = to_mxc_spi_slave(slave);
  81. unsigned int cfg_reg = reg_read(mxcs->base + MXC_CSPICTRL);
  82. mxcs->ctrl_reg = (mxcs->ctrl_reg & ~MXC_CSPICTRL_BITCOUNT(31)) |
  83. MXC_CSPICTRL_BITCOUNT(bitlen - 1);
  84. if (cfg_reg != mxcs->ctrl_reg)
  85. reg_write(mxcs->base + MXC_CSPICTRL, mxcs->ctrl_reg);
  86. if (mxcs->gpio > 0 && (flags & SPI_XFER_BEGIN))
  87. mx31_gpio_set(mxcs->gpio, mxcs->ctrl_reg & MXC_CSPICTRL_SSPOL);
  88. reg_write(mxcs->base + MXC_CSPITXDATA, data);
  89. reg_write(mxcs->base + MXC_CSPICTRL, mxcs->ctrl_reg | MXC_CSPICTRL_XCH);
  90. while (reg_read(mxcs->base + MXC_CSPICTRL) & MXC_CSPICTRL_XCH)
  91. ;
  92. if (mxcs->gpio > 0 && (flags & SPI_XFER_END)) {
  93. mx31_gpio_set(mxcs->gpio,
  94. !(mxcs->ctrl_reg & MXC_CSPICTRL_SSPOL));
  95. }
  96. return reg_read(mxcs->base + MXC_CSPIRXDATA);
  97. }
  98. int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
  99. void *din, unsigned long flags)
  100. {
  101. int n_blks = (bitlen + 31) / 32;
  102. u32 *out_l, *in_l;
  103. int i;
  104. if ((int)dout & 3 || (int)din & 3) {
  105. printf("Error: unaligned buffers in: %p, out: %p\n", din, dout);
  106. return 1;
  107. }
  108. /* This driver is currently partly broken, alert the user */
  109. if (bitlen > 16 && (bitlen % 32)) {
  110. printf("Error: SPI transfer with bitlen=%d is broken.\n",
  111. bitlen);
  112. return 1;
  113. }
  114. for (i = 0, in_l = (u32 *)din, out_l = (u32 *)dout;
  115. i < n_blks;
  116. i++, in_l++, out_l++, bitlen -= 32) {
  117. u32 data = spi_xchg_single(slave, *out_l, bitlen, flags);
  118. /* Check if we're only transfering 8 or 16 bits */
  119. if (!i) {
  120. if (bitlen < 9)
  121. *(u8 *)din = data;
  122. else if (bitlen < 17)
  123. *(u16 *)din = data;
  124. else
  125. *in_l = data;
  126. }
  127. }
  128. return 0;
  129. }
  130. void spi_init(void)
  131. {
  132. }
  133. static int decode_cs(struct mxc_spi_slave *mxcs, unsigned int cs)
  134. {
  135. int ret;
  136. /*
  137. * Some SPI devices require active chip-select over multiple
  138. * transactions, we achieve this using a GPIO. Still, the SPI
  139. * controller has to be configured to use one of its own chipselects.
  140. * To use this feature you have to call spi_setup_slave() with
  141. * cs = internal_cs | (gpio << 8), and you have to use some unused
  142. * on this SPI controller cs between 0 and 3.
  143. */
  144. if (cs > 3) {
  145. mxcs->gpio = cs >> 8;
  146. cs &= 3;
  147. ret = mx31_gpio_direction(mxcs->gpio, MX31_GPIO_DIRECTION_OUT);
  148. if (ret) {
  149. printf("mxc_spi: cannot setup gpio %d\n", mxcs->gpio);
  150. return -EINVAL;
  151. }
  152. } else {
  153. mxcs->gpio = -1;
  154. }
  155. return cs;
  156. }
  157. struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
  158. unsigned int max_hz, unsigned int mode)
  159. {
  160. unsigned int ctrl_reg;
  161. struct mxc_spi_slave *mxcs;
  162. int ret;
  163. if (bus >= ARRAY_SIZE(spi_bases))
  164. return NULL;
  165. mxcs = malloc(sizeof(struct mxc_spi_slave));
  166. if (!mxcs)
  167. return NULL;
  168. ret = decode_cs(mxcs, cs);
  169. if (ret < 0) {
  170. free(mxcs);
  171. return NULL;
  172. }
  173. cs = ret;
  174. ctrl_reg = MXC_CSPICTRL_CHIPSELECT(cs) |
  175. MXC_CSPICTRL_BITCOUNT(31) |
  176. MXC_CSPICTRL_DATARATE(7) | /* FIXME: calculate data rate */
  177. MXC_CSPICTRL_EN |
  178. MXC_CSPICTRL_MODE;
  179. if (mode & SPI_CPHA)
  180. ctrl_reg |= MXC_CSPICTRL_PHA;
  181. if (!(mode & SPI_CPOL))
  182. ctrl_reg |= MXC_CSPICTRL_POL;
  183. if (mode & SPI_CS_HIGH)
  184. ctrl_reg |= MXC_CSPICTRL_SSPOL;
  185. mxcs->slave.bus = bus;
  186. mxcs->slave.cs = cs;
  187. mxcs->base = spi_bases[bus];
  188. mxcs->ctrl_reg = ctrl_reg;
  189. return &mxcs->slave;
  190. }
  191. void spi_free_slave(struct spi_slave *slave)
  192. {
  193. struct mxc_spi_slave *mxcs = to_mxc_spi_slave(slave);
  194. free(mxcs);
  195. }
  196. int spi_claim_bus(struct spi_slave *slave)
  197. {
  198. struct mxc_spi_slave *mxcs = to_mxc_spi_slave(slave);
  199. reg_write(mxcs->base + MXC_CSPIRESET, 1);
  200. udelay(1);
  201. reg_write(mxcs->base + MXC_CSPICTRL, mxcs->ctrl_reg);
  202. reg_write(mxcs->base + MXC_CSPIPERIOD,
  203. MXC_CSPIPERIOD_32KHZ);
  204. reg_write(mxcs->base + MXC_CSPIINT, 0);
  205. return 0;
  206. }
  207. void spi_release_bus(struct spi_slave *slave)
  208. {
  209. /* TODO: Shut the controller down */
  210. }