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