]> git.ipfire.org Git - thirdparty/u-boot.git/blame - board/corscience/tricorder/tricorder-eeprom.c
command: Remove the cmd_tbl_t typedef
[thirdparty/u-boot.git] / board / corscience / tricorder / tricorder-eeprom.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
459f1da8
AB
2/*
3 * (C) Copyright 2013
4 * Corscience GmbH & Co. KG, <www.corscience.de>
5 * Andreas Bießmann <andreas.biessmann@corscience.de>
459f1da8
AB
6 */
7#include <common.h>
09140113 8#include <command.h>
cb3ef681 9#include <eeprom.h>
459f1da8 10#include <i2c.h>
3db71108 11#include <u-boot/crc.h>
459f1da8
AB
12
13#include "tricorder-eeprom.h"
14
15static inline void warn_wrong_value(const char *msg, unsigned int a,
16 unsigned int b)
17{
18 printf("Expected EEPROM %s %08x, got %08x\n", msg, a, b);
19}
20
21static int handle_eeprom_v0(struct tricorder_eeprom *eeprom)
22{
23 struct tricorder_eeprom_v0 {
24 uint32_t magic;
25 uint16_t length;
26 uint16_t version;
27 char board_name[TRICORDER_BOARD_NAME_LENGTH];
28 char board_version[TRICORDER_BOARD_VERSION_LENGTH];
29 char board_serial[TRICORDER_BOARD_SERIAL_LENGTH];
30 uint32_t crc32;
31 } __packed eepromv0;
32 uint32_t crc;
33
34 printf("Old EEPROM (v0), consider rewrite!\n");
35
36 if (be16_to_cpu(eeprom->length) != sizeof(eepromv0)) {
37 warn_wrong_value("length", sizeof(eepromv0),
38 be16_to_cpu(eeprom->length));
39 return 1;
40 }
41
42 memcpy(&eepromv0, eeprom, sizeof(eepromv0));
43
44 crc = crc32(0L, (unsigned char *)&eepromv0,
45 sizeof(eepromv0) - sizeof(eepromv0.crc32));
46 if (be32_to_cpu(eepromv0.crc32) != crc) {
47 warn_wrong_value("CRC", be32_to_cpu(eepromv0.crc32),
48 crc);
49 return 1;
50 }
51
52 /* Ok the content is correct, do the conversion */
53 memset(eeprom->interface_version, 0x0,
54 TRICORDER_INTERFACE_VERSION_LENGTH);
55 crc = crc32(0L, (unsigned char *)eeprom, TRICORDER_EEPROM_CRC_SIZE);
56 eeprom->crc32 = cpu_to_be32(crc);
57
58 return 0;
59}
60
61static int handle_eeprom_v1(struct tricorder_eeprom *eeprom)
62{
63 uint32_t crc;
64
65 if (be16_to_cpu(eeprom->length) != TRICORDER_EEPROM_SIZE) {
66 warn_wrong_value("length", TRICORDER_EEPROM_SIZE,
67 be16_to_cpu(eeprom->length));
68 return 1;
69 }
70
71 crc = crc32(0L, (unsigned char *)eeprom, TRICORDER_EEPROM_CRC_SIZE);
72 if (be32_to_cpu(eeprom->crc32) != crc) {
73 warn_wrong_value("CRC", be32_to_cpu(eeprom->crc32), crc);
74 return 1;
75 }
76
77 return 0;
78}
79
80int tricorder_get_eeprom(int addr, struct tricorder_eeprom *eeprom)
81{
459f1da8
AB
82 unsigned int bus = i2c_get_bus_num();
83 i2c_set_bus_num(CONFIG_SYS_EEPROM_BUS_NUM);
459f1da8
AB
84
85 memset(eeprom, 0, TRICORDER_EEPROM_SIZE);
86
87 i2c_read(addr, 0, 2, (unsigned char *)eeprom, TRICORDER_EEPROM_SIZE);
459f1da8 88 i2c_set_bus_num(bus);
459f1da8
AB
89
90 if (be32_to_cpu(eeprom->magic) != TRICORDER_EEPROM_MAGIC) {
91 warn_wrong_value("magic", TRICORDER_EEPROM_MAGIC,
92 be32_to_cpu(eeprom->magic));
93 return 1;
94 }
95
96 switch (be16_to_cpu(eeprom->version)) {
97 case 0:
98 return handle_eeprom_v0(eeprom);
99 case 1:
100 return handle_eeprom_v1(eeprom);
101 default:
102 warn_wrong_value("version", TRICORDER_EEPROM_VERSION,
103 be16_to_cpu(eeprom->version));
104 return 1;
105 }
106}
107
108#if !defined(CONFIG_SPL)
109int tricorder_eeprom_read(unsigned devaddr)
110{
111 struct tricorder_eeprom eeprom;
112 int ret = tricorder_get_eeprom(devaddr, &eeprom);
113
114 if (ret)
115 return ret;
116
117 printf("Board type: %.*s\n",
118 sizeof(eeprom.board_name), eeprom.board_name);
119 printf("Board version: %.*s\n",
120 sizeof(eeprom.board_version), eeprom.board_version);
121 printf("Board serial: %.*s\n",
122 sizeof(eeprom.board_serial), eeprom.board_serial);
123 printf("Board interface version: %.*s\n",
124 sizeof(eeprom.interface_version),
125 eeprom.interface_version);
126
127 return ret;
128}
129
130int tricorder_eeprom_write(unsigned devaddr, const char *name,
131 const char *version, const char *serial, const char *interface)
132{
133 struct tricorder_eeprom eeprom, eeprom_verify;
134 size_t length;
135 uint32_t crc;
136 int ret;
137 unsigned char *p;
138 int i;
459f1da8
AB
139
140 memset(eeprom, 0, TRICORDER_EEPROM_SIZE);
141 memset(eeprom_verify, 0, TRICORDER_EEPROM_SIZE);
142
143 eeprom.magic = cpu_to_be32(TRICORDER_EEPROM_MAGIC);
144 eeprom.length = cpu_to_be16(TRICORDER_EEPROM_SIZE);
145 eeprom.version = cpu_to_be16(TRICORDER_EEPROM_VERSION);
146
147 length = min(sizeof(eeprom.board_name), strlen(name));
148 strncpy(eeprom.board_name, name, length);
149
150 length = min(sizeof(eeprom.board_version), strlen(version));
151 strncpy(eeprom.board_version, version, length);
152
153 length = min(sizeof(eeprom.board_serial), strlen(serial));
154 strncpy(eeprom.board_serial, serial, length);
155
156 if (interface) {
157 length = min(sizeof(eeprom.interface_version),
158 strlen(interface));
159 strncpy(eeprom.interface_version, interface, length);
160 }
161
162 crc = crc32(0L, (unsigned char *)&eeprom, TRICORDER_EEPROM_CRC_SIZE);
163 eeprom.crc32 = cpu_to_be32(crc);
164
165#if defined(DEBUG)
166 puts("Tricorder EEPROM content:\n");
167 print_buffer(0, &eeprom, 1, sizeof(eeprom), 16);
168#endif
169
8961dac9 170 eeprom_init(CONFIG_SYS_EEPROM_BUS_NUM);
459f1da8 171
8961dac9
AB
172 ret = eeprom_write(devaddr, 0, (unsigned char *)&eeprom,
173 TRICORDER_EEPROM_SIZE);
174 if (ret)
175 printf("Tricorder: Could not write EEPROM content!\n");
459f1da8 176
8961dac9 177 ret = eeprom_read(devaddr, 0, (unsigned char *)&eeprom_verify,
459f1da8 178 TRICORDER_EEPROM_SIZE);
8961dac9
AB
179 if (ret)
180 printf("Tricorder: Could not read EEPROM content!\n");
459f1da8
AB
181
182 if (memcmp(&eeprom, &eeprom_verify, sizeof(eeprom)) != 0) {
183 printf("Tricorder: Could not verify EEPROM content!\n");
184 ret = 1;
185 }
186
459f1da8
AB
187 return ret;
188}
189
09140113 190int do_tricorder_eeprom(struct cmd_tbl *cmdtp, int flag, int argc, char *argv[])
459f1da8
AB
191{
192 if (argc == 3) {
193 ulong dev_addr = simple_strtoul(argv[2], NULL, 16);
8961dac9 194
63a7578e
MY
195 if (strcmp(argv[1], "read") == 0)
196 return tricorder_eeprom_read(dev_addr);
459f1da8
AB
197 } else if (argc == 6 || argc == 7) {
198 ulong dev_addr = simple_strtoul(argv[2], NULL, 16);
199 char *name = argv[3];
200 char *version = argv[4];
201 char *serial = argv[5];
202 char *interface = NULL;
459f1da8
AB
203
204 if (argc == 7)
205 interface = argv[6];
206
63a7578e
MY
207 if (strcmp(argv[1], "write") == 0)
208 return tricorder_eeprom_write(dev_addr, name, version,
209 serial, interface);
459f1da8
AB
210 }
211
212 return CMD_RET_USAGE;
213}
214
215U_BOOT_CMD(
216 tricordereeprom, 7, 1, do_tricorder_eeprom,
217 "Tricorder EEPROM",
218 "read devaddr\n"
219 " - read Tricorder EEPROM at devaddr and print content\n"
220 "tricordereeprom write devaddr name version serial [interface]\n"
221 " - write Tricorder EEPROM at devaddr with 'name', 'version'"
222 "and 'serial'\n"
223 " optional add an HW interface parameter"
224);
225#endif /* CONFIG_SPL */