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