123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- // SPDX-License-Identifier: GPL-2.0+
- /*
- * (C) Copyright 2013
- * Corscience GmbH & Co. KG, <www.corscience.de>
- * Andreas Bießmann <andreas.biessmann@corscience.de>
- */
- #include <common.h>
- #include <i2c.h>
- #include "tricorder-eeprom.h"
- static inline void warn_wrong_value(const char *msg, unsigned int a,
- unsigned int b)
- {
- printf("Expected EEPROM %s %08x, got %08x\n", msg, a, b);
- }
- static int handle_eeprom_v0(struct tricorder_eeprom *eeprom)
- {
- struct tricorder_eeprom_v0 {
- uint32_t magic;
- uint16_t length;
- uint16_t version;
- char board_name[TRICORDER_BOARD_NAME_LENGTH];
- char board_version[TRICORDER_BOARD_VERSION_LENGTH];
- char board_serial[TRICORDER_BOARD_SERIAL_LENGTH];
- uint32_t crc32;
- } __packed eepromv0;
- uint32_t crc;
- printf("Old EEPROM (v0), consider rewrite!\n");
- if (be16_to_cpu(eeprom->length) != sizeof(eepromv0)) {
- warn_wrong_value("length", sizeof(eepromv0),
- be16_to_cpu(eeprom->length));
- return 1;
- }
- memcpy(&eepromv0, eeprom, sizeof(eepromv0));
- crc = crc32(0L, (unsigned char *)&eepromv0,
- sizeof(eepromv0) - sizeof(eepromv0.crc32));
- if (be32_to_cpu(eepromv0.crc32) != crc) {
- warn_wrong_value("CRC", be32_to_cpu(eepromv0.crc32),
- crc);
- return 1;
- }
- /* Ok the content is correct, do the conversion */
- memset(eeprom->interface_version, 0x0,
- TRICORDER_INTERFACE_VERSION_LENGTH);
- crc = crc32(0L, (unsigned char *)eeprom, TRICORDER_EEPROM_CRC_SIZE);
- eeprom->crc32 = cpu_to_be32(crc);
- return 0;
- }
- static int handle_eeprom_v1(struct tricorder_eeprom *eeprom)
- {
- uint32_t crc;
- if (be16_to_cpu(eeprom->length) != TRICORDER_EEPROM_SIZE) {
- warn_wrong_value("length", TRICORDER_EEPROM_SIZE,
- be16_to_cpu(eeprom->length));
- return 1;
- }
- crc = crc32(0L, (unsigned char *)eeprom, TRICORDER_EEPROM_CRC_SIZE);
- if (be32_to_cpu(eeprom->crc32) != crc) {
- warn_wrong_value("CRC", be32_to_cpu(eeprom->crc32), crc);
- return 1;
- }
- return 0;
- }
- int tricorder_get_eeprom(int addr, struct tricorder_eeprom *eeprom)
- {
- unsigned int bus = i2c_get_bus_num();
- i2c_set_bus_num(CONFIG_SYS_EEPROM_BUS_NUM);
- memset(eeprom, 0, TRICORDER_EEPROM_SIZE);
- i2c_read(addr, 0, 2, (unsigned char *)eeprom, TRICORDER_EEPROM_SIZE);
- i2c_set_bus_num(bus);
- if (be32_to_cpu(eeprom->magic) != TRICORDER_EEPROM_MAGIC) {
- warn_wrong_value("magic", TRICORDER_EEPROM_MAGIC,
- be32_to_cpu(eeprom->magic));
- return 1;
- }
- switch (be16_to_cpu(eeprom->version)) {
- case 0:
- return handle_eeprom_v0(eeprom);
- case 1:
- return handle_eeprom_v1(eeprom);
- default:
- warn_wrong_value("version", TRICORDER_EEPROM_VERSION,
- be16_to_cpu(eeprom->version));
- return 1;
- }
- }
- #if !defined(CONFIG_SPL)
- int tricorder_eeprom_read(unsigned devaddr)
- {
- struct tricorder_eeprom eeprom;
- int ret = tricorder_get_eeprom(devaddr, &eeprom);
- if (ret)
- return ret;
- printf("Board type: %.*s\n",
- sizeof(eeprom.board_name), eeprom.board_name);
- printf("Board version: %.*s\n",
- sizeof(eeprom.board_version), eeprom.board_version);
- printf("Board serial: %.*s\n",
- sizeof(eeprom.board_serial), eeprom.board_serial);
- printf("Board interface version: %.*s\n",
- sizeof(eeprom.interface_version),
- eeprom.interface_version);
- return ret;
- }
- int tricorder_eeprom_write(unsigned devaddr, const char *name,
- const char *version, const char *serial, const char *interface)
- {
- struct tricorder_eeprom eeprom, eeprom_verify;
- size_t length;
- uint32_t crc;
- int ret;
- unsigned char *p;
- int i;
- memset(eeprom, 0, TRICORDER_EEPROM_SIZE);
- memset(eeprom_verify, 0, TRICORDER_EEPROM_SIZE);
- eeprom.magic = cpu_to_be32(TRICORDER_EEPROM_MAGIC);
- eeprom.length = cpu_to_be16(TRICORDER_EEPROM_SIZE);
- eeprom.version = cpu_to_be16(TRICORDER_EEPROM_VERSION);
- length = min(sizeof(eeprom.board_name), strlen(name));
- strncpy(eeprom.board_name, name, length);
- length = min(sizeof(eeprom.board_version), strlen(version));
- strncpy(eeprom.board_version, version, length);
- length = min(sizeof(eeprom.board_serial), strlen(serial));
- strncpy(eeprom.board_serial, serial, length);
- if (interface) {
- length = min(sizeof(eeprom.interface_version),
- strlen(interface));
- strncpy(eeprom.interface_version, interface, length);
- }
- crc = crc32(0L, (unsigned char *)&eeprom, TRICORDER_EEPROM_CRC_SIZE);
- eeprom.crc32 = cpu_to_be32(crc);
- #if defined(DEBUG)
- puts("Tricorder EEPROM content:\n");
- print_buffer(0, &eeprom, 1, sizeof(eeprom), 16);
- #endif
- eeprom_init(CONFIG_SYS_EEPROM_BUS_NUM);
- ret = eeprom_write(devaddr, 0, (unsigned char *)&eeprom,
- TRICORDER_EEPROM_SIZE);
- if (ret)
- printf("Tricorder: Could not write EEPROM content!\n");
- ret = eeprom_read(devaddr, 0, (unsigned char *)&eeprom_verify,
- TRICORDER_EEPROM_SIZE);
- if (ret)
- printf("Tricorder: Could not read EEPROM content!\n");
- if (memcmp(&eeprom, &eeprom_verify, sizeof(eeprom)) != 0) {
- printf("Tricorder: Could not verify EEPROM content!\n");
- ret = 1;
- }
- return ret;
- }
- int do_tricorder_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
- {
- if (argc == 3) {
- ulong dev_addr = simple_strtoul(argv[2], NULL, 16);
- if (strcmp(argv[1], "read") == 0)
- return tricorder_eeprom_read(dev_addr);
- } else if (argc == 6 || argc == 7) {
- ulong dev_addr = simple_strtoul(argv[2], NULL, 16);
- char *name = argv[3];
- char *version = argv[4];
- char *serial = argv[5];
- char *interface = NULL;
- if (argc == 7)
- interface = argv[6];
- if (strcmp(argv[1], "write") == 0)
- return tricorder_eeprom_write(dev_addr, name, version,
- serial, interface);
- }
- return CMD_RET_USAGE;
- }
- U_BOOT_CMD(
- tricordereeprom, 7, 1, do_tricorder_eeprom,
- "Tricorder EEPROM",
- "read devaddr\n"
- " - read Tricorder EEPROM at devaddr and print content\n"
- "tricordereeprom write devaddr name version serial [interface]\n"
- " - write Tricorder EEPROM at devaddr with 'name', 'version'"
- "and 'serial'\n"
- " optional add an HW interface parameter"
- );
- #endif /* CONFIG_SPL */
|