3 * Read FactorySet information from EEPROM into global structure.
4 * (C) Copyright 2013 Siemens Schweiz AG
6 * SPDX-License-Identifier: GPL-2.0+
9 #if !defined(CONFIG_SPL_BUILD)
14 #include <asm/arch/cpu.h>
15 #include <asm/arch/sys_proto.h>
16 #include <asm/unaligned.h>
18 #include <usbdescriptors.h>
19 #include "factoryset.h"
21 #define EEPR_PG_SZ 0x80
22 #define EEPROM_FATORYSET_OFFSET 0x400
23 #define OFF_PG EEPROM_FATORYSET_OFFSET/EEPR_PG_SZ
25 /* Global variable that contains necessary information from FactorySet */
26 struct factorysetcontainer factory_dat
;
28 #define fact_get_char(i) *((char *)&eeprom_buf[i])
30 static int fact_match(unsigned char *eeprom_buf
, uchar
*s1
, int i2
)
35 while (*s1
== fact_get_char(i2
++))
39 if (*s1
== '\0' && fact_get_char(i2
-1) == '=')
45 static int get_factory_val(unsigned char *eeprom_buf
, int size
, uchar
*name
,
50 for (i
= 0; fact_get_char(i
) != '\0'; i
= nxt
+ 1) {
53 for (nxt
= i
; fact_get_char(nxt
) != '\0'; ++nxt
) {
58 val
= fact_match(eeprom_buf
, (uchar
*)name
, i
);
63 for (n
= 0; n
< len
; ++n
, ++buf
) {
64 *buf
= fact_get_char(val
++);
72 printf("env_buf [%d bytes] too small for value of \"%s\"\n",
81 int get_factory_record_val(unsigned char *eeprom_buf
, int size
, uchar
*record
,
82 uchar
*name
, uchar
*buf
, int len
)
87 unsigned char end
= 0xff;
89 for (i
= 0; fact_get_char(i
) != end
; i
= nxt
) {
91 if (fact_get_char(i
) == '>') {
96 c
= strncmp((char *)&eeprom_buf
[i
+ 1], (char *)record
,
97 strlen((char *)record
));
100 pos
= i
+ strlen((char *)record
) + 2;
104 for (z
= pos
; fact_get_char(z
) != end
; z
++) {
105 if ((fact_get_char(z
) == '<') ||
106 (fact_get_char(z
) == '>')) {
115 /* end found -> call get_factory_val */
116 eeprom_buf
[endpos
] = end
;
117 ret
= get_factory_val(&eeprom_buf
[pos
],
118 size
- pos
, name
, buf
, len
);
120 eeprom_buf
[endpos
] = '<';
121 debug("%s: %s.%s = %s\n",
122 __func__
, record
, name
, buf
);
130 int factoryset_read_eeprom(int i2c_addr
)
132 int i
, pages
= 0, size
= 0;
133 unsigned char eeprom_buf
[0x3c00], hdr
[4], buf
[MAX_STRING_LENGTH
];
134 unsigned char *cp
, *cp1
;
136 #if defined(CONFIG_DFU_FUNCTION)
137 factory_dat
.usb_vendor_id
= CONFIG_G_DNL_VENDOR_NUM
;
138 factory_dat
.usb_product_id
= CONFIG_G_DNL_PRODUCT_NUM
;
140 if (i2c_probe(i2c_addr
))
143 if (i2c_read(i2c_addr
, EEPROM_FATORYSET_OFFSET
, 2, hdr
, sizeof(hdr
)))
146 if ((hdr
[0] != 0x99) || (hdr
[1] != 0x80)) {
147 printf("FactorySet is not right in eeprom.\n");
151 /* get FactorySet size */
152 size
= (hdr
[2] << 8) + hdr
[3] + sizeof(hdr
);
156 pages
= size
/ EEPR_PG_SZ
;
159 * read the eeprom using i2c
160 * I can not read entire eeprom in once, so separate into several
161 * times. Furthermore, fetch eeprom take longer time, so we fetch
162 * data after every time we got a record from eeprom
164 debug("Read eeprom page :\n");
165 for (i
= 0; i
< pages
; i
++)
166 if (i2c_read(i2c_addr
, (OFF_PG
+ i
) * EEPR_PG_SZ
, 2,
167 eeprom_buf
+ (i
* EEPR_PG_SZ
), EEPR_PG_SZ
))
170 if (size
% EEPR_PG_SZ
)
171 if (i2c_read(i2c_addr
, (OFF_PG
+ pages
) * EEPR_PG_SZ
, 2,
172 eeprom_buf
+ (pages
* EEPR_PG_SZ
),
173 (size
% EEPR_PG_SZ
)))
176 /* we do below just for eeprom align */
177 for (i
= 0; i
< size
; i
++)
178 if (eeprom_buf
[i
] == '\n')
183 cp
= (uchar
*)eeprom_buf
+ sizeof(hdr
);
185 /* get mac address */
186 get_factory_record_val(cp
, size
, (uchar
*)"ETH1", (uchar
*)"mac",
187 buf
, MAX_STRING_LENGTH
);
189 for (i
= 0; i
< 6; i
++) {
190 factory_dat
.mac
[i
] = simple_strtoul((char *)cp1
, NULL
, 16);
194 #if defined(CONFIG_DFU_FUNCTION)
195 /* read vid and pid for dfu mode */
196 if (0 <= get_factory_record_val(cp
, size
, (uchar
*)"USBD1",
198 MAX_STRING_LENGTH
)) {
199 factory_dat
.usb_vendor_id
= simple_strtoul((char *)buf
,
203 if (0 <= get_factory_record_val(cp
, size
, (uchar
*)"USBD1",
205 MAX_STRING_LENGTH
)) {
206 factory_dat
.usb_product_id
= simple_strtoul((char *)buf
,
209 printf("DFU USB: VID = 0x%4x, PID = 0x%4x\n", factory_dat
.usb_vendor_id
,
210 factory_dat
.usb_product_id
);
212 if (0 <= get_factory_record_val(cp
, size
, (uchar
*)"DEV",
214 MAX_STRING_LENGTH
)) {
215 if (strncmp((const char *)buf
, "PXM50", 5) == 0)
216 factory_dat
.pxm50
= 1;
218 factory_dat
.pxm50
= 0;
220 debug("PXM50: %d\n", factory_dat
.pxm50
);
221 #if defined(CONFIG_VIDEO)
222 if (0 <= get_factory_record_val(cp
, size
, (uchar
*)"DISP1",
223 (uchar
*)"name", factory_dat
.disp_name
,
224 MAX_STRING_LENGTH
)) {
225 debug("display name: %s\n", factory_dat
.disp_name
);
232 printf("Could not read the EEPROM; something fundamentally wrong on the I2C bus.\n");
236 static struct ctrl_dev
*cdev
= (struct ctrl_dev
*)CTRL_DEVICE_BASE
;
238 static int factoryset_mac_setenv(void)
242 debug("FactorySet: Set mac address\n");
243 if (is_valid_ether_addr(factory_dat
.mac
)) {
244 memcpy(mac_addr
, factory_dat
.mac
, 6);
246 uint32_t mac_hi
, mac_lo
;
248 debug("Warning: FactorySet: <ethaddr> not set. Fallback to E-fuse\n");
249 mac_lo
= readl(&cdev
->macid0l
);
250 mac_hi
= readl(&cdev
->macid0h
);
252 mac_addr
[0] = mac_hi
& 0xFF;
253 mac_addr
[1] = (mac_hi
& 0xFF00) >> 8;
254 mac_addr
[2] = (mac_hi
& 0xFF0000) >> 16;
255 mac_addr
[3] = (mac_hi
& 0xFF000000) >> 24;
256 mac_addr
[4] = mac_lo
& 0xFF;
257 mac_addr
[5] = (mac_lo
& 0xFF00) >> 8;
258 if (!is_valid_ether_addr(mac_addr
)) {
259 printf("Warning: ethaddr not set by FactorySet or E-fuse. Set <ethaddr> variable to overcome this.\n");
264 eth_setenv_enetaddr("ethaddr", mac_addr
);
268 int factoryset_setenv(void)
272 if (factoryset_mac_setenv() < 0)
278 int g_dnl_bind_fixup(struct usb_device_descriptor
*dev
)
280 put_unaligned(factory_dat
.usb_vendor_id
, &dev
->idVendor
);
281 put_unaligned(factory_dat
.usb_product_id
, &dev
->idProduct
);
284 #endif /* defined(CONFIG_SPL_BUILD) */