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