1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2021
4  * Köry Maincent, Bootlin, <kory.maincent@bootlin.com>
5  */
6 
7 #include <common.h>
8 #include <malloc.h>
9 #include <i2c.h>
10 #include <extension_board.h>
11 
12 #include "cape_detect.h"
13 
sanitize_field(char * text,size_t size)14 static void sanitize_field(char *text, size_t size)
15 {
16 	char *c = NULL;
17 
18 	for (c = text; c < text + (int)size; c++) {
19 		if (*c == 0xFF)
20 			*c = 0;
21 	}
22 }
23 
extension_board_scan(struct list_head * extension_list)24 int extension_board_scan(struct list_head *extension_list)
25 {
26 	struct extension *cape;
27 	struct am335x_cape_eeprom_id eeprom_header;
28 
29 	int num_capes = 0;
30 	int ret, i;
31 	struct udevice *dev;
32 	unsigned char addr;
33 
34 	char process_cape_part_number[17] = {'0'};
35 	char process_cape_version[5] = {'0'};
36 	uint8_t cursor = 0;
37 
38 	for (addr = CAPE_EEPROM_FIRST_ADDR; addr <= CAPE_EEPROM_LAST_ADDR; addr++) {
39 		ret = i2c_get_chip_for_busnum(CONFIG_CAPE_EEPROM_BUS_NUM, addr, 1, &dev);
40 		if (ret)
41 			continue;
42 
43 		/* Move the read cursor to the beginning of the EEPROM */
44 		dm_i2c_write(dev, 0, &cursor, 1);
45 		ret = dm_i2c_read(dev, 0, (uint8_t *)&eeprom_header,
46 				  sizeof(struct am335x_cape_eeprom_id));
47 		if (ret) {
48 			printf("Cannot read i2c EEPROM\n");
49 			continue;
50 		}
51 
52 		if (eeprom_header.header != CAPE_MAGIC)
53 			continue;
54 
55 		sanitize_field(eeprom_header.board_name, sizeof(eeprom_header.board_name));
56 		sanitize_field(eeprom_header.version, sizeof(eeprom_header.version));
57 		sanitize_field(eeprom_header.manufacturer, sizeof(eeprom_header.manufacturer));
58 		sanitize_field(eeprom_header.part_number, sizeof(eeprom_header.part_number));
59 
60 		/* Process cape part_number */
61 		memset(process_cape_part_number, 0, sizeof(process_cape_part_number));
62 		strncpy(process_cape_part_number, eeprom_header.part_number, 16);
63 		/* Some capes end with '.' */
64 		for (i = 15; i >= 0; i--) {
65 			if (process_cape_part_number[i] == '.')
66 				process_cape_part_number[i] = '\0';
67 			else
68 				break;
69 		}
70 
71 		/* Process cape version */
72 		memset(process_cape_version, 0, sizeof(process_cape_version));
73 		strncpy(process_cape_version, eeprom_header.version, 4);
74 		for (i = 0; i < 4; i++) {
75 			if (process_cape_version[i] == 0)
76 				process_cape_version[i] = '0';
77 		}
78 
79 		printf("BeagleBone Cape: %s (0x%x)\n", eeprom_header.board_name, addr);
80 
81 		cape = calloc(1, sizeof(struct extension));
82 		if (!cape) {
83 			printf("Error in memory allocation\n");
84 			return num_capes;
85 		}
86 
87 		snprintf(cape->overlay, sizeof(cape->overlay), "%s-%s.dtbo",
88 			 process_cape_part_number, process_cape_version);
89 		strncpy(cape->name, eeprom_header.board_name, 32);
90 		strncpy(cape->version, process_cape_version, 4);
91 		strncpy(cape->owner, eeprom_header.manufacturer, 16);
92 		list_add_tail(&cape->list, extension_list);
93 		num_capes++;
94 	}
95 	return num_capes;
96 }
97