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_MACRONIX 135 { 0, 0xc2, spi_flash_probe_macronix, }, 136 #endif 137 #ifdef CONFIG_SPI_FLASH_SPANSION 138 { 0, 0x01, spi_flash_probe_spansion, }, 139 #endif 140 #ifdef CONFIG_SPI_FLASH_SST 141 { 0, 0xbf, spi_flash_probe_sst, }, 142 #endif 143 #ifdef CONFIG_SPI_FLASH_STMICRO 144 { 0, 0x20, spi_flash_probe_stmicro, }, 145 #endif 146 #ifdef CONFIG_SPI_FLASH_WINBOND 147 { 0, 0xef, spi_flash_probe_winbond, }, 148 #endif 149 #ifdef CONFIG_SPI_FRAM_RAMTRON 150 { 6, 0xc2, spi_fram_probe_ramtron, }, 151 # undef IDCODE_CONT_LEN 152 # define IDCODE_CONT_LEN 6 153 #endif 154 /* Keep it sorted by best detection */ 155 #ifdef CONFIG_SPI_FLASH_STMICRO 156 { 0, 0xff, spi_flash_probe_stmicro, }, 157 #endif 158 #ifdef CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC 159 { 0, 0xff, spi_fram_probe_ramtron, }, 160 #endif 161 }; 162 #define IDCODE_LEN (IDCODE_CONT_LEN + IDCODE_PART_LEN) 163 164 struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, 165 unsigned int max_hz, unsigned int spi_mode) 166 { 167 struct spi_slave *spi; 168 struct spi_flash *flash = NULL; 169 int ret, i, shift; 170 u8 idcode[IDCODE_LEN], *idp; 171 172 spi = spi_setup_slave(bus, cs, max_hz, spi_mode); 173 if (!spi) { 174 printf("SF: Failed to set up slave\n"); 175 return NULL; 176 } 177 178 ret = spi_claim_bus(spi); 179 if (ret) { 180 debug("SF: Failed to claim SPI bus: %d\n", ret); 181 goto err_claim_bus; 182 } 183 184 /* Read the ID codes */ 185 ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode)); 186 if (ret) 187 goto err_read_id; 188 189 #ifdef DEBUG 190 printf("SF: Got idcodes\n"); 191 print_buffer(0, idcode, 1, sizeof(idcode), 0); 192 #endif 193 194 /* count the number of continuation bytes */ 195 for (shift = 0, idp = idcode; 196 shift < IDCODE_CONT_LEN && *idp == 0x7f; 197 ++shift, ++idp) 198 continue; 199 200 /* search the table for matches in shift and id */ 201 for (i = 0; i < ARRAY_SIZE(flashes); ++i) 202 if (flashes[i].shift == shift && flashes[i].idcode == *idp) { 203 /* we have a match, call probe */ 204 flash = flashes[i].probe(spi, idp); 205 if (flash) 206 break; 207 } 208 209 if (!flash) { 210 printf("SF: Unsupported manufacturer %02x\n", *idp); 211 goto err_manufacturer_probe; 212 } 213 214 spi_release_bus(spi); 215 216 return flash; 217 218 err_manufacturer_probe: 219 err_read_id: 220 spi_release_bus(spi); 221 err_claim_bus: 222 spi_free_slave(spi); 223 return NULL; 224 } 225 226 void spi_flash_free(struct spi_flash *flash) 227 { 228 spi_free_slave(flash->spi); 229 free(flash); 230 } 231