sf_probe.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * SPI flash probing
  4. *
  5. * Copyright (C) 2008 Atmel Corporation
  6. * Copyright (C) 2010 Reinhard Meyer, EMK Elektronik
  7. * Copyright (C) 2013 Jagannadha Sutradharudu Teki, Xilinx Inc.
  8. */
  9. #include <common.h>
  10. #include <dm.h>
  11. #include <errno.h>
  12. #include <log.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_nor_scan(flash);
  39. if (ret)
  40. goto err_read_id;
  41. if (CONFIG_IS_ENABLED(SPI_FLASH_MTD))
  42. ret = spi_flash_mtd_register(flash);
  43. err_read_id:
  44. spi_release_bus(spi);
  45. return ret;
  46. }
  47. #if !CONFIG_IS_ENABLED(DM_SPI_FLASH)
  48. struct spi_flash *spi_flash_probe(unsigned int busnum, unsigned int cs,
  49. unsigned int max_hz, unsigned int spi_mode)
  50. {
  51. struct spi_slave *bus;
  52. struct spi_flash *flash;
  53. bus = spi_setup_slave(busnum, cs, max_hz, spi_mode);
  54. if (!bus)
  55. return NULL;
  56. /* Allocate space if needed (not used by sf-uclass */
  57. flash = calloc(1, sizeof(*flash));
  58. if (!flash) {
  59. debug("SF: Failed to allocate spi_flash\n");
  60. return NULL;
  61. }
  62. flash->spi = bus;
  63. if (spi_flash_probe_slave(flash)) {
  64. spi_free_slave(bus);
  65. free(flash);
  66. return NULL;
  67. }
  68. return flash;
  69. }
  70. void spi_flash_free(struct spi_flash *flash)
  71. {
  72. if (CONFIG_IS_ENABLED(SPI_FLASH_MTD))
  73. spi_flash_mtd_unregister();
  74. spi_free_slave(flash->spi);
  75. free(flash);
  76. }
  77. #else /* defined CONFIG_DM_SPI_FLASH */
  78. static int spi_flash_std_read(struct udevice *dev, u32 offset, size_t len,
  79. void *buf)
  80. {
  81. struct spi_flash *flash = dev_get_uclass_priv(dev);
  82. struct mtd_info *mtd = &flash->mtd;
  83. size_t retlen;
  84. return log_ret(mtd->_read(mtd, offset, len, &retlen, buf));
  85. }
  86. static int spi_flash_std_write(struct udevice *dev, u32 offset, size_t len,
  87. const void *buf)
  88. {
  89. struct spi_flash *flash = dev_get_uclass_priv(dev);
  90. struct mtd_info *mtd = &flash->mtd;
  91. size_t retlen;
  92. return mtd->_write(mtd, offset, len, &retlen, buf);
  93. }
  94. static int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len)
  95. {
  96. struct spi_flash *flash = dev_get_uclass_priv(dev);
  97. struct mtd_info *mtd = &flash->mtd;
  98. struct erase_info instr;
  99. if (offset % mtd->erasesize || len % mtd->erasesize) {
  100. printf("SF: Erase offset/length not multiple of erase size\n");
  101. return -EINVAL;
  102. }
  103. memset(&instr, 0, sizeof(instr));
  104. instr.addr = offset;
  105. instr.len = len;
  106. return mtd->_erase(mtd, &instr);
  107. }
  108. int spi_flash_std_probe(struct udevice *dev)
  109. {
  110. struct spi_slave *slave = dev_get_parent_priv(dev);
  111. struct spi_flash *flash;
  112. flash = dev_get_uclass_priv(dev);
  113. flash->dev = dev;
  114. flash->spi = slave;
  115. return spi_flash_probe_slave(flash);
  116. }
  117. static int spi_flash_std_remove(struct udevice *dev)
  118. {
  119. if (CONFIG_IS_ENABLED(SPI_FLASH_MTD))
  120. spi_flash_mtd_unregister();
  121. return 0;
  122. }
  123. static const struct dm_spi_flash_ops spi_flash_std_ops = {
  124. .read = spi_flash_std_read,
  125. .write = spi_flash_std_write,
  126. .erase = spi_flash_std_erase,
  127. };
  128. static const struct udevice_id spi_flash_std_ids[] = {
  129. { .compatible = "jedec,spi-nor" },
  130. { }
  131. };
  132. U_BOOT_DRIVER(spi_flash_std) = {
  133. .name = "spi_flash_std",
  134. .id = UCLASS_SPI_FLASH,
  135. .of_match = spi_flash_std_ids,
  136. .probe = spi_flash_std_probe,
  137. .remove = spi_flash_std_remove,
  138. .priv_auto_alloc_size = sizeof(struct spi_flash),
  139. .ops = &spi_flash_std_ops,
  140. };
  141. #endif /* CONFIG_DM_SPI_FLASH */