mxc_spi.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  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. for (i = 0, in_l = (u32 *)din, out_l = (u32 *)dout;
  109. i < n_blks;
  110. i++, in_l++, out_l++, bitlen -= 32) {
  111. u32 data = spi_xchg_single(slave, *out_l, bitlen, flags);
  112. /* Check if we're only transfering 8 or 16 bits */
  113. if (!i) {
  114. if (bitlen < 9)
  115. *(u8 *)din = data;
  116. else if (bitlen < 17)
  117. *(u16 *)din = data;
  118. }
  119. }
  120. return 0;
  121. }
  122. void spi_init(void)
  123. {
  124. }
  125. static int decode_cs(struct mxc_spi_slave *mxcs, unsigned int cs)
  126. {
  127. int ret;
  128. /*
  129. * Some SPI devices require active chip-select over multiple
  130. * transactions, we achieve this using a GPIO. Still, the SPI
  131. * controller has to be configured to use one of its own chipselects.
  132. * To use this feature you have to call spi_setup_slave() with
  133. * cs = internal_cs | (gpio << 8), and you have to use some unused
  134. * on this SPI controller cs between 0 and 3.
  135. */
  136. if (cs > 3) {
  137. mxcs->gpio = cs >> 8;
  138. cs &= 3;
  139. ret = mx31_gpio_direction(mxcs->gpio, MX31_GPIO_DIRECTION_OUT);
  140. if (ret) {
  141. printf("mxc_spi: cannot setup gpio %d\n", mxcs->gpio);
  142. return -EINVAL;
  143. }
  144. } else {
  145. mxcs->gpio = -1;
  146. }
  147. return cs;
  148. }
  149. struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
  150. unsigned int max_hz, unsigned int mode)
  151. {
  152. unsigned int ctrl_reg;
  153. struct mxc_spi_slave *mxcs;
  154. int ret;
  155. if (bus >= ARRAY_SIZE(spi_bases))
  156. return NULL;
  157. mxcs = malloc(sizeof(struct mxc_spi_slave));
  158. if (!mxcs)
  159. return NULL;
  160. ret = decode_cs(mxcs, cs);
  161. if (ret < 0) {
  162. free(mxcs);
  163. return NULL;
  164. }
  165. cs = ret;
  166. ctrl_reg = MXC_CSPICTRL_CHIPSELECT(cs) |
  167. MXC_CSPICTRL_BITCOUNT(31) |
  168. MXC_CSPICTRL_DATARATE(7) | /* FIXME: calculate data rate */
  169. MXC_CSPICTRL_EN |
  170. MXC_CSPICTRL_MODE;
  171. if (mode & SPI_CPHA)
  172. ctrl_reg |= MXC_CSPICTRL_PHA;
  173. if (!(mode & SPI_CPOL))
  174. ctrl_reg |= MXC_CSPICTRL_POL;
  175. if (mode & SPI_CS_HIGH)
  176. ctrl_reg |= MXC_CSPICTRL_SSPOL;
  177. mxcs->slave.bus = bus;
  178. mxcs->slave.cs = cs;
  179. mxcs->base = spi_bases[bus];
  180. mxcs->ctrl_reg = ctrl_reg;
  181. return &mxcs->slave;
  182. }
  183. void spi_free_slave(struct spi_slave *slave)
  184. {
  185. struct mxc_spi_slave *mxcs = to_mxc_spi_slave(slave);
  186. free(mxcs);
  187. }
  188. int spi_claim_bus(struct spi_slave *slave)
  189. {
  190. struct mxc_spi_slave *mxcs = to_mxc_spi_slave(slave);
  191. reg_write(mxcs->base + MXC_CSPIRESET, 1);
  192. udelay(1);
  193. reg_write(mxcs->base + MXC_CSPICTRL, mxcs->ctrl_reg);
  194. reg_write(mxcs->base + MXC_CSPIPERIOD,
  195. MXC_CSPIPERIOD_32KHZ);
  196. reg_write(mxcs->base + MXC_CSPIINT, 0);
  197. return 0;
  198. }
  199. void spi_release_bus(struct spi_slave *slave)
  200. {
  201. /* TODO: Shut the controller down */
  202. }