Skip to content
Snippets Groups Projects
Commit 3ac374c0 authored by Albin Tonnerre's avatar Albin Tonnerre Committed by Wolfgang Denk
Browse files

Add driver for the ST M95xxx SPI EEPROM


This chip is used in a number of boards manufactured by Calao-Systems
which should be supported soon. This driver provides the necessary
spi_read and spi_write functions necessary to communicate with the chip.

Signed-off-by: default avatarAlbin Tonnerre <albin.tonnerre@free-electrons.com>
parent 30951960
No related branches found
No related tags found
No related merge requests found
......@@ -31,6 +31,7 @@ COBJS-$(CONFIG_SPI_FLASH_MACRONIX) += macronix.o
COBJS-$(CONFIG_SPI_FLASH_SPANSION) += spansion.o
COBJS-$(CONFIG_SPI_FLASH_SST) += sst.o
COBJS-$(CONFIG_SPI_FLASH_STMICRO) += stmicro.o
COBJS-$(CONFIG_SPI_M95XXX) += eeprom_m95xxx.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
......
/*
* Copyright (C) 2009
* Albin Tonnerre, Free Electrons <albin.tonnerre@free-electrons.com>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#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
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);
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;
int i;
char buf[3];
slave = spi_setup_slave(CONFIG_DEFAULT_SPI_BUS, 1, 1000000,
CONFIG_DEFAULT_SPI_MODE);
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;
reset_timer_masked();
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_masked() < CONFIG_SYS_SPI_WRITE_TOUT);
if (buf[1] & 1)
printf ("*** spi_write: Time out while writing!\n");
spi_release_bus(slave);
spi_free_slave(slave);
return len;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment