1*433d6423SLionel Sambuc #include <minix/i2c.h>
2*433d6423SLionel Sambuc
3*433d6423SLionel Sambuc #include <sys/types.h>
4*433d6423SLionel Sambuc #include <sys/stat.h>
5*433d6423SLionel Sambuc
6*433d6423SLionel Sambuc #include <errno.h>
7*433d6423SLionel Sambuc #include <fcntl.h>
8*433d6423SLionel Sambuc #include <stdio.h>
9*433d6423SLionel Sambuc #include <stdlib.h>
10*433d6423SLionel Sambuc #include <string.h>
11*433d6423SLionel Sambuc #include <unistd.h>
12*433d6423SLionel Sambuc
13*433d6423SLionel Sambuc #include "eepromread.h"
14*433d6423SLionel Sambuc
15*433d6423SLionel Sambuc /*
16*433d6423SLionel Sambuc * Attempt to read the board info from an eeprom on this board.
17*433d6423SLionel Sambuc */
18*433d6423SLionel Sambuc
19*433d6423SLionel Sambuc static int board_info_beaglebone(int fd, i2c_addr_t address, int flags,
20*433d6423SLionel Sambuc enum device_types device_type);
21*433d6423SLionel Sambuc static int board_info_cape_a0(int fd, i2c_addr_t address, int flags,
22*433d6423SLionel Sambuc enum device_types device_type);
23*433d6423SLionel Sambuc static int board_info_cape_a1(int fd, i2c_addr_t address, int flags,
24*433d6423SLionel Sambuc enum device_types device_type);
25*433d6423SLionel Sambuc
26*433d6423SLionel Sambuc /* Memory Layout of the BeagleBone and BeagleBone Black EEPROM */
27*433d6423SLionel Sambuc typedef struct beaglebone_info
28*433d6423SLionel Sambuc {
29*433d6423SLionel Sambuc uint8_t magic_number[4]; /* Should be 0xaa 0x55 0x33 0xee */
30*433d6423SLionel Sambuc char board_name[8]; /* Warning: strings not NULL terminated */
31*433d6423SLionel Sambuc char version[4];
32*433d6423SLionel Sambuc char serial_number[12];
33*433d6423SLionel Sambuc char config[32]; /* All 0x00 on BeagleBone White */
34*433d6423SLionel Sambuc char mac_addrs[3][6]; /* Not set on BeagleBone White */
35*433d6423SLionel Sambuc } beaglebone_info_t;
36*433d6423SLionel Sambuc
37*433d6423SLionel Sambuc /* Memory Layout of the Cape EEPROM (A0 Format) - Defined in BBW SRM Rev A5.3 */
38*433d6423SLionel Sambuc typedef struct cape_info_a0
39*433d6423SLionel Sambuc {
40*433d6423SLionel Sambuc uint8_t magic_number[4]; /* Should be 0xaa 0x55 0x33 0xee */
41*433d6423SLionel Sambuc char revision[2]; /* Should be 'A' '0' */
42*433d6423SLionel Sambuc char board_name[32]; /* Warning: strings not NULL terminated */
43*433d6423SLionel Sambuc char version[4];
44*433d6423SLionel Sambuc char manufacturer[16];
45*433d6423SLionel Sambuc char partno[16];
46*433d6423SLionel Sambuc char num_pins[2];
47*433d6423SLionel Sambuc char serial[12];
48*433d6423SLionel Sambuc char pin_usage[140];
49*433d6423SLionel Sambuc char vdd_3v3exp_i[2];
50*433d6423SLionel Sambuc char vdd_5v_i[2];
51*433d6423SLionel Sambuc char sys_5v_i[2];
52*433d6423SLionel Sambuc char dc_supp[2];
53*433d6423SLionel Sambuc } cape_info_a0_t;
54*433d6423SLionel Sambuc
55*433d6423SLionel Sambuc /* Memory Layout of the Cape EEPROM (A1 Format) - Defined in BBB SRM Rev A5.3 */
56*433d6423SLionel Sambuc typedef struct cape_info_a1
57*433d6423SLionel Sambuc {
58*433d6423SLionel Sambuc uint8_t magic_number[4]; /* Should be 0xaa 0x55 0x33 0xee */
59*433d6423SLionel Sambuc char revision[2]; /* Should be 'A' '1' */
60*433d6423SLionel Sambuc char board_name[32]; /* Warning: strings not NULL terminated */
61*433d6423SLionel Sambuc char version[4];
62*433d6423SLionel Sambuc char manufacturer[16];
63*433d6423SLionel Sambuc char partno[16];
64*433d6423SLionel Sambuc char num_pins[2];
65*433d6423SLionel Sambuc char serial[12];
66*433d6423SLionel Sambuc char pin_usage[148];
67*433d6423SLionel Sambuc char vdd_3v3exp_i[2];
68*433d6423SLionel Sambuc char vdd_5v_i[2];
69*433d6423SLionel Sambuc char sys_5v_i[2];
70*433d6423SLionel Sambuc char dc_supp[2];
71*433d6423SLionel Sambuc } cape_info_a1_t;
72*433d6423SLionel Sambuc
73*433d6423SLionel Sambuc static int
board_info_beaglebone(int fd,i2c_addr_t address,int flags,enum device_types device_type)74*433d6423SLionel Sambuc board_info_beaglebone(int fd, i2c_addr_t address, int flags,
75*433d6423SLionel Sambuc enum device_types device_type)
76*433d6423SLionel Sambuc {
77*433d6423SLionel Sambuc int r;
78*433d6423SLionel Sambuc int i, j;
79*433d6423SLionel Sambuc char s[33];
80*433d6423SLionel Sambuc beaglebone_info_t boneinfo;
81*433d6423SLionel Sambuc
82*433d6423SLionel Sambuc r = eeprom_read(fd, address, 0x0000, &boneinfo,
83*433d6423SLionel Sambuc sizeof(beaglebone_info_t), flags, device_type);
84*433d6423SLionel Sambuc if (r == -1) {
85*433d6423SLionel Sambuc fprintf(stderr, "Failed to read BeagleBone info r=%d\n", r);
86*433d6423SLionel Sambuc return -1;
87*433d6423SLionel Sambuc }
88*433d6423SLionel Sambuc
89*433d6423SLionel Sambuc fprintf(stdout, "%-16s: 0x%x%x%x%x\n", "MAGIC_NUMBER",
90*433d6423SLionel Sambuc boneinfo.magic_number[0], boneinfo.magic_number[1],
91*433d6423SLionel Sambuc boneinfo.magic_number[2], boneinfo.magic_number[3]);
92*433d6423SLionel Sambuc
93*433d6423SLionel Sambuc memset(s, '\0', 33);
94*433d6423SLionel Sambuc memcpy(s, boneinfo.board_name, 8);
95*433d6423SLionel Sambuc fprintf(stdout, "%-16s: %s\n", "BOARD_NAME", s);
96*433d6423SLionel Sambuc
97*433d6423SLionel Sambuc memset(s, '\0', 33);
98*433d6423SLionel Sambuc memcpy(s, boneinfo.version, 4);
99*433d6423SLionel Sambuc fprintf(stdout, "%-16s: %s\n", "VERSION", s);
100*433d6423SLionel Sambuc
101*433d6423SLionel Sambuc memset(s, '\0', 33);
102*433d6423SLionel Sambuc memcpy(s, boneinfo.serial_number, 12);
103*433d6423SLionel Sambuc fprintf(stdout, "%-16s: %s\n", "SERIAL_NUMBER", s);
104*433d6423SLionel Sambuc
105*433d6423SLionel Sambuc return 0;
106*433d6423SLionel Sambuc }
107*433d6423SLionel Sambuc
108*433d6423SLionel Sambuc static int
board_info_cape_a0(int fd,i2c_addr_t address,int flags,enum device_types device_type)109*433d6423SLionel Sambuc board_info_cape_a0(int fd, i2c_addr_t address, int flags,
110*433d6423SLionel Sambuc enum device_types device_type)
111*433d6423SLionel Sambuc {
112*433d6423SLionel Sambuc int r;
113*433d6423SLionel Sambuc int i, j;
114*433d6423SLionel Sambuc char s[33];
115*433d6423SLionel Sambuc cape_info_a0_t capeinfo;
116*433d6423SLionel Sambuc
117*433d6423SLionel Sambuc r = eeprom_read(fd, address, 0x0000, &capeinfo,
118*433d6423SLionel Sambuc sizeof(cape_info_a0_t), flags, device_type);
119*433d6423SLionel Sambuc if (r == -1) {
120*433d6423SLionel Sambuc fprintf(stderr, "failed to read cape A0 info r=%d\n", r);
121*433d6423SLionel Sambuc return -1;
122*433d6423SLionel Sambuc }
123*433d6423SLionel Sambuc
124*433d6423SLionel Sambuc fprintf(stdout, "%-16s: 0x%x%x%x%x\n", "MAGIC_NUMBER",
125*433d6423SLionel Sambuc capeinfo.magic_number[0], capeinfo.magic_number[1],
126*433d6423SLionel Sambuc capeinfo.magic_number[2], capeinfo.magic_number[3]);
127*433d6423SLionel Sambuc
128*433d6423SLionel Sambuc memset(s, '\0', 33);
129*433d6423SLionel Sambuc memcpy(s, capeinfo.revision, 2);
130*433d6423SLionel Sambuc fprintf(stdout, "%-16s: %s\n", "REVISION", s);
131*433d6423SLionel Sambuc
132*433d6423SLionel Sambuc memset(s, '\0', 33);
133*433d6423SLionel Sambuc memcpy(s, capeinfo.board_name, 32);
134*433d6423SLionel Sambuc fprintf(stdout, "%-16s: %s\n", "BOARD_NAME", s);
135*433d6423SLionel Sambuc
136*433d6423SLionel Sambuc memset(s, '\0', 33);
137*433d6423SLionel Sambuc memcpy(s, capeinfo.version, 4);
138*433d6423SLionel Sambuc fprintf(stdout, "%-16s: %s\n", "VERSION", s);
139*433d6423SLionel Sambuc
140*433d6423SLionel Sambuc memset(s, '\0', 33);
141*433d6423SLionel Sambuc memcpy(s, capeinfo.manufacturer, 16);
142*433d6423SLionel Sambuc fprintf(stdout, "%-16s: %s\n", "MANUFACTURER", s);
143*433d6423SLionel Sambuc
144*433d6423SLionel Sambuc memset(s, '\0', 33);
145*433d6423SLionel Sambuc memcpy(s, capeinfo.partno, 16);
146*433d6423SLionel Sambuc fprintf(stdout, "%-16s: %s\n", "PART_NUMBER", s);
147*433d6423SLionel Sambuc
148*433d6423SLionel Sambuc memset(s, '\0', 33);
149*433d6423SLionel Sambuc memcpy(s, capeinfo.serial, 12);
150*433d6423SLionel Sambuc fprintf(stdout, "%-16s: %s\n", "SERIAL", s);
151*433d6423SLionel Sambuc
152*433d6423SLionel Sambuc return 0;
153*433d6423SLionel Sambuc }
154*433d6423SLionel Sambuc
155*433d6423SLionel Sambuc static int
board_info_cape_a1(int fd,i2c_addr_t address,int flags,enum device_types device_type)156*433d6423SLionel Sambuc board_info_cape_a1(int fd, i2c_addr_t address, int flags,
157*433d6423SLionel Sambuc enum device_types device_type)
158*433d6423SLionel Sambuc {
159*433d6423SLionel Sambuc int r;
160*433d6423SLionel Sambuc int i, j;
161*433d6423SLionel Sambuc char s[33];
162*433d6423SLionel Sambuc cape_info_a1_t capeinfo;
163*433d6423SLionel Sambuc
164*433d6423SLionel Sambuc r = eeprom_read(fd, address, 0x0000, &capeinfo,
165*433d6423SLionel Sambuc sizeof(cape_info_a1_t), flags, device_type);
166*433d6423SLionel Sambuc if (r == -1) {
167*433d6423SLionel Sambuc fprintf(stderr, "failed to read cape A0 info r=%d\n", r);
168*433d6423SLionel Sambuc return -1;
169*433d6423SLionel Sambuc }
170*433d6423SLionel Sambuc
171*433d6423SLionel Sambuc fprintf(stdout, "%-16s: 0x%x%x%x%x\n", "MAGIC_NUMBER",
172*433d6423SLionel Sambuc capeinfo.magic_number[0], capeinfo.magic_number[1],
173*433d6423SLionel Sambuc capeinfo.magic_number[2], capeinfo.magic_number[3]);
174*433d6423SLionel Sambuc
175*433d6423SLionel Sambuc memset(s, '\0', 33);
176*433d6423SLionel Sambuc memcpy(s, capeinfo.revision, 2);
177*433d6423SLionel Sambuc fprintf(stdout, "%-16s: %s\n", "REVISION", s);
178*433d6423SLionel Sambuc
179*433d6423SLionel Sambuc memset(s, '\0', 33);
180*433d6423SLionel Sambuc memcpy(s, capeinfo.board_name, 32);
181*433d6423SLionel Sambuc fprintf(stdout, "%-16s: %s\n", "BOARD_NAME", s);
182*433d6423SLionel Sambuc
183*433d6423SLionel Sambuc memset(s, '\0', 33);
184*433d6423SLionel Sambuc memcpy(s, capeinfo.version, 4);
185*433d6423SLionel Sambuc fprintf(stdout, "%-16s: %s\n", "VERSION", s);
186*433d6423SLionel Sambuc
187*433d6423SLionel Sambuc memset(s, '\0', 33);
188*433d6423SLionel Sambuc memcpy(s, capeinfo.manufacturer, 16);
189*433d6423SLionel Sambuc fprintf(stdout, "%-16s: %s\n", "MANUFACTURER", s);
190*433d6423SLionel Sambuc
191*433d6423SLionel Sambuc memset(s, '\0', 33);
192*433d6423SLionel Sambuc memcpy(s, capeinfo.partno, 16);
193*433d6423SLionel Sambuc fprintf(stdout, "%-16s: %s\n", "PART_NUMBER", s);
194*433d6423SLionel Sambuc
195*433d6423SLionel Sambuc memset(s, '\0', 33);
196*433d6423SLionel Sambuc memcpy(s, capeinfo.serial, 12);
197*433d6423SLionel Sambuc fprintf(stdout, "%-16s: %s\n", "SERIAL", s);
198*433d6423SLionel Sambuc
199*433d6423SLionel Sambuc return 0;
200*433d6423SLionel Sambuc }
201*433d6423SLionel Sambuc
202*433d6423SLionel Sambuc int
board_info(int fd,i2c_addr_t address,int flags,enum device_types device_type)203*433d6423SLionel Sambuc board_info(int fd, i2c_addr_t address, int flags,
204*433d6423SLionel Sambuc enum device_types device_type)
205*433d6423SLionel Sambuc {
206*433d6423SLionel Sambuc int r;
207*433d6423SLionel Sambuc uint8_t magic_number[6];
208*433d6423SLionel Sambuc
209*433d6423SLionel Sambuc r = eeprom_read(fd, address, 0x0000, &magic_number, 6, flags,
210*433d6423SLionel Sambuc device_type);
211*433d6423SLionel Sambuc if (r == -1) {
212*433d6423SLionel Sambuc printf("%-16s: %s\n", "BOARD_NAME", "UNKNOWN");
213*433d6423SLionel Sambuc return 0;
214*433d6423SLionel Sambuc }
215*433d6423SLionel Sambuc
216*433d6423SLionel Sambuc /* Check for BeagleBone/BeagleBone Black/Cape Magic Number */
217*433d6423SLionel Sambuc if (magic_number[0] == 0xaa && magic_number[1] == 0x55 &&
218*433d6423SLionel Sambuc magic_number[2] == 0x33 && magic_number[3] == 0xee) {
219*433d6423SLionel Sambuc
220*433d6423SLionel Sambuc /* Check if Cape Rev A0, Cape Rev A1, or on-board EEPROM */
221*433d6423SLionel Sambuc if (magic_number[4] == 'A' && magic_number[5] == '0') {
222*433d6423SLionel Sambuc board_info_cape_a0(fd, address, flags, device_type);
223*433d6423SLionel Sambuc } else if (magic_number[4] == 'A' && magic_number[5] == '1') {
224*433d6423SLionel Sambuc board_info_cape_a1(fd, address, flags, device_type);
225*433d6423SLionel Sambuc } else {
226*433d6423SLionel Sambuc board_info_beaglebone(fd, address, flags, device_type);
227*433d6423SLionel Sambuc }
228*433d6423SLionel Sambuc } else {
229*433d6423SLionel Sambuc printf("%-16s: %s\n", "BOARD_NAME", "UNKNOWN");
230*433d6423SLionel Sambuc }
231*433d6423SLionel Sambuc
232*433d6423SLionel Sambuc return 0;
233*433d6423SLionel Sambuc }
234