board: cssi: Refactor EEPROM read
On cmpc885 board, the ethernet addresses are stored in an EEPROM that is accessed through SPI. A 3 bytes command is sent to the chip then the content gets read. At the time being a single block access is performed, ignoring the first 3 bytes read. Reword the SPI transfer to first send 3 bytes then receive the content of the EEPROM so that there don't be 3 dummy bytes at the beginning of the buffer. And move the function into common.c so that it can be reused by the board that will be added in a future patch. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
This commit is contained in:
parent
3155b0af4e
commit
4b6a5388da
3 changed files with 40 additions and 31 deletions
|
@ -147,55 +147,28 @@ int checkboard(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define SPI_EEPROM_READ 0x03
|
||||
#define MAX_SPI_BYTES 0x20
|
||||
|
||||
#define EE_OFF_MAC1 0x13
|
||||
#define EE_OFF_MAC2 0x19
|
||||
#define EE_OFF_MAC1 0x10
|
||||
#define EE_OFF_MAC2 0x16
|
||||
|
||||
/* Reads MAC addresses from SPI EEPROM */
|
||||
static int setup_mac(void)
|
||||
{
|
||||
struct udevice *eeprom;
|
||||
struct spi_slave *slave;
|
||||
char name[30], *str;
|
||||
uchar din[MAX_SPI_BYTES];
|
||||
uchar dout[MAX_SPI_BYTES] = {SPI_EEPROM_READ, 0, 0};
|
||||
int bitlen = 256, cs = 0, mode = 0, bus = 0, ret;
|
||||
int ret;
|
||||
unsigned long ident = 0x08005120;
|
||||
|
||||
snprintf(name, sizeof(name), "generic_%d:%d", bus, cs);
|
||||
|
||||
str = strdup(name);
|
||||
if (!str)
|
||||
return -1;
|
||||
|
||||
ret = uclass_get_device(UCLASS_SPI, 0, &eeprom);
|
||||
if (ret) {
|
||||
printf("Could not enable Serial Peripheral Interface (SPI).\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = _spi_get_bus_and_cs(bus, cs, 1000000, mode, "spi_generic_drv", str, &eeprom, &slave);
|
||||
ret = read_eeprom(din, sizeof(din));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = spi_claim_bus(slave);
|
||||
|
||||
ret = spi_xfer(slave, bitlen, dout, din, SPI_XFER_BEGIN | SPI_XFER_END);
|
||||
if (ret) {
|
||||
printf("Error %d during SPI transaction\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (memcmp(din + EE_OFF_MAC1, &ident, sizeof(ident)) == 0)
|
||||
eth_env_set_enetaddr("ethaddr", din + EE_OFF_MAC1);
|
||||
|
||||
if (memcmp(din + EE_OFF_MAC2, &ident, sizeof(ident)) == 0)
|
||||
eth_env_set_enetaddr("eth1addr", din + EE_OFF_MAC2);
|
||||
|
||||
spi_release_bus(slave);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,11 @@
|
|||
* Common specific routines for the CS Group boards
|
||||
*/
|
||||
|
||||
#include <dm.h>
|
||||
#include <fdt_support.h>
|
||||
#include <spi.h>
|
||||
|
||||
#define SPI_EEPROM_READ 0x03
|
||||
|
||||
static int fdt_set_node_and_value(void *blob, char *node, const char *prop,
|
||||
void *var, int size)
|
||||
|
@ -60,3 +64,34 @@ void ft_cleanup(void *blob, unsigned long id, const char *prop, const char *comp
|
|||
|
||||
fdt_set_node_and_value(blob, "/", prop, &id, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
int read_eeprom(u8 *din, int len)
|
||||
{
|
||||
struct udevice *eeprom;
|
||||
struct spi_slave *slave;
|
||||
uchar dout[3] = {SPI_EEPROM_READ, 0, 0};
|
||||
int ret;
|
||||
|
||||
ret = uclass_get_device(UCLASS_SPI, 0, &eeprom);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = _spi_get_bus_and_cs(0, 0, 1000000, 0, "spi_generic_drv",
|
||||
"generic_0:0", &eeprom, &slave);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = spi_claim_bus(slave);
|
||||
|
||||
ret = spi_xfer(slave, sizeof(dout) << 3, dout, NULL, SPI_XFER_BEGIN);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = spi_xfer(slave, len << 3, NULL, din, SPI_XFER_END);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
spi_release_bus(slave);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -4,5 +4,6 @@
|
|||
#define _BOARD_CSSI_COMMON_H
|
||||
|
||||
void ft_cleanup(void *blob, unsigned long id, const char *prop, const char *compatible);
|
||||
int read_eeprom(u8 *din, int len);
|
||||
|
||||
#endif /* _BOARD_CSSI_COMMON_H */
|
||||
|
|
Loading…
Reference in a new issue