~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/board/siemens/common/factoryset.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *
 
3
 * Read FactorySet information from EEPROM into global structure.
 
4
 * (C) Copyright 2013 Siemens Schweiz AG
 
5
 *
 
6
 * SPDX-License-Identifier:     GPL-2.0+
 
7
 */
 
8
 
 
9
#if !defined(CONFIG_SPL_BUILD)
 
10
 
 
11
#include <common.h>
 
12
#include <i2c.h>
 
13
#include <asm/io.h>
 
14
#include <asm/arch/cpu.h>
 
15
#include <asm/arch/sys_proto.h>
 
16
#include <asm/unaligned.h>
 
17
#include <net.h>
 
18
#include <errno.h>
 
19
#include <g_dnl.h>
 
20
#include "factoryset.h"
 
21
 
 
22
#define EEPR_PG_SZ              0x80
 
23
#define EEPROM_FATORYSET_OFFSET 0x400
 
24
#define OFF_PG            EEPROM_FATORYSET_OFFSET/EEPR_PG_SZ
 
25
 
 
26
/* Global variable that contains necessary information from FactorySet */
 
27
struct factorysetcontainer factory_dat;
 
28
 
 
29
#define fact_get_char(i) *((char *)&eeprom_buf[i])
 
30
 
 
31
static int fact_match(unsigned char *eeprom_buf, uchar *s1, int i2)
 
32
{
 
33
        if (s1 == NULL)
 
34
                return -1;
 
35
 
 
36
        while (*s1 == fact_get_char(i2++))
 
37
                if (*s1++ == '=')
 
38
                        return i2;
 
39
 
 
40
        if (*s1 == '\0' && fact_get_char(i2-1) == '=')
 
41
                return i2;
 
42
 
 
43
        return -1;
 
44
}
 
45
 
 
46
static int get_factory_val(unsigned char *eeprom_buf, int size, uchar *name,
 
47
                        uchar *buf, int len)
 
48
{
 
49
        int i, nxt = 0;
 
50
 
 
51
        for (i = 0; fact_get_char(i) != '\0'; i = nxt + 1) {
 
52
                int val, n;
 
53
 
 
54
                for (nxt = i; fact_get_char(nxt) != '\0'; ++nxt) {
 
55
                        if (nxt >= size)
 
56
                                return -1;
 
57
                }
 
58
 
 
59
                val = fact_match(eeprom_buf, (uchar *)name, i);
 
60
                if (val < 0)
 
61
                        continue;
 
62
 
 
63
                /* found; copy out */
 
64
                for (n = 0; n < len; ++n, ++buf) {
 
65
                        *buf = fact_get_char(val++);
 
66
                        if (*buf == '\0')
 
67
                                return n;
 
68
                }
 
69
 
 
70
                if (n)
 
71
                        *--buf = '\0';
 
72
 
 
73
                printf("env_buf [%d bytes] too small for value of \"%s\"\n",
 
74
                       len, name);
 
75
 
 
76
                return n;
 
77
        }
 
78
        return -1;
 
79
}
 
80
 
 
81
static
 
82
int get_factory_record_val(unsigned char *eeprom_buf, int size, uchar *record,
 
83
        uchar *name, uchar *buf, int len)
 
84
{
 
85
        int ret = -1;
 
86
        int i, nxt = 0;
 
87
        int c;
 
88
        unsigned char end = 0xff;
 
89
 
 
90
        for (i = 0; fact_get_char(i) != end; i = nxt) {
 
91
                nxt = i + 1;
 
92
                if (fact_get_char(i) == '>') {
 
93
                        int pos;
 
94
                        int endpos;
 
95
                        int z;
 
96
 
 
97
                        c = strncmp((char *)&eeprom_buf[i + 1], (char *)record,
 
98
                                    strlen((char *)record));
 
99
                        if (c == 0) {
 
100
                                /* record found */
 
101
                                pos = i + strlen((char *)record) + 2;
 
102
                                nxt = pos;
 
103
                                /* search for "<" */
 
104
                                c = -1;
 
105
                                for (z = pos; fact_get_char(z) != end; z++) {
 
106
                                        if ((fact_get_char(z) == '<')  ||
 
107
                                            (fact_get_char(z) == '>')) {
 
108
                                                endpos = z;
 
109
                                                nxt = endpos;
 
110
                                                c = 0;
 
111
                                                break;
 
112
                                        }
 
113
                                }
 
114
                        }
 
115
                        if (c == 0) {
 
116
                                /* end found -> call get_factory_val */
 
117
                                eeprom_buf[endpos] = end;
 
118
                                ret = get_factory_val(&eeprom_buf[pos],
 
119
                                        size - pos, name, buf, len);
 
120
                                /* fix buffer */
 
121
                                eeprom_buf[endpos] = '<';
 
122
                                debug("%s: %s.%s = %s\n",
 
123
                                      __func__, record, name, buf);
 
124
                                return ret;
 
125
                        }
 
126
                }
 
127
        }
 
128
        return ret;
 
129
}
 
