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 spi_flash_ctrl_wlock_dm(struct udevice *dev, u32 offset, size_t len) 32 { 33 return log_ret(sf_get_ops(dev)->flash_ctrl_wlock(dev, offset, len)); 34 } 35 36 int spi_flash_ctrl_wunlock_dm(struct udevice *dev, u32 offset, size_t len) 37 { 38 return log_ret(sf_get_ops(dev)->flash_ctrl_wunlock(dev, offset, len)); 39 } 40 41 int spl_flash_get_sw_write_prot(struct udevice *dev) 42 { 43 struct dm_spi_flash_ops *ops = sf_get_ops(dev); 44 45 if (!ops->get_sw_write_prot) 46 return -ENOSYS; 47 return log_ret(ops->get_sw_write_prot(dev)); 48 } 49 50 /* 51 * TODO(sjg@chromium.org): This is an old-style function. We should remove 52 * it when all SPI flash drivers use dm 53 */ 54 struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, 55 unsigned int max_hz, unsigned int spi_mode) 56 { 57 struct udevice *dev; 58 59 if (spi_flash_probe_bus_cs(bus, cs, max_hz, spi_mode, &dev)) 60 return NULL; 61 62 return dev_get_uclass_priv(dev); 63 } 64 65 void spi_flash_free(struct spi_flash *flash) 66 { 67 device_remove(flash->spi->dev, DM_REMOVE_NORMAL); 68 } 69 70 int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs, 71 unsigned int max_hz, unsigned int spi_mode, 72 struct udevice **devp) 73 { 74 struct spi_slave *slave; 75 struct udevice *bus; 76 char *str; 77 int ret; 78 79 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_USE_TINY_PRINTF) 80 str = "spi_flash"; 81 #else 82 char name[30]; 83 84 snprintf(name, sizeof(name), "spi_flash@%d:%d", busnum, cs); 85 str = strdup(name); 86 #endif 87 ret = spi_get_bus_and_cs(busnum, cs, max_hz, spi_mode, 88 "spi_flash_std", str, &bus, &slave); 89 if (ret) 90 return ret; 91 92 *devp = slave->dev; 93 return 0; 94 } 95 96 static int spi_flash_post_bind(struct udevice *dev) 97 { 98 #if defined(CONFIG_NEEDS_MANUAL_RELOC) 99 struct dm_spi_flash_ops *ops = sf_get_ops(dev); 100 static int reloc_done; 101 102 if (!reloc_done) { 103 if (ops->read) 104 ops->read += gd->reloc_off; 105 if (ops->write) 106 ops->write += gd->reloc_off; 107 if (ops->erase) 108 ops->erase += gd->reloc_off; 109 110 reloc_done++; 111 } 112 #endif 113 return 0; 114 } 115 116 UCLASS_DRIVER(spi_flash) = { 117 .id = UCLASS_SPI_FLASH, 118 .name = "spi_flash", 119 .post_bind = spi_flash_post_bind, 120 .per_device_auto_alloc_size = sizeof(struct spi_flash), 121 }; 122