1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2014 Gateworks Corporation
4 * Author: Tim Harvey <tharvey@gateworks.com>
11 #include <asm/bitops.h>
14 #include "ventana_eeprom.h"
16 /* read ventana EEPROM, check for validity, and return baseboard type */
18 read_eeprom(int bus
, struct ventana_board_info
*info
)
24 unsigned char *buf
= (unsigned char *)info
;
26 memset(info
, 0, sizeof(*info
));
29 * On a board with a missing/depleted backup battery for GSC, the
30 * board may be ready to probe the GSC before its firmware is
31 * running. We will wait here indefinately for the GSC/EEPROM.
34 if (0 == i2c_set_bus_num(bus
) &&
35 0 == i2c_probe(GSC_EEPROM_ADDR
))
40 /* read eeprom config section */
41 if (gsc_i2c_read(GSC_EEPROM_ADDR
, 0x00, 1, buf
, sizeof(*info
))) {
42 puts("EEPROM: Failed to read EEPROM\n");
47 if (info
->model
[0] != 'G' || info
->model
[1] != 'W') {
48 puts("EEPROM: Invalid Model in EEPROM\n");
52 /* validate checksum */
53 for (chksum
= 0, i
= 0; i
< sizeof(*info
)-2; i
++)
55 if ((info
->chksum
[0] != chksum
>>8) ||
56 (info
->chksum
[1] != (chksum
&0xff))) {
57 puts("EEPROM: Failed EEPROM checksum\n");
61 /* original GW5400-A prototype */
62 baseboard
= info
->model
[3];
63 if (strncasecmp((const char *)info
->model
, "GW5400-A", 8) == 0)
68 case '0': /* original GW5400-A prototype */
84 if (info
->model
[4] == '1') {
87 } else if (info
->model
[4] == '2') {
90 } else if (info
->model
[4] == '3') {
96 if (info
->model
[4] == '0')
100 if (info
->model
[4] == '0' && info
->model
[5] == '3')
102 if (info
->model
[4] == '0' && info
->model
[5] == '4')
109 /* list of config bits that the bootloader will remove from dtb if not set */
110 struct ventana_eeprom_config econfig
[] = {
111 { "eth0", "ethernet0", EECONFIG_ETH0
},
112 { "usb0", NULL
, EECONFIG_USB0
},
113 { "usb1", NULL
, EECONFIG_USB1
},
114 { "mmc0", NULL
, EECONFIG_SD0
},
115 { "mmc1", NULL
, EECONFIG_SD1
},
116 { "mmc2", NULL
, EECONFIG_SD2
},
117 { "mmc3", NULL
, EECONFIG_SD3
},
121 #if defined(CONFIG_CMD_EECONFIG) && !defined(CONFIG_SPL_BUILD)
122 static struct ventana_eeprom_config
*get_config(const char *name
)
124 struct ventana_eeprom_config
*cfg
= econfig
;
127 if (0 == strcmp(name
, cfg
->name
))
134 static u8 econfig_bytes
[sizeof(ventana_info
.config
)];
135 static int econfig_init
= -1;
137 static int do_econfig(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
139 struct ventana_eeprom_config
*cfg
;
140 struct ventana_board_info
*info
= &ventana_info
;
144 return CMD_RET_USAGE
;
147 if (econfig_init
!= 1) {
148 memcpy(econfig_bytes
, info
->config
, sizeof(econfig_bytes
));
153 if ((strncmp(argv
[1], "list", 4) == 0)) {
156 printf("%s: %d\n", cfg
->name
,
157 test_bit(cfg
->bit
, econfig_bytes
) ? 1 : 0);
163 else if ((strncmp(argv
[1], "save", 4) == 0)) {
164 unsigned char *buf
= (unsigned char *)info
;
167 /* calculate new checksum */
168 memcpy(info
->config
, econfig_bytes
, sizeof(econfig_bytes
));
169 for (chksum
= 0, i
= 0; i
< sizeof(*info
)-2; i
++)
171 debug("old chksum:0x%04x\n",
172 (info
->chksum
[0] << 8) | info
->chksum
[1]);
173 debug("new chksum:0x%04x\n", chksum
);
174 info
->chksum
[0] = chksum
>> 8;
175 info
->chksum
[1] = chksum
& 0xff;
177 /* write new config data */
178 if (gsc_i2c_write(GSC_EEPROM_ADDR
, info
->config
- (u8
*)info
,
179 1, econfig_bytes
, sizeof(econfig_bytes
))) {
180 printf("EEPROM: Failed updating config\n");
181 return CMD_RET_FAILURE
;
184 /* write new config data */
185 if (gsc_i2c_write(GSC_EEPROM_ADDR
, info
->chksum
- (u8
*)info
,
186 1, info
->chksum
, 2)) {
187 printf("EEPROM: Failed updating checksum\n");
188 return CMD_RET_FAILURE
;
191 printf("Config saved to EEPROM\n");
195 else if (argc
== 2) {
196 cfg
= get_config(argv
[1]);
198 printf("%s: %d\n", cfg
->name
,
199 test_bit(cfg
->bit
, econfig_bytes
) ? 1 : 0);
201 printf("invalid config: %s\n", argv
[1]);
202 return CMD_RET_FAILURE
;
207 else if (argc
== 3) {
208 cfg
= get_config(argv
[1]);
210 if (simple_strtol(argv
[2], NULL
, 10)) {
211 test_and_set_bit(cfg
->bit
, econfig_bytes
);
212 printf("Enabled %s\n", cfg
->name
);
214 test_and_clear_bit(cfg
->bit
, econfig_bytes
);
215 printf("Disabled %s\n", cfg
->name
);
218 printf("invalid config: %s\n", argv
[1]);
219 return CMD_RET_FAILURE
;
224 return CMD_RET_USAGE
;
226 return CMD_RET_SUCCESS
;
230 econfig
, 3, 0, do_econfig
,
231 "EEPROM configuration",
232 "list - list config\n"
233 "save - save config to EEPROM\n"
234 "<name> - get config 'name'\n"
235 "<name> [0|1] - set config 'name' to value\n"
238 #endif /* CONFIG_CMD_EECONFIG */