atmel_spi.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. * Copyright (C) 2007 Atmel Corporation
  3. *
  4. * See file CREDITS for list of people who contributed to this
  5. * project.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU 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., 59 Temple Place, Suite 330, Boston,
  20. * MA 02111-1307 USA
  21. */
  22. #include <common.h>
  23. #include <spi.h>
  24. #include <malloc.h>
  25. #include <asm/io.h>
  26. #include <asm/arch/clk.h>
  27. #include <asm/arch/memory-map.h>
  28. #include "atmel_spi.h"
  29. void spi_init()
  30. {
  31. }
  32. struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
  33. unsigned int max_hz, unsigned int mode)
  34. {
  35. struct atmel_spi_slave *as;
  36. unsigned int scbr;
  37. u32 csrx;
  38. void *regs;
  39. if (cs > 3 || !spi_cs_is_valid(bus, cs))
  40. return NULL;
  41. switch (bus) {
  42. case 0:
  43. regs = (void *)SPI0_BASE;
  44. break;
  45. #ifdef SPI1_BASE
  46. case 1:
  47. regs = (void *)SPI1_BASE;
  48. break;
  49. #endif
  50. #ifdef SPI2_BASE
  51. case 2:
  52. regs = (void *)SPI2_BASE;
  53. break;
  54. #endif
  55. #ifdef SPI3_BASE
  56. case 3:
  57. regs = (void *)SPI3_BASE;
  58. break;
  59. #endif
  60. default:
  61. return NULL;
  62. }
  63. scbr = (get_spi_clk_rate(bus) + max_hz - 1) / max_hz;
  64. if (scbr > ATMEL_SPI_CSRx_SCBR_MAX)
  65. /* Too low max SCK rate */
  66. return NULL;
  67. if (scbr < 1)
  68. scbr = 1;
  69. csrx = ATMEL_SPI_CSRx_SCBR(scbr);
  70. csrx |= ATMEL_SPI_CSRx_BITS(ATMEL_SPI_BITS_8);
  71. if (!(mode & SPI_CPHA))
  72. csrx |= ATMEL_SPI_CSRx_NCPHA;
  73. if (mode & SPI_CPOL)
  74. csrx |= ATMEL_SPI_CSRx_CPOL;
  75. as = malloc(sizeof(struct atmel_spi_slave));
  76. if (!as)
  77. return NULL;
  78. as->slave.bus = bus;
  79. as->slave.cs = cs;
  80. as->regs = regs;
  81. as->mr = ATMEL_SPI_MR_MSTR | ATMEL_SPI_MR_MODFDIS
  82. | ATMEL_SPI_MR_PCS(~(1 << cs) & 0xf);
  83. spi_writel(as, CSR(cs), csrx);
  84. return &as->slave;
  85. }
  86. void spi_free_slave(struct spi_slave *slave)
  87. {
  88. struct atmel_spi_slave *as = to_atmel_spi(slave);
  89. free(as);
  90. }
  91. int spi_claim_bus(struct spi_slave *slave)
  92. {
  93. struct atmel_spi_slave *as = to_atmel_spi(slave);
  94. /* Enable the SPI hardware */
  95. spi_writel(as, CR, ATMEL_SPI_CR_SPIEN);
  96. /*
  97. * Select the slave. This should set SCK to the correct
  98. * initial state, etc.
  99. */
  100. spi_writel(as, MR, as->mr);
  101. return 0;
  102. }
  103. void spi_release_bus(struct spi_slave *slave)
  104. {
  105. struct atmel_spi_slave *as = to_atmel_spi(slave);
  106. /* Disable the SPI hardware */
  107. spi_writel(as, CR, ATMEL_SPI_CR_SPIDIS);
  108. }
  109. int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
  110. const void *dout, void *din, unsigned long flags)
  111. {
  112. struct atmel_spi_slave *as = to_atmel_spi(slave);
  113. unsigned int len_tx;
  114. unsigned int len_rx;
  115. unsigned int len;
  116. int ret;
  117. u32 status;
  118. const u8 *txp = dout;
  119. u8 *rxp = din;
  120. u8 value;
  121. ret = 0;
  122. if (bitlen == 0)
  123. /* Finish any previously submitted transfers */
  124. goto out;
  125. /*
  126. * TODO: The controller can do non-multiple-of-8 bit
  127. * transfers, but this driver currently doesn't support it.
  128. *
  129. * It's also not clear how such transfers are supposed to be
  130. * represented as a stream of bytes...this is a limitation of
  131. * the current SPI interface.
  132. */
  133. if (bitlen % 8) {
  134. /* Errors always terminate an ongoing transfer */
  135. flags |= SPI_XFER_END;
  136. goto out;
  137. }
  138. len = bitlen / 8;
  139. /*
  140. * The controller can do automatic CS control, but it is
  141. * somewhat quirky, and it doesn't really buy us much anyway
  142. * in the context of U-Boot.
  143. */
  144. if (flags & SPI_XFER_BEGIN)
  145. spi_cs_activate(slave);
  146. for (len_tx = 0, len_rx = 0; len_rx < len; ) {
  147. status = spi_readl(as, SR);
  148. if (status & ATMEL_SPI_SR_OVRES)
  149. return -1;
  150. if (len_tx < len && (status & ATMEL_SPI_SR_TDRE)) {
  151. if (txp)
  152. value = *txp++;
  153. else
  154. value = 0;
  155. spi_writel(as, TDR, value);
  156. len_tx++;
  157. }
  158. if (status & ATMEL_SPI_SR_RDRF) {
  159. value = spi_readl(as, RDR);
  160. if (rxp)
  161. *rxp++ = value;
  162. len_rx++;
  163. }
  164. }
  165. out:
  166. if (flags & SPI_XFER_END) {
  167. /*
  168. * Wait until the transfer is completely done before
  169. * we deactivate CS.
  170. */
  171. do {
  172. status = spi_readl(as, SR);
  173. } while (!(status & ATMEL_SPI_SR_TXEMPTY));
  174. spi_cs_deactivate(slave);
  175. }
  176. return 0;
  177. }