fdt_spi.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  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 <spi.h>
  32. #include <fdtdec.h>
  33. DECLARE_GLOBAL_DATA_PTR;
  34. struct fdt_spi_driver {
  35. int compat;
  36. int max_ctrls;
  37. int (*init)(int *node_list, int count);
  38. int (*claim_bus)(struct spi_slave *slave);
  39. int (*release_bus)(struct spi_slave *slave);
  40. int (*cs_is_valid)(unsigned int bus, unsigned int cs);
  41. struct spi_slave *(*setup_slave)(unsigned int bus, unsigned int cs,
  42. unsigned int max_hz, unsigned int mode);
  43. void (*free_slave)(struct spi_slave *slave);
  44. void (*cs_activate)(struct spi_slave *slave);
  45. void (*cs_deactivate)(struct spi_slave *slave);
  46. int (*xfer)(struct spi_slave *slave, unsigned int bitlen,
  47. const void *data_out, void *data_in, unsigned long flags);
  48. };
  49. static struct fdt_spi_driver fdt_spi_drivers[] = {
  50. #ifdef CONFIG_TEGRA20_SFLASH
  51. {
  52. .compat = COMPAT_NVIDIA_TEGRA20_SFLASH,
  53. .max_ctrls = 1,
  54. .init = tegra20_spi_init,
  55. .claim_bus = tegra20_spi_claim_bus,
  56. .cs_is_valid = tegra20_spi_cs_is_valid,
  57. .setup_slave = tegra20_spi_setup_slave,
  58. .free_slave = tegra20_spi_free_slave,
  59. .cs_activate = tegra20_spi_cs_activate,
  60. .cs_deactivate = tegra20_spi_cs_deactivate,
  61. .xfer = tegra20_spi_xfer,
  62. },
  63. #endif
  64. #ifdef CONFIG_TEGRA20_SLINK
  65. {
  66. .compat = COMPAT_NVIDIA_TEGRA20_SLINK,
  67. .max_ctrls = CONFIG_TEGRA_SLINK_CTRLS,
  68. .init = tegra30_spi_init,
  69. .claim_bus = tegra30_spi_claim_bus,
  70. .cs_is_valid = tegra30_spi_cs_is_valid,
  71. .setup_slave = tegra30_spi_setup_slave,
  72. .free_slave = tegra30_spi_free_slave,
  73. .cs_activate = tegra30_spi_cs_activate,
  74. .cs_deactivate = tegra30_spi_cs_deactivate,
  75. .xfer = tegra30_spi_xfer,
  76. },
  77. #endif
  78. };
  79. static struct fdt_spi_driver *driver;
  80. int spi_cs_is_valid(unsigned int bus, unsigned int cs)
  81. {
  82. if (!driver)
  83. return 0;
  84. else if (!driver->cs_is_valid)
  85. return 1;
  86. else
  87. return driver->cs_is_valid(bus, cs);
  88. }
  89. struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
  90. unsigned int max_hz, unsigned int mode)
  91. {
  92. if (!driver || !driver->setup_slave)
  93. return NULL;
  94. return driver->setup_slave(bus, cs, max_hz, mode);
  95. }
  96. void spi_free_slave(struct spi_slave *slave)
  97. {
  98. if (driver && driver->free_slave)
  99. return driver->free_slave(slave);
  100. }
  101. static int spi_init_driver(struct fdt_spi_driver *driver)
  102. {
  103. int count;
  104. int node_list[driver->max_ctrls];
  105. count = fdtdec_find_aliases_for_id(gd->fdt_blob, "spi",
  106. driver->compat,
  107. node_list,
  108. driver->max_ctrls);
  109. return driver->init(node_list, count);
  110. }
  111. void spi_init(void)
  112. {
  113. int i;
  114. for (i = 0; i < ARRAY_SIZE(fdt_spi_drivers); i++) {
  115. driver = &fdt_spi_drivers[i];
  116. if (!spi_init_driver(driver))
  117. break;
  118. }
  119. if (i == ARRAY_SIZE(fdt_spi_drivers))
  120. driver = NULL;
  121. }
  122. int spi_claim_bus(struct spi_slave *slave)
  123. {
  124. if (!driver)
  125. return 1;
  126. if (!driver->claim_bus)
  127. return 0;
  128. return driver->claim_bus(slave);
  129. }
  130. void spi_release_bus(struct spi_slave *slave)
  131. {
  132. if (driver && driver->release_bus)
  133. driver->release_bus(slave);
  134. }
  135. void spi_cs_activate(struct spi_slave *slave)
  136. {
  137. if (driver && driver->cs_activate)
  138. driver->cs_activate(slave);
  139. }
  140. void spi_cs_deactivate(struct spi_slave *slave)
  141. {
  142. if (driver && driver->cs_deactivate)
  143. driver->cs_deactivate(slave);
  144. }
  145. int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
  146. const void *data_out, void *data_in, unsigned long flags)
  147. {
  148. if (!driver || !driver->xfer)
  149. return -1;
  150. return driver->xfer(slave, bitlen, data_out, data_in, flags);
  151. }