blob: 2e6105cfbf1567c072e97a19e5f48f542efefab5 [file] [log] [blame]
Kory Maincent26551102021-05-04 19:31:24 +02001// 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
14static 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
24int 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}