1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (c) 2014 Google, Inc 4 */ 5 6 #include <common.h> 7 #include <dm.h> 8 #include <spi.h> 9 #include <spi_flash.h> 10 #include <dm/device-internal.h> 11 #include "sf_internal.h" 12 13 DECLARE_GLOBAL_DATA_PTR; 14 15 int spi_flash_read_dm(struct udevice *dev, u32 offset, size_t len, void *buf) 16 { 17 return log_ret(sf_get_ops(dev)->read(dev, offset, len, buf)); 18 } 19 20 int spi_flash_write_dm(struct udevice *dev, u32 offset, size_t len, 21 const void *buf) 22 { 23 return log_ret(sf_get_ops(dev)->write(dev, offset, len, buf)); 24 } 25 26 int spi_flash_erase_dm(struct udevice *dev, u32 offset, size_t len) 27 { 28 return log_ret(sf_get_ops(dev)->erase(dev, offset, len)); 29 } 30 31 int spl_flash_get_sw_write_prot(struct udevice *dev) 32 { 33 struct dm_spi_flash_ops *ops = sf_get_ops(dev); 34 35 if (!ops->get_sw_write_prot) 36 return -ENOSYS; 37 return log_ret(ops->get_sw_write_prot(dev)); 38 } 39 40 /* 41 * TODO(sjg@chromium.org): This is an old-style function. We should remove 42 * it when all SPI flash drivers use dm 43 */ 44 struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, 45 unsigned int max_hz, unsigned int spi_mode) 46 { 47 struct udevice *dev; 48 49 if (spi_flash_probe_bus_cs(bus, cs, max_hz, spi_mode, &dev)) 50 return NULL; 51 52 return dev_get_uclass_priv(dev); 53 } 54 55 void spi_flash_free(struct spi_flash *flash) 56 { 57 device_remove(flash->spi->dev, DM_REMOVE_NORMAL); 58 } 59 60 int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs, 61 unsigned int max_hz, unsigned int spi_mode, 62 struct udevice **devp) 63 { 64 struct spi_slave *slave; 65 struct udevice *bus; 66 char *str; 67 int ret; 68 69 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_USE_TINY_PRINTF) 70 str = "spi_flash"; 71 #else 72 char name[30]; 73 74 snprintf(name, sizeof(name), "spi_flash@%d:%d", busnum, cs); 75 str = strdup(name); 76 #endif 77 ret = spi_get_bus_and_cs(busnum, cs, max_hz, spi_mode, 78 "spi_flash_std", str, &bus, &slave); 79 if (ret) 80 return ret; 81 82 *devp = slave->dev; 83 return 0; 84 } 85 86 static int spi_flash_post_bind(struct udevice *dev) 87 { 88 #if defined(CONFIG_NEEDS_MANUAL_RELOC) 89 struct dm_spi_flash_ops *ops = sf_get_ops(dev); 90 static int reloc_done; 91 92 if (!reloc_done) { 93 if (ops->read) 94 ops->read += gd->reloc_off; 95 if (ops->write) 96 ops->write += gd->reloc_off; 97 if (ops->erase) 98 ops->erase += gd->reloc_off; 99 100 reloc_done++; 101 } 102 #endif 103 return 0; 104 } 105 106 UCLASS_DRIVER(spi_flash) = { 107 .id = UCLASS_SPI_FLASH, 108 .name = "spi_flash", 109 .post_bind = spi_flash_post_bind, 110 .per_device_auto_alloc_size = sizeof(struct spi_flash), 111 }; 112