130
 
 
131
int factoryset_read_eeprom(int i2c_addr)
 
132
{
 
133
        int i, pages = 0, size = 0;
 
134
        unsigned char eeprom_buf[0x3c00], hdr[4], buf[MAX_STRING_LENGTH];
 
135
        unsigned char *cp, *cp1;
 
136
 
 
137
#if defined(CONFIG_DFU_FUNCTION)
 
138
        factory_dat.usb_vendor_id = CONFIG_G_DNL_VENDOR_NUM;
 
139
        factory_dat.usb_product_id = CONFIG_G_DNL_PRODUCT_NUM;
 
140
#endif
 
141
        if (i2c_probe(i2c_addr))
 
142
                goto err;
 
143
 
 
144
        if (i2c_read(i2c_addr, EEPROM_FATORYSET_OFFSET, 2, hdr, sizeof(hdr)))
 
145
                goto err;
 
146
 
 
147
        if ((hdr[0] != 0x99) || (hdr[1] != 0x80)) {
 
148
                printf("FactorySet is not right in eeprom.\n");
 
149
                return 1;
 
150
        }
 
151
 
 
152
        /* get FactorySet size */
 
153
        size = (hdr[2] << 8) + hdr[3] + sizeof(hdr);
 
154
        if (size > 0x3bfa)
 
155
                size = 0x3bfa;
 
156
 
 
157
        pages = size / EEPR_PG_SZ;
 
158
 
 
159
        /*
 
160
         * read the eeprom using i2c
 
161
         * I can not read entire eeprom in once, so separate into several
 
162
         * times. Furthermore, fetch eeprom take longer time, so we fetch
 
163
         * data after every time we got a record from eeprom
 
164
         */
 
165
        debug("Read eeprom page :\n");
 
166
        for (i = 0; i < pages; i++)
 
167
                if (i2c_read(i2c_addr, (OFF_PG + i) * EEPR_PG_SZ, 2,
 
168
                             eeprom_buf + (i * EEPR_PG_SZ), EEPR_PG_SZ))
 
169
                        goto err;
 
170
 
 
171
        if (size % EEPR_PG_SZ)
 
172
                if (i2c_read(i2c_addr, (OFF_PG + pages) * EEPR_PG_SZ, 2,
 
173
                             eeprom_buf + (pages * EEPR_PG_SZ),
 
174
                             (size % EEPR_PG_SZ)))
 
175
                        goto err;
 
176
 
 
177
        /* we do below just for eeprom align */
 
178
        for (i = 0; i < size; i++)
 
179
                if (eeprom_buf[i] == '\n')
 
180
                        eeprom_buf[i] = 0;
 
181
 
 
182
        /* skip header */
 
183
        size -= sizeof(hdr);
 
184
        cp = (uchar *)eeprom_buf + sizeof(hdr);
 
185
 
 
186
        /* get mac address */
 
187
        get_factory_record_val(cp, size, (uchar *)"ETH1", (uchar *)"mac",
 
188
                               buf, MAX_STRING_LENGTH);
 
189
        cp1 = buf;
 
190
        for (i = 0; i < 6; i++) {
 
191
                factory_dat.mac[i] = simple_strtoul((char *)cp1, NULL, 16);
 
192
                cp1 += 3;
 
193
        }
 
194
 
 
195
#if defined(CONFIG_DFU_FUNCTION)
 
196
        /* read vid and pid for dfu mode */
 
197
        if (0 <= get_factory_record_val(cp, size, (uchar *)"USBD1",
 
198
                                        (uchar *)"vid", buf,
 
199
                                        MAX_STRING_LENGTH)) {
 
200
                factory_dat.usb_vendor_id = simple_strtoul((char *)buf,
 
201
                                                           NULL, 16);
 
202
        }
 
203
 
 
204
        if (0 <= get_factory_record_val(cp, size, (uchar *)"USBD1",
 
205
                                        (uchar *)"pid", buf,
 
206
                                        MAX_STRING_LENGTH)) {
 
207
                factory_dat.usb_product_id = simple_strtoul((char *)buf,
 
208
                                                            NULL, 16);
 
209
        }
 
210
        printf("DFU USB: VID = 0x%4x, PID = 0x%4x\n", factory_dat.usb_vendor_id,
 
211
               factory_dat.usb_product_id);
 
212
#endif
 
213
        if (0 <= get_factory_record_val(cp, size, (uchar *)"DEV",
 
214
                                        (uchar *)"id", buf,
 
215
                                        MAX_STRING_LENGTH)) {
 
216
                if (strncmp((const char *)buf, "PXM50", 5) == 0)
 
217
                        factory_dat.pxm50 = 1;
 
218
                else
 
219
                        factory_dat.pxm50 = 0;
 
220
        }
 
221
        debug("PXM50: %d\n", factory_dat.pxm50);
 
222
#if defined(CONFIG_VIDEO)
 
223
        if (0 <= get_factory_record_val(cp, size, (uchar *)"DISP1",
 
224
                                        (uchar *)"name", factory_dat.disp_name,
 
225
                                        MAX_STRING_LENGTH)) {
 
226
                debug("display name: %s\n", factory_dat.disp_name);
 
227
        }
 
228
#endif
 
229
        if (0 <= get_factory_record_val(cp, size, (uchar *)"DEV",
 
230
                                        (uchar *)"num", factory_dat.serial,
 
231
                                        MAX_STRING_LENGTH)) {
 
232
                debug("serial number: %s\n", factory_dat.serial);
 
233
        }
 
234
        if (0 <= get_factory_record_val(cp, size, (uchar *)"DEV",
 
235
                                        (uchar *)"ver", buf,
 
236
                                        MAX_STRING_LENGTH)) {
 
237
                factory_dat.version = simple_strtoul((char *)buf,
 
238
                                                            NULL, 16);
 
239
                debug("version number: %d\n", factory_dat.version);
 
240
        }
 
241
 
 
242
        return 0;
 
243
 
 
244
err:
 
245
        printf("Could not read the EEPROM; something fundamentally wrong on the I2C bus.\n");
 
246
        return 1;
 
247
}
 
