fdt_spi.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * Common fdt based SPI driver front end
  3. *
  4. * Copyright (c) 2013 NVIDIA Corporation
  5. *
  6. * See file CREDITS for list of people who contributed to this
  7. * project.
  8. *
  9. * This software is licensed under the terms of the GNU General Public
  10. * License version 2, as published by the Free Software Foundation, and
  11. * may be copied, distributed, and modified under those terms.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. */
  23. #include <common.h>
  24. #include <malloc.h>
  25. #include <asm/io.h>
  26. #include <asm/gpio.h>
  27. #include <asm/arch/clock.h>
  28. #include <asm/arch-tegra/clk_rst.h>
  29. #include <asm/arch-tegra20/tegra20_sflash.h>
  30. #include <asm/arch-tegra20/tegra20_slink.h>
  31. #include <asm/arch-tegra114/tegra114_spi.h>
  32. #include <spi.h>
  33. #include <fdtdec.h>
  34. DECLARE_GLOBAL_DATA_PTR;
  35. struct fdt_spi_driver {
  36. int compat;
  37. int max_ctrls;
  38. int (*init)(int *node_list, int count);
  39. int (*claim_bus)(struct spi_slave *slave);
  40. int (*release_bus)(struct spi_slave *slave);
  41. int (*cs_is_valid)(unsigned int bus, unsigned int cs);
  42. struct spi_slave *(*setup_slave)(unsigned int bus, unsigned int cs,
  43. unsigned int max_hz, unsigned int mode);
  44. void (*free_slave)(struct spi_slave *slave);
  45. void (*cs_activate)(struct spi_slave *slave);
  46. void (*cs_deactivate)(struct spi_slave *slave);
  47. int (*xfer)(struct spi_slave *slave, unsigned int bitlen,
  48. const void *data_out, void *data_in, unsigned long flags);
  49. };
  50. static struct fdt_spi_driver fdt_spi_drivers[] = {
  51. #ifdef CONFIG_TEGRA20_SFLASH
  52. {
  53. .compat = COMPAT_NVIDIA_TEGRA20_SFLASH,
  54. .max_ctrls = 1,
  55. .init = tegra20_spi_init,
  56. .claim_bus = tegra20_spi_claim_bus,
  57. .cs_is_valid = tegra20_spi_cs_is_valid,
  58. .setup_slave = tegra20_spi_setup_slave,
  59. .free_slave = tegra20_spi_free_slave,
  60. .cs_activate = tegra20_spi_cs_activate,
  61. .cs_deactivate = tegra20_spi_cs_deactivate,
  62. .xfer = tegra20_spi_xfer,
  63. },
  64. #endif
  65. #ifdef CONFIG_TEGRA20_SLINK
  66. {
  67. .compat = COMPAT_NVIDIA_TEGRA20_SLINK,
  68. .max_ctrls = CONFIG_TEGRA_SLINK_CTRLS,
  69. .init = tegra30_spi_init,
  70. .claim_bus = tegra30_spi_claim_bus,
  71. .cs_is_valid = tegra30_spi_cs_is_valid,
  72. .setup_slave = tegra30_spi_setup_slave,
  73. .free_slave = tegra30_spi_free_slave,
  74. .cs_activate = tegra30_spi_cs_activate,
  75. .cs_deactivate = tegra30_spi_cs_deactivate,
  76. .xfer = tegra30_spi_xfer,
  77. },
  78. #endif
  79. #ifdef CONFIG_TEGRA114_SPI
  80. {
  81. .compat = COMPAT_NVIDIA_TEGRA114_SPI,
  82. .max_ctrls = CONFIG_TEGRA114_SPI_CTRLS,
  83. .init = tegra114_spi_init,
  84. .claim_bus = tegra114_spi_claim_bus,
  85. .cs_is_valid = tegra114_spi_cs_is_valid,
  86. .setup_slave = tegra114_spi_setup_slave,
  87. .free_slave = tegra114_spi_free_slave,
  88. .cs_activate = tegra114_spi_cs_activate,
  89. .cs_deactivate = tegra114_spi_cs_deactivate,
  90. .xfer = tegra114_spi_xfer,
  91. },
  92. #endif
  93. };
  94. static struct fdt_spi_driver *driver;
  95. int spi_cs_is_valid(unsigned int bus, unsigned int cs)
  96. {
  97. if (!driver)
  98. return 0;
  99. else if (!driver->cs_is_valid)
  100. return 1;
  101. else
  102. return driver->cs_is_valid(bus, cs);
  103. }
  104. struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
  105. unsigned int max_hz, unsigned int mode)
  106. {
  107. if (!driver || !driver->setup_slave)
  108. return NULL;
  109. return driver->setup_slave(bus, cs, max_hz, mode);
  110. }
  111. void spi_free_slave(struct spi_slave *slave)
  112. {
  113. if (driver && driver->free_slave)
  114. return driver->free_slave(slave);
  115. }
  116. static int spi_init_driver(struct fdt_spi_driver *driver)
  117. {
  118. int count;
  119. int node_list[driver->max_ctrls];
  120. count = fdtdec_find_aliases_for_id(gd->fdt_blob, "spi",
  121. driver->compat,
  122. node_list,
  123. driver->max_ctrls);
  124. return driver->init(node_list, count);
  125. }
  126. void spi_init(void)
  127. {
  128. int i;
  129. for (i = 0; i < ARRAY_SIZE(fdt_spi_drivers); i++) {
  130. driver = &fdt_spi_drivers[i];
  131. if (!spi_init_driver(driver))
  132. break;
  133. }
  134. if (i == ARRAY_SIZE(fdt_spi_drivers))
  135. driver = NULL;
  136. }
  137. int spi_claim_bus(struct spi_slave *slave)
  138. {
  139. if (!driver)
  140. return 1;
  141. if (!driver->claim_bus)
  142. return 0;
  143. return driver->claim_bus(slave);
  144. }
  145. void spi_release_bus(struct spi_slave *slave)
  146. {
  147. if (driver && driver->release_bus)
  148. driver->release_bus(slave);
  149. }
  150. void spi_cs_activate(struct spi_slave *slave)
  151. {
  152. if (driver && driver->cs_activate)
  153. driver->cs_activate(slave);
  154. }
  155. void spi_cs_deactivate(struct spi_slave *slave)
  156. {
  157. if (driver && driver->cs_deactivate)
  158. driver->cs_deactivate(slave);
  159. }
  160. int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
  161. const void *data_out, void *data_in, unsigned long flags)
  162. {
  163. if (!driver || !driver->xfer)
  164. return -1;
  165. return driver->xfer(slave, bitlen, data_out, data_in, flags);
  166. }