2 * Copyright (C) 2014 Gateworks Corporation
3 * Author: Tim Harvey <tharvey@gateworks.com>
5 * SPDX-License-Identifier: GPL-2.0+
12 #include <asm/bitops.h>
15 #include "ventana_eeprom.h"
17 /* read ventana EEPROM, check for validity, and return baseboard type */
19 read_eeprom(int bus
, struct ventana_board_info
*info
)
25 unsigned char *buf
= (unsigned char *)info
;
27 memset(info
, 0, sizeof(*info
));
30 * On a board with a missing/depleted backup battery for GSC, the
31 * board may be ready to probe the GSC before its firmware is
32 * running. We will wait here indefinately for the GSC/EEPROM.
35 if (0 == i2c_set_bus_num(bus
) &&
36 0 == i2c_probe(GSC_EEPROM_ADDR
))
41 /* read eeprom config section */
42 if (gsc_i2c_read(GSC_EEPROM_ADDR
, 0x00, 1, buf
, sizeof(*info
))) {
43 puts("EEPROM: Failed to read EEPROM\n");
48 if (info
->model
[0] != 'G' || info
->model
[1] != 'W') {
49 puts("EEPROM: Invalid Model in EEPROM\n");
53 /* validate checksum */
54 for (chksum
= 0, i
= 0; i
< sizeof(*info
)-2; i
++)
56 if ((info
->chksum
[0] != chksum
>>8) ||
57 (info
->chksum
[1] != (chksum
&0xff))) {
58 puts("EEPROM: Failed EEPROM checksum\n");
62 /* original GW5400-A prototype */
63 baseboard
= info
->model
[3];
64 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') {
93 printf("EEPROM: Unknown model in EEPROM: %s\n", info
->model
);
100 /* list of config bits that the bootloader will remove from dtb if not set */
101 struct ventana_eeprom_config econfig
[] = {
102 { "eth0", "ethernet0", EECONFIG_ETH0
},
103 { "eth1", "ethernet1", EECONFIG_ETH1
},
104 { "sata", "ahci0", EECONFIG_SATA
},
105 { "pcie", NULL
, EECONFIG_PCIE
},
106 { "lvds0", NULL
, EECONFIG_LVDS0
},
107 { "lvds1", NULL
, EECONFIG_LVDS1
},
108 { "usb0", NULL
, EECONFIG_USB0
},
109 { "usb1", NULL
, EECONFIG_USB1
},
110 { "mmc0", NULL
, EECONFIG_SD0
},
111 { "mmc1", NULL
, EECONFIG_SD1
},
112 { "mmc2", NULL
, EECONFIG_SD2
},
113 { "mmc3", NULL
, EECONFIG_SD3
},
114 { "uart0", NULL
, EECONFIG_UART0
},
115 { "uart1", NULL
, EECONFIG_UART1
},
116 { "uart2", NULL
, EECONFIG_UART2
},
117 { "uart3", NULL
, EECONFIG_UART3
},
118 { "uart4", NULL
, EECONFIG_UART4
},
119 { "ipu0", NULL
, EECONFIG_IPU0
},
120 { "ipu1", NULL
, EECONFIG_IPU1
},
121 { "can0", NULL
, EECONFIG_FLEXCAN
},
122 { "i2c0", NULL
, EECONFIG_I2C0
},
123 { "i2c1", NULL
, EECONFIG_I2C1
},
124 { "i2c2", NULL
, EECONFIG_I2C2
},
125 { "vpu", NULL
, EECONFIG_VPU
},
126 { "csi0", NULL
, EECONFIG_CSI0
},
127 { "csi1", NULL
, EECONFIG_CSI1
},
128 { "spi0", NULL
, EECONFIG_ESPCI0
},
129 { "spi1", NULL
, EECONFIG_ESPCI1
},
130 { "spi2", NULL
, EECONFIG_ESPCI2
},
131 { "spi3", NULL
, EECONFIG_ESPCI3
},
132 { "spi4", NULL
, EECONFIG_ESPCI4
},
133 { "spi5", NULL
, EECONFIG_ESPCI5
},
134 { "gps", "pps", EECONFIG_GPS
},
135 { "hdmi_in", NULL
, EECONFIG_HDMI_IN
},
136 { "hdmi_out", NULL
, EECONFIG_HDMI_OUT
},
137 { "cvbs_in", NULL
, EECONFIG_VID_IN
},
138 { "cvbs_out", NULL
, EECONFIG_VID_OUT
},
139 { "nand", NULL
, EECONFIG_NAND
},
143 #ifdef CONFIG_CMD_EECONFIG
144 static struct ventana_eeprom_config
*get_config(const char *name
)
146 struct ventana_eeprom_config
*cfg
= econfig
;
149 if (0 == strcmp(name
, cfg
->name
))
156 static u8 econfig_bytes
[sizeof(ventana_info
.config
)];
157 static int econfig_init
= -1;
159 int do_econfig(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
161 struct ventana_eeprom_config
*cfg
;
162 struct ventana_board_info
*info
= &ventana_info
;
166 return CMD_RET_USAGE
;
169 if (econfig_init
!= 1) {
170 memcpy(econfig_bytes
, info
->config
, sizeof(econfig_bytes
));
175 if ((strncmp(argv
[1], "list", 4) == 0)) {
178 printf("%s: %d\n", cfg
->name
,
179 test_bit(cfg
->bit
, econfig_bytes
) ? 1 : 0);
185 else if ((strncmp(argv
[1], "save", 4) == 0)) {
186 unsigned char *buf
= (unsigned char *)info
;
189 /* calculate new checksum */
190 memcpy(info
->config
, econfig_bytes
, sizeof(econfig_bytes
));
191 for (chksum
= 0, i
= 0; i
< sizeof(*info
)-2; i
++)
193 debug("old chksum:0x%04x\n",
194 (info
->chksum
[0] << 8) | info
->chksum
[1]);
195 debug("new chksum:0x%04x\n", chksum
);
196 info
->chksum
[0] = chksum
>> 8;
197 info
->chksum
[1] = chksum
& 0xff;
199 /* write new config data */
200 if (gsc_i2c_write(GSC_EEPROM_ADDR
, info
->config
- (u8
*)info
,
201 1, econfig_bytes
, sizeof(econfig_bytes
))) {
202 printf("EEPROM: Failed updating config\n");
203 return CMD_RET_FAILURE
;
206 /* write new config data */
207 if (gsc_i2c_write(GSC_EEPROM_ADDR
, info
->chksum
- (u8
*)info
,
208 1, info
->chksum
, 2)) {
209 printf("EEPROM: Failed updating checksum\n");
210 return CMD_RET_FAILURE
;
213 printf("Config saved to EEPROM\n");
217 else if (argc
== 2) {
218 cfg
= get_config(argv
[1]);
220 printf("%s: %d\n", cfg
->name
,
221 test_bit(cfg
->bit
, econfig_bytes
) ? 1 : 0);
223 printf("invalid config: %s\n", argv
[1]);
224 return CMD_RET_FAILURE
;
229 else if (argc
== 3) {
230 cfg
= get_config(argv
[1]);
232 if (simple_strtol(argv
[2], NULL
, 10)) {
233 test_and_set_bit(cfg
->bit
, econfig_bytes
);
234 printf("Enabled %s\n", cfg
->name
);
236 test_and_clear_bit(cfg
->bit
, econfig_bytes
);
237 printf("Disabled %s\n", cfg
->name
);
240 printf("invalid config: %s\n", argv
[1]);
241 return CMD_RET_FAILURE
;
246 return CMD_RET_USAGE
;
248 return CMD_RET_SUCCESS
;
252 econfig
, 3, 0, do_econfig
,
253 "EEPROM configuration",
254 "list - list config\n"
255 "save - save config to EEPROM\n"
256 "<name> - get config 'name'\n"
257 "<name> [0|1] - set config 'name' to value\n"
260 #endif /* CONFIG_CMD_EECONFIG */