1
2
3
4
5
6
7
8
9
10#include <common.h>
11#include <i2c.h>
12#include "eeprom.h"
13
14#ifndef CONFIG_SYS_I2C_EEPROM_ADDR
15# define CONFIG_SYS_I2C_EEPROM_ADDR 0x50
16# define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1
17#endif
18
19#ifndef CONFIG_SYS_I2C_EEPROM_BUS
20#define CONFIG_SYS_I2C_EEPROM_BUS 0
21#endif
22
23#define EEPROM_LAYOUT_VER_OFFSET 44
24#define BOARD_SERIAL_OFFSET 20
25#define BOARD_SERIAL_OFFSET_LEGACY 8
26#define BOARD_REV_OFFSET 0
27#define BOARD_REV_OFFSET_LEGACY 6
28#define BOARD_REV_SIZE 2
29#define PRODUCT_NAME_OFFSET 128
30#define PRODUCT_NAME_SIZE 16
31#define MAC_ADDR_OFFSET 4
32#define MAC_ADDR_OFFSET_LEGACY 0
33
34#define LAYOUT_INVALID 0
35#define LAYOUT_LEGACY 0xff
36
37static int cl_eeprom_bus;
38static int cl_eeprom_layout;
39
40static int cl_eeprom_read(uint offset, uchar *buf, int len)
41{
42 int res;
43 unsigned int current_i2c_bus = i2c_get_bus_num();
44
45 res = i2c_set_bus_num(cl_eeprom_bus);
46 if (res < 0)
47 return res;
48
49 res = i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, offset,
50 CONFIG_SYS_I2C_EEPROM_ADDR_LEN, buf, len);
51
52 i2c_set_bus_num(current_i2c_bus);
53
54 return res;
55}
56
57static int cl_eeprom_setup(uint eeprom_bus)
58{
59 int res;
60
61
62
63
64
65 if (cl_eeprom_layout != LAYOUT_INVALID && eeprom_bus == cl_eeprom_bus)
66 return 0;
67
68 cl_eeprom_bus = eeprom_bus;
69 res = cl_eeprom_read(EEPROM_LAYOUT_VER_OFFSET,
70 (uchar *)&cl_eeprom_layout, 1);
71 if (res) {
72 cl_eeprom_layout = LAYOUT_INVALID;
73 return res;
74 }
75
76 if (cl_eeprom_layout == 0 || cl_eeprom_layout >= 0x20)
77 cl_eeprom_layout = LAYOUT_LEGACY;
78
79 return 0;
80}
81
82void get_board_serial(struct tag_serialnr *serialnr)
83{
84 u32 serial[2];
85 uint offset;
86
87 memset(serialnr, 0, sizeof(*serialnr));
88
89 if (cl_eeprom_setup(CONFIG_SYS_I2C_EEPROM_BUS))
90 return;
91
92 offset = (cl_eeprom_layout != LAYOUT_LEGACY) ?
93 BOARD_SERIAL_OFFSET : BOARD_SERIAL_OFFSET_LEGACY;
94
95 if (cl_eeprom_read(offset, (uchar *)serial, 8))
96 return;
97
98 if (serial[0] != 0xffffffff && serial[1] != 0xffffffff) {
99 serialnr->low = serial[0];
100 serialnr->high = serial[1];
101 }
102}
103
104
105
106
107
108int cl_eeprom_read_mac_addr(uchar *buf, uint eeprom_bus)
109{
110 uint offset;
111 int err;
112
113 err = cl_eeprom_setup(eeprom_bus);
114 if (err)
115 return err;
116
117 offset = (cl_eeprom_layout != LAYOUT_LEGACY) ?
118 MAC_ADDR_OFFSET : MAC_ADDR_OFFSET_LEGACY;
119
120 return cl_eeprom_read(offset, buf, 6);
121}
122
123static u32 board_rev;
124
125
126
127
128
129u32 cl_eeprom_get_board_rev(uint eeprom_bus)
130{
131 char str[5];
132 uint offset = BOARD_REV_OFFSET_LEGACY;
133
134 if (board_rev)
135 return board_rev;
136
137 if (cl_eeprom_setup(eeprom_bus))
138 return 0;
139
140 if (cl_eeprom_layout != LAYOUT_LEGACY)
141 offset = BOARD_REV_OFFSET;
142
143 if (cl_eeprom_read(offset, (uchar *)&board_rev, BOARD_REV_SIZE))
144 return 0;
145
146
147
148
149
150 if (cl_eeprom_layout == LAYOUT_LEGACY) {
151 sprintf(str, "%x", board_rev);
152 board_rev = simple_strtoul(str, NULL, 10);
153 }
154
155 return board_rev;
156};
157
158
159
160
161
162
163
164
165
166
167int cl_eeprom_get_product_name(uchar *buf, uint eeprom_bus)
168{
169 int err;
170
171 if (buf == NULL)
172 return -EINVAL;
173
174 err = cl_eeprom_setup(eeprom_bus);
175 if (err)
176 return err;
177
178 err = cl_eeprom_read(PRODUCT_NAME_OFFSET, buf, PRODUCT_NAME_SIZE);
179 if (!err)
180 buf[PRODUCT_NAME_SIZE - 1] = '\0';
181
182 return err;
183}
184