1 /* 2 * SPI flash interface 3 * 4 * Copyright (C) 2008 Atmel Corporation 5 * Licensed under the GPL-2 or later. 6 */ 7 8 #include <common.h> 9 #include <malloc.h> 10 #include <spi.h> 11 #include <spi_flash.h> 12 13 #include "spi_flash_internal.h" 14 15 int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len) 16 { 17 unsigned long flags = SPI_XFER_BEGIN; 18 int ret; 19 20 if (len == 0) 21 flags |= SPI_XFER_END; 22 23 ret = spi_xfer(spi, 8, &cmd, NULL, flags); 24 if (ret) { 25 debug("SF: Failed to send command %02x: %d\n", cmd, ret); 26 return ret; 27 } 28 29 if (len) { 30 ret = spi_xfer(spi, len * 8, NULL, response, SPI_XFER_END); 31 if (ret) 32 debug("SF: Failed to read response (%zu bytes): %d\n", 33 len, ret); 34 } 35 36 return ret; 37 } 38 39 int spi_flash_cmd_read(struct spi_slave *spi, const u8 *cmd, 40 size_t cmd_len, void *data, size_t data_len) 41 { 42 unsigned long flags = SPI_XFER_BEGIN; 43 int ret; 44 45 if (data_len == 0) 46 flags |= SPI_XFER_END; 47 48 ret = spi_xfer(spi, cmd_len * 8, cmd, NULL, flags); 49 if (ret) { 50 debug("SF: Failed to send read command (%zu bytes): %d\n", 51 cmd_len, ret); 52 } else if (data_len != 0) { 53 ret = spi_xfer(spi, data_len * 8, NULL, data, SPI_XFER_END); 54 if (ret) 55 debug("SF: Failed to read %zu bytes of data: %d\n", 56 data_len, ret); 57 } 58 59 return ret; 60 } 61 62 int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len, 63 const void *data, size_t data_len) 64 { 65 unsigned long flags = SPI_XFER_BEGIN; 66 int ret; 67 68 if (data_len == 0) 69 flags |= SPI_XFER_END; 70 71 ret = spi_xfer(spi, cmd_len * 8, cmd, NULL, flags); 72 if (ret) { 73 debug("SF: Failed to send read command (%zu bytes): %d\n", 74 cmd_len, ret); 75 } else if (data_len != 0) { 76 ret = spi_xfer(spi, data_len * 8, data, NULL, SPI_XFER_END); 77 if (ret) 78 debug("SF: Failed to read %zu bytes of data: %d\n", 79 data_len, ret); 80 } 81 82 return ret; 83 } 84 85 86 int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd, 87 size_t cmd_len, void *data, size_t data_len) 88 { 89 struct spi_slave *spi = flash->spi; 90 int ret; 91 92 spi_claim_bus(spi); 93 ret = spi_flash_cmd_read(spi, cmd, cmd_len, data, data_len); 94 spi_release_bus(spi); 95 96 return ret; 97 } 98 99 struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, 100 unsigned int max_hz, unsigned int spi_mode) 101 { 102 struct spi_slave *spi; 103 struct spi_flash *flash; 104 int ret; 105 u8 idcode[5]; 106 107 spi = spi_setup_slave(bus, cs, max_hz, spi_mode); 108 if (!spi) { 109 debug("SF: Failed to set up slave\n"); 110 return NULL; 111 } 112 113 ret = spi_claim_bus(spi); 114 if (ret) { 115 debug("SF: Failed to claim SPI bus: %d\n", ret); 116 goto err_claim_bus; 117 } 118 119 /* Read the ID codes */ 120 ret = spi_flash_cmd(spi, CMD_READ_ID, &idcode, sizeof(idcode)); 121 if (ret) 122 goto err_read_id; 123 124 debug("SF: Got idcode %02x %02x %02x %02x %02x\n", idcode[0], 125 idcode[1], idcode[2], idcode[3], idcode[4]); 126 127 switch (idcode[0]) { 128 #ifdef CONFIG_SPI_FLASH_SPANSION 129 case 0x01: 130 flash = spi_flash_probe_spansion(spi, idcode); 131 break; 132 #endif 133 #ifdef CONFIG_SPI_FLASH_ATMEL 134 case 0x1F: 135 flash = spi_flash_probe_atmel(spi, idcode); 136 break; 137 #endif 138 #ifdef CONFIG_SPI_FLASH_MACRONIX 139 case 0xc2: 140 flash = spi_flash_probe_macronix(spi, idcode); 141 break; 142 #endif 143 #ifdef CONFIG_SPI_FLASH_WINBOND 144 case 0xef: 145 flash = spi_flash_probe_winbond(spi, idcode); 146 break; 147 #endif 148 #ifdef CONFIG_SPI_FLASH_STMICRO 149 case 0x20: 150 flash = spi_flash_probe_stmicro(spi, idcode); 151 break; 152 #endif 153 #ifdef CONFIG_SPI_FLASH_SST 154 case 0xBF: 155 flash = spi_flash_probe_sst(spi, idcode); 156 break; 157 #endif 158 default: 159 debug("SF: Unsupported manufacturer %02X\n", idcode[0]); 160 flash = NULL; 161 break; 162 } 163 164 if (!flash) 165 goto err_manufacturer_probe; 166 167 spi_release_bus(spi); 168 169 return flash; 170 171 err_manufacturer_probe: 172 err_read_id: 173 spi_release_bus(spi); 174 err_claim_bus: 175 spi_free_slave(spi); 176 return NULL; 177 } 178 179 void spi_flash_free(struct spi_flash *flash) 180 { 181 spi_free_slave(flash->spi); 182 free(flash); 183 } 184