248
 
 
249
static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
 
250
 
 
251
static int factoryset_mac_setenv(void)
 
252
{
 
253
        uint8_t mac_addr[6];
 
254
 
 
255
        debug("FactorySet: Set mac address\n");
 
256
        if (is_valid_ether_addr(factory_dat.mac)) {
 
257
                memcpy(mac_addr, factory_dat.mac, 6);
 
258
        } else {
 
259
                uint32_t mac_hi, mac_lo;
 
260
 
 
261
                debug("Warning: FactorySet: <ethaddr> not set. Fallback to E-fuse\n");
 
262
                mac_lo = readl(&cdev->macid0l);
 
263
                mac_hi = readl(&cdev->macid0h);
 
264
 
 
265
                mac_addr[0] = mac_hi & 0xFF;
 
266
                mac_addr[1] = (mac_hi & 0xFF00) >> 8;
 
267
                mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
 
268
                mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
 
269
                mac_addr[4] = mac_lo & 0xFF;
 
270
                mac_addr[5] = (mac_lo & 0xFF00) >> 8;
 
271
                if (!is_valid_ether_addr(mac_addr)) {
 
272
                        printf("Warning: ethaddr not set by FactorySet or E-fuse. Set <ethaddr> variable to overcome this.\n");
 
273
                        return -1;
 
274
                }
 
275
        }
 
276
 
 
277
        eth_setenv_enetaddr("ethaddr", mac_addr);
 
278
        return 0;
 
279
}
 
280
 
 
281
int factoryset_setenv(void)
 
282
{
 
283
        int ret = 0;
 
284
 
 
285
        if (factoryset_mac_setenv() < 0)
 
286
                ret = -1;
 
287
 
 
288
        return ret;
 
289
}
 
290
 
 
291
int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name)
 
292
{
 
293
        put_unaligned(factory_dat.usb_vendor_id, &dev->idVendor);
 
294
        put_unaligned(factory_dat.usb_product_id, &dev->idProduct);
 
295
        g_dnl_set_serialnumber((char *)factory_dat.serial);
 
296
 
 
297
        return 0;
 
298
}
 
299
 
 
300
int g_dnl_get_board_bcd_device_number(int gcnum)
 
301
{
 
302
        return factory_dat.version;
 
303
}
 
304
#endif /* defined(CONFIG_SPL_BUILD) */