1 /* 2 * SPI flash interface 3 * 4 * Copyright (C) 2008 Atmel Corporation 5 * Copyright (C) 2010 Reinhard Meyer, EMK Elektronik 6 * 7 * Licensed under the GPL-2 or later. 8 */ 9 10 #include <common.h> 11 #include <malloc.h> 12 #include <spi.h> 13 #include <spi_flash.h> 14 15 #include "spi_flash_internal.h" 16 17 int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len) 18 { 19 unsigned long flags = SPI_XFER_BEGIN; 20 int ret; 21 22 if (len == 0) 23 flags |= SPI_XFER_END; 24 25 ret = spi_xfer(spi, 8, &cmd, NULL, flags); 26 if (ret) { 27 debug("SF: Failed to send command %02x: %d\n", cmd, ret); 28 return ret; 29 } 30 31 if (len) { 32 ret = spi_xfer(spi, len * 8, NULL, response, SPI_XFER_END); 33 if (ret) 34 debug("SF: Failed to read response (%zu bytes): %d\n", 35 len, ret); 36 } 37 38 return ret; 39 } 40 41 int spi_flash_cmd_read(struct spi_slave *spi, const u8 *cmd, 42 size_t cmd_len, void *data, size_t data_len) 43 { 44 unsigned long flags = SPI_XFER_BEGIN; 45 int ret; 46 47 if (data_len == 0) 48 flags |= SPI_XFER_END; 49 50 ret = spi_xfer(spi, cmd_len * 8, cmd, NULL, flags); 51 if (ret) { 52 debug("SF: Failed to send read command (%zu bytes): %d\n", 53 cmd_len, ret); 54 } else if (data_len != 0) { 55 ret = spi_xfer(spi, data_len * 8, NULL, data, SPI_XFER_END); 56 if (ret) 57 debug("SF: Failed to read %zu bytes of data: %d\n", 58 data_len, ret); 59 } 60 61 return ret; 62 } 63 64 int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len, 65 const void *data, size_t data_len) 66 { 67 unsigned long flags = SPI_XFER_BEGIN; 68 int ret; 69 70 if (data_len == 0) 71 flags |= SPI_XFER_END; 72 73 ret = spi_xfer(spi, cmd_len * 8, cmd, NULL, flags); 74 if (ret) { 75 debug("SF: Failed to send read command (%zu bytes): %d\n", 76 cmd_len, ret); 77 } else if (data_len != 0) { 78 ret = spi_xfer(spi, data_len * 8, data, NULL, SPI_XFER_END); 79 if (ret) 80 debug("SF: Failed to read %zu bytes of data: %d\n", 81 data_len, ret); 82 } 83 84 return ret; 85 } 86 87 88 int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd, 89 size_t cmd_len, void *data, size_t data_len) 90 { 91 struct spi_slave *spi = flash->spi; 92 int ret; 93 94 spi_claim_bus(spi); 95 ret = spi_flash_cmd_read(spi, cmd, cmd_len, data, data_len); 96 spi_release_bus(spi); 97 98 return ret; 99 } 100 101 /* 102 * The following table holds all device probe functions 103 * 104 * shift: number of continuation bytes before the ID 105 * idcode: the expected IDCODE or 0xff for non JEDEC devices 106 * probe: the function to call 107 * 108 * Non JEDEC devices should be ordered in the table such that 109 * the probe functions with best detection algorithms come first. 110 * 111 * Several matching entries are permitted, they will be tried 112 * in sequence until a probe function returns non NULL. 113 * 114 * IDCODE_CONT_LEN may be redefined if a device needs to declare a 115 * larger "shift" value. IDCODE_PART_LEN generally shouldn't be 116 * changed. This is the max number of bytes probe functions may 117 * examine when looking up part-specific identification info. 118 * 119 * Probe functions will be given the idcode buffer starting at their 120 * manu id byte (the "idcode" in the table below). In other words, 121 * all of the continuation bytes will be skipped (the "shift" below). 122 */ 123 #define IDCODE_CONT_LEN 0 124 #define IDCODE_PART_LEN 5 125 static const struct { 126 const u8 shift; 127 const u8 idcode; 128 struct spi_flash *(*probe) (struct spi_slave *spi, u8 *idcode); 129 } flashes[] = { 130 /* Keep it sorted by define name */ 131 #ifdef CONFIG_SPI_FLASH_ATMEL 132 { 0, 0x1f, spi_flash_probe_atmel, }, 133 #endif 134 #ifdef CONFIG_SPI_FLASH_EON 135 { 0, 0x1c, spi_flash_probe_eon, }, 136 #endif 137 #ifdef CONFIG_SPI_FLASH_MACRONIX 138 { 0, 0xc2, spi_flash_probe_macronix, }, 139 #endif 140 #ifdef CONFIG_SPI_FLASH_SPANSION 141 { 0, 0x01, spi_flash_probe_spansion, }, 142 #endif 143 #ifdef CONFIG_SPI_FLASH_SST 144 { 0, 0xbf, spi_flash_probe_sst, }, 145 #endif 146 #ifdef CONFIG_SPI_FLASH_STMICRO 147 { 0, 0x20, spi_flash_probe_stmicro, }, 148 #endif 149 #ifdef CONFIG_SPI_FLASH_WINBOND 150 { 0, 0xef, spi_flash_probe_winbond, }, 151 #endif 152 #ifdef CONFIG_SPI_FRAM_RAMTRON 153 { 6, 0xc2, spi_fram_probe_ramtron, }, 154 # undef IDCODE_CONT_LEN 155 # define IDCODE_CONT_LEN 6 156 #endif 157 /* Keep it sorted by best detection */ 158 #ifdef CONFIG_SPI_FLASH_STMICRO 159 { 0, 0xff, spi_flash_probe_stmicro, }, 160 #endif 161 #ifdef CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC 162 { 0, 0xff, spi_fram_probe_ramtron, }, 163 #endif 164 }; 165 #define IDCODE_LEN (IDCODE_CONT_LEN + IDCODE_PART_LEN) 166 167 struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, 168 unsigned int max_hz, unsigned int spi_mode) 169 { 170 struct spi_slave *spi; 171 struct spi_flash *flash = NULL; 172 int ret, i, shift; 173 u8 idcode[IDCODE_LEN], *idp; 174 175 spi = spi_setup_slave(bus, cs, max_hz, spi_mode); 176 if (!spi) { 177 printf("SF: Failed to set up slave\n"); 178 return NULL; 179 } 180 181 ret = spi_claim_bus(spi); 182 if (ret) { 183 debug("SF: Failed to claim SPI bus: %d\n", ret); 184 goto err_claim_bus; 185 } 186 187 /* Read the ID codes */ 188 ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode)); 189 if (ret) 190 goto err_read_id; 191 192 #ifdef DEBUG 193 printf("SF: Got idcodes\n"); 194 print_buffer(0, idcode, 1, sizeof(idcode), 0); 195 #endif 196 197 /* count the number of continuation bytes */ 198 for (shift = 0, idp = idcode; 199 shift < IDCODE_CONT_LEN && *idp == 0x7f; 200 ++shift, ++idp) 201 continue; 202 203 /* search the table for matches in shift and id */ 204 for (i = 0; i < ARRAY_SIZE(flashes); ++i) 205 if (flashes[i].shift == shift && flashes[i].idcode == *idp) { 206 /* we have a match, call probe */ 207 flash = flashes[i].probe(spi, idp); 208 if (flash) 209 break; 210 } 211 212 if (!flash) { 213 printf("SF: Unsupported manufacturer %02x\n", *idp); 214 goto err_manufacturer_probe; 215 } 216 217 spi_release_bus(spi); 218 219 return flash; 220 221 err_manufacturer_probe: 222 err_read_id: 223 spi_release_bus(spi); 224 err_claim_bus: 225 spi_free_slave(spi); 226 return NULL; 227 } 228 229 void spi_flash_free(struct spi_flash *flash) 230 { 231 spi_free_slave(flash->spi); 232 free(flash); 233 } 234