diff options
author | fishsoupisgood <github@madingley.org> | 2019-04-29 01:17:54 +0100 |
---|---|---|
committer | fishsoupisgood <github@madingley.org> | 2019-05-27 03:43:43 +0100 |
commit | 3f2546b2ef55b661fd8dd69682b38992225e86f6 (patch) | |
tree | 65ca85f13617aee1dce474596800950f266a456c /roms/u-boot/drivers/mtd/spi/eeprom_m95xxx.c | |
download | qemu-master.tar.gz qemu-master.tar.bz2 qemu-master.zip |
Diffstat (limited to 'roms/u-boot/drivers/mtd/spi/eeprom_m95xxx.c')
-rw-r--r-- | roms/u-boot/drivers/mtd/spi/eeprom_m95xxx.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/roms/u-boot/drivers/mtd/spi/eeprom_m95xxx.c b/roms/u-boot/drivers/mtd/spi/eeprom_m95xxx.c new file mode 100644 index 00000000..a019939b --- /dev/null +++ b/roms/u-boot/drivers/mtd/spi/eeprom_m95xxx.c @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2009 + * Albin Tonnerre, Free Electrons <albin.tonnerre@free-electrons.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <spi.h> + +#define SPI_EEPROM_WREN 0x06 +#define SPI_EEPROM_RDSR 0x05 +#define SPI_EEPROM_READ 0x03 +#define SPI_EEPROM_WRITE 0x02 + +#ifndef CONFIG_DEFAULT_SPI_BUS +#define CONFIG_DEFAULT_SPI_BUS 0 +#endif + +#ifndef CONFIG_DEFAULT_SPI_MODE +#define CONFIG_DEFAULT_SPI_MODE SPI_MODE_0 +#endif + +#ifndef CONFIG_SYS_SPI_WRITE_TOUT +#define CONFIG_SYS_SPI_WRITE_TOUT (5 * CONFIG_SYS_HZ) +#endif + +ssize_t spi_read(uchar *addr, int alen, uchar *buffer, int len) +{ + struct spi_slave *slave; + u8 cmd = SPI_EEPROM_READ; + + slave = spi_setup_slave(CONFIG_DEFAULT_SPI_BUS, 1, 1000000, + CONFIG_DEFAULT_SPI_MODE); + if (!slave) + return 0; + + spi_claim_bus(slave); + + /* command */ + if (spi_xfer(slave, 8, &cmd, NULL, SPI_XFER_BEGIN)) + return -1; + + /* + * if alen == 3, addr[0] is the block number, we never use it here. + * All we need are the lower 16 bits. + */ + if (alen == 3) + addr++; + + /* address, and data */ + if (spi_xfer(slave, 16, addr, NULL, 0)) + return -1; + if (spi_xfer(slave, 8 * len, NULL, buffer, SPI_XFER_END)) + return -1; + + spi_release_bus(slave); + spi_free_slave(slave); + return len; +} + +ssize_t spi_write(uchar *addr, int alen, uchar *buffer, int len) +{ + struct spi_slave *slave; + char buf[3]; + ulong start; + + slave = spi_setup_slave(CONFIG_DEFAULT_SPI_BUS, 1, 1000000, + CONFIG_DEFAULT_SPI_MODE); + if (!slave) + return 0; + + spi_claim_bus(slave); + + buf[0] = SPI_EEPROM_WREN; + if (spi_xfer(slave, 8, buf, NULL, SPI_XFER_BEGIN | SPI_XFER_END)) + return -1; + + buf[0] = SPI_EEPROM_WRITE; + + /* As for reading, drop addr[0] if alen is 3 */ + if (alen == 3) { + alen--; + addr++; + } + + memcpy(buf + 1, addr, alen); + /* command + addr, then data */ + if (spi_xfer(slave, 24, buf, NULL, SPI_XFER_BEGIN)) + return -1; + if (spi_xfer(slave, len * 8, buffer, NULL, SPI_XFER_END)) + return -1; + + start = get_timer(0); + do { + buf[0] = SPI_EEPROM_RDSR; + buf[1] = 0; + spi_xfer(slave, 16, buf, buf, SPI_XFER_BEGIN | SPI_XFER_END); + + if (!(buf[1] & 1)) + break; + + } while (get_timer(start) < CONFIG_SYS_SPI_WRITE_TOUT); + + if (buf[1] & 1) + printf("*** spi_write: Timeout while writing!\n"); + + spi_release_bus(slave); + spi_free_slave(slave); + return len; +} |