1 // SPDX-License-Identifier: GPL-2.0+
4 * Corscience GmbH & Co. KG, <www.corscience.de>
5 * Andreas Bießmann <andreas.biessmann@corscience.de>
10 #include <u-boot/crc.h>
12 #include "tricorder-eeprom.h"
14 static inline void warn_wrong_value(const char *msg, unsigned int a,
17 printf("Expected EEPROM %s %08x, got %08x\n", msg, a, b);
20 static int handle_eeprom_v0(struct tricorder_eeprom *eeprom)
22 struct tricorder_eeprom_v0 {
26 char board_name[TRICORDER_BOARD_NAME_LENGTH];
27 char board_version[TRICORDER_BOARD_VERSION_LENGTH];
28 char board_serial[TRICORDER_BOARD_SERIAL_LENGTH];
33 printf("Old EEPROM (v0), consider rewrite!\n");
35 if (be16_to_cpu(eeprom->length) != sizeof(eepromv0)) {
36 warn_wrong_value("length", sizeof(eepromv0),
37 be16_to_cpu(eeprom->length));
41 memcpy(&eepromv0, eeprom, sizeof(eepromv0));
43 crc = crc32(0L, (unsigned char *)&eepromv0,
44 sizeof(eepromv0) - sizeof(eepromv0.crc32));
45 if (be32_to_cpu(eepromv0.crc32) != crc) {
46 warn_wrong_value("CRC", be32_to_cpu(eepromv0.crc32),
51 /* Ok the content is correct, do the conversion */
52 memset(eeprom->interface_version, 0x0,
53 TRICORDER_INTERFACE_VERSION_LENGTH);
54 crc = crc32(0L, (unsigned char *)eeprom, TRICORDER_EEPROM_CRC_SIZE);
55 eeprom->crc32 = cpu_to_be32(crc);
60 static int handle_eeprom_v1(struct tricorder_eeprom *eeprom)
64 if (be16_to_cpu(eeprom->length) != TRICORDER_EEPROM_SIZE) {
65 warn_wrong_value("length", TRICORDER_EEPROM_SIZE,
66 be16_to_cpu(eeprom->length));
70 crc = crc32(0L, (unsigned char *)eeprom, TRICORDER_EEPROM_CRC_SIZE);
71 if (be32_to_cpu(eeprom->crc32) != crc) {
72 warn_wrong_value("CRC", be32_to_cpu(eeprom->crc32), crc);
79 int tricorder_get_eeprom(int addr, struct tricorder_eeprom *eeprom)
81 unsigned int bus = i2c_get_bus_num();
82 i2c_set_bus_num(CONFIG_SYS_EEPROM_BUS_NUM);
84 memset(eeprom, 0, TRICORDER_EEPROM_SIZE);
86 i2c_read(addr, 0, 2, (unsigned char *)eeprom, TRICORDER_EEPROM_SIZE);
89 if (be32_to_cpu(eeprom->magic) != TRICORDER_EEPROM_MAGIC) {
90 warn_wrong_value("magic", TRICORDER_EEPROM_MAGIC,
91 be32_to_cpu(eeprom->magic));
95 switch (be16_to_cpu(eeprom->version)) {
97 return handle_eeprom_v0(eeprom);
99 return handle_eeprom_v1(eeprom);
101 warn_wrong_value("version", TRICORDER_EEPROM_VERSION,
102 be16_to_cpu(eeprom->version));
107 #if !defined(CONFIG_SPL)
108 int tricorder_eeprom_read(unsigned devaddr)
110 struct tricorder_eeprom eeprom;
111 int ret = tricorder_get_eeprom(devaddr, &eeprom);
116 printf("Board type: %.*s\n",
117 sizeof(eeprom.board_name), eeprom.board_name);
118 printf("Board version: %.*s\n",
119 sizeof(eeprom.board_version), eeprom.board_version);
120 printf("Board serial: %.*s\n",
121 sizeof(eeprom.board_serial), eeprom.board_serial);
122 printf("Board interface version: %.*s\n",
123 sizeof(eeprom.interface_version),
124 eeprom.interface_version);
129 int tricorder_eeprom_write(unsigned devaddr, const char *name,
130 const char *version, const char *serial, const char *interface)
132 struct tricorder_eeprom eeprom, eeprom_verify;
139 memset(eeprom, 0, TRICORDER_EEPROM_SIZE);
140 memset(eeprom_verify, 0, TRICORDER_EEPROM_SIZE);
142 eeprom.magic = cpu_to_be32(TRICORDER_EEPROM_MAGIC);
143 eeprom.length = cpu_to_be16(TRICORDER_EEPROM_SIZE);
144 eeprom.version = cpu_to_be16(TRICORDER_EEPROM_VERSION);
146 length = min(sizeof(eeprom.board_name), strlen(name));
147 strncpy(eeprom.board_name, name, length);
149 length = min(sizeof(eeprom.board_version), strlen(version));
150 strncpy(eeprom.board_version, version, length);
152 length = min(sizeof(eeprom.board_serial), strlen(serial));
153 strncpy(eeprom.board_serial, serial, length);
156 length = min(sizeof(eeprom.interface_version),
158 strncpy(eeprom.interface_version, interface, length);
161 crc = crc32(0L, (unsigned char *)&eeprom, TRICORDER_EEPROM_CRC_SIZE);
162 eeprom.crc32 = cpu_to_be32(crc);
165 puts("Tricorder EEPROM content:\n");
166 print_buffer(0, &eeprom, 1, sizeof(eeprom), 16);
169 eeprom_init(CONFIG_SYS_EEPROM_BUS_NUM);
171 ret = eeprom_write(devaddr, 0, (unsigned char *)&eeprom,
172 TRICORDER_EEPROM_SIZE);
174 printf("Tricorder: Could not write EEPROM content!\n");
176 ret = eeprom_read(devaddr, 0, (unsigned char *)&eeprom_verify,
177 TRICORDER_EEPROM_SIZE);
179 printf("Tricorder: Could not read EEPROM content!\n");
181 if (memcmp(&eeprom, &eeprom_verify, sizeof(eeprom)) != 0) {
182 printf("Tricorder: Could not verify EEPROM content!\n");
189 int do_tricorder_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
192 ulong dev_addr = simple_strtoul(argv[2], NULL, 16);
194 if (strcmp(argv[1], "read") == 0)
195 return tricorder_eeprom_read(dev_addr);
196 } else if (argc == 6 || argc == 7) {
197 ulong dev_addr = simple_strtoul(argv[2], NULL, 16);
198 char *name = argv[3];
199 char *version = argv[4];
200 char *serial = argv[5];
201 char *interface = NULL;
206 if (strcmp(argv[1], "write") == 0)
207 return tricorder_eeprom_write(dev_addr, name, version,
211 return CMD_RET_USAGE;
215 tricordereeprom, 7, 1, do_tricorder_eeprom,
218 " - read Tricorder EEPROM at devaddr and print content\n"
219 "tricordereeprom write devaddr name version serial [interface]\n"
220 " - write Tricorder EEPROM at devaddr with 'name', 'version'"
222 " optional add an HW interface parameter"
224 #endif /* CONFIG_SPL */