sf_probe.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /*
  2. * SPI flash probing
  3. *
  4. * Copyright (C) 2008 Atmel Corporation
  5. * Copyright (C) 2010 Reinhard Meyer, EMK Elektronik
  6. * Copyright (C) 2013 Jagannadha Sutradharudu Teki, Xilinx Inc.
  7. *
  8. * SPDX-License-Identifier: GPL-2.0+
  9. */
  10. #include <common.h>
  11. #include <dm.h>
  12. #include <errno.h>
  13. #include <malloc.h>
  14. #include <spi.h>
  15. #include <spi_flash.h>
  16. #include "sf_internal.h"
  17. /**
  18. * spi_flash_probe_slave() - Probe for a SPI flash device on a bus
  19. *
  20. * @flashp: Pointer to place to put flash info, which may be NULL if the
  21. * space should be allocated
  22. */
  23. static int spi_flash_probe_slave(struct spi_flash *flash)
  24. {
  25. struct spi_slave *spi = flash->spi;
  26. int ret;
  27. /* Setup spi_slave */
  28. if (!spi) {
  29. printf("SF: Failed to set up slave\n");
  30. return -ENODEV;
  31. }
  32. /* Claim spi bus */
  33. ret = spi_claim_bus(spi);
  34. if (ret) {
  35. debug("SF: Failed to claim SPI bus: %d\n", ret);
  36. return ret;
  37. }
  38. ret = spi_flash_scan(flash);
  39. if (ret)
  40. goto err_read_id;
  41. #ifdef CONFIG_SPI_FLASH_MTD
  42. ret = spi_flash_mtd_register(flash);
  43. #endif
  44. err_read_id:
  45. spi_release_bus(spi);
  46. return ret;
  47. }
  48. #ifndef CONFIG_DM_SPI_FLASH
  49. static struct spi_flash *spi_flash_probe_tail(struct spi_slave *bus)
  50. {
  51. struct spi_flash *flash;
  52. /* Allocate space if needed (not used by sf-uclass */
  53. flash = calloc(1, sizeof(*flash));
  54. if (!flash) {
  55. debug("SF: Failed to allocate spi_flash\n");
  56. return NULL;
  57. }
  58. flash->spi = bus;
  59. if (spi_flash_probe_slave(flash)) {
  60. spi_free_slave(bus);
  61. free(flash);
  62. return NULL;
  63. }
  64. return flash;
  65. }
  66. struct spi_flash *spi_flash_probe(unsigned int busnum, unsigned int cs,
  67. unsigned int max_hz, unsigned int spi_mode)
  68. {
  69. struct spi_slave *bus;
  70. bus = spi_setup_slave(busnum, cs, max_hz, spi_mode);
  71. if (!bus)
  72. return NULL;
  73. return spi_flash_probe_tail(bus);
  74. }
  75. #ifdef CONFIG_OF_SPI_FLASH
  76. struct spi_flash *spi_flash_probe_fdt(const void *blob, int slave_node,
  77. int spi_node)
  78. {
  79. struct spi_slave *bus;
  80. bus = spi_setup_slave_fdt(blob, slave_node, spi_node);
  81. if (!bus)
  82. return NULL;
  83. return spi_flash_probe_tail(bus);
  84. }
  85. #endif
  86. void spi_flash_free(struct spi_flash *flash)
  87. {
  88. #ifdef CONFIG_SPI_FLASH_MTD
  89. spi_flash_mtd_unregister();
  90. #endif
  91. spi_free_slave(flash->spi);
  92. free(flash);
  93. }
  94. #else /* defined CONFIG_DM_SPI_FLASH */
  95. static int spi_flash_std_read(struct udevice *dev, u32 offset, size_t len,
  96. void *buf)
  97. {
  98. struct spi_flash *flash = dev_get_uclass_priv(dev);
  99. return spi_flash_cmd_read_ops(flash, offset, len, buf);
  100. }
  101. static int spi_flash_std_write(struct udevice *dev, u32 offset, size_t len,
  102. const void *buf)
  103. {
  104. struct spi_flash *flash = dev_get_uclass_priv(dev);
  105. #if defined(CONFIG_SPI_FLASH_SST)
  106. if (flash->flags & SNOR_F_SST_WR) {
  107. if (flash->spi->mode & SPI_TX_BYTE)
  108. return sst_write_bp(flash, offset, len, buf);
  109. else
  110. return sst_write_wp(flash, offset, len, buf);
  111. }
  112. #endif
  113. return spi_flash_cmd_write_ops(flash, offset, len, buf);
  114. }
  115. static int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len)
  116. {
  117. struct spi_flash *flash = dev_get_uclass_priv(dev);
  118. return spi_flash_cmd_erase_ops(flash, offset, len);
  119. }
  120. static int spi_flash_std_probe(struct udevice *dev)
  121. {
  122. struct spi_slave *slave = dev_get_parent_priv(dev);
  123. struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
  124. struct spi_flash *flash;
  125. flash = dev_get_uclass_priv(dev);
  126. flash->dev = dev;
  127. flash->spi = slave;
  128. debug("%s: slave=%p, cs=%d\n", __func__, slave, plat->cs);
  129. return spi_flash_probe_slave(flash);
  130. }
  131. static const struct dm_spi_flash_ops spi_flash_std_ops = {
  132. .read = spi_flash_std_read,
  133. .write = spi_flash_std_write,
  134. .erase = spi_flash_std_erase,
  135. };
  136. static const struct udevice_id spi_flash_std_ids[] = {
  137. { .compatible = "spi-flash" },
  138. { }
  139. };
  140. U_BOOT_DRIVER(spi_flash_std) = {
  141. .name = "spi_flash_std",
  142. .id = UCLASS_SPI_FLASH,
  143. .of_match = spi_flash_std_ids,
  144. .probe = spi_flash_std_probe,
  145. .priv_auto_alloc_size = sizeof(struct spi_flash),
  146. .ops = &spi_flash_std_ops,
  147. };
  148. #endif /* CONFIG_DM_SPI_FLASH */