diff options
Diffstat (limited to 'roms/u-boot/board/ti/common/cape_detect.c')
-rw-r--r-- | roms/u-boot/board/ti/common/cape_detect.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/roms/u-boot/board/ti/common/cape_detect.c b/roms/u-boot/board/ti/common/cape_detect.c new file mode 100644 index 000000000..2e6105cfb --- /dev/null +++ b/roms/u-boot/board/ti/common/cape_detect.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2021 + * Köry Maincent, Bootlin, <kory.maincent@bootlin.com> + */ + +#include <common.h> +#include <malloc.h> +#include <i2c.h> +#include <extension_board.h> + +#include "cape_detect.h" + +static void sanitize_field(char *text, size_t size) +{ + char *c = NULL; + + for (c = text; c < text + (int)size; c++) { + if (*c == 0xFF) + *c = 0; + } +} + +int extension_board_scan(struct list_head *extension_list) +{ + struct extension *cape; + struct am335x_cape_eeprom_id eeprom_header; + + int num_capes = 0; + int ret, i; + struct udevice *dev; + unsigned char addr; + + char process_cape_part_number[17] = {'0'}; + char process_cape_version[5] = {'0'}; + uint8_t cursor = 0; + + for (addr = CAPE_EEPROM_FIRST_ADDR; addr <= CAPE_EEPROM_LAST_ADDR; addr++) { + ret = i2c_get_chip_for_busnum(CONFIG_CAPE_EEPROM_BUS_NUM, addr, 1, &dev); + if (ret) + continue; + + /* Move the read cursor to the beginning of the EEPROM */ + dm_i2c_write(dev, 0, &cursor, 1); + ret = dm_i2c_read(dev, 0, (uint8_t *)&eeprom_header, + sizeof(struct am335x_cape_eeprom_id)); + if (ret) { + printf("Cannot read i2c EEPROM\n"); + continue; + } + + if (eeprom_header.header != CAPE_MAGIC) + continue; + + sanitize_field(eeprom_header.board_name, sizeof(eeprom_header.board_name)); + sanitize_field(eeprom_header.version, sizeof(eeprom_header.version)); + sanitize_field(eeprom_header.manufacturer, sizeof(eeprom_header.manufacturer)); + sanitize_field(eeprom_header.part_number, sizeof(eeprom_header.part_number)); + + /* Process cape part_number */ + memset(process_cape_part_number, 0, sizeof(process_cape_part_number)); + strncpy(process_cape_part_number, eeprom_header.part_number, 16); + /* Some capes end with '.' */ + for (i = 15; i >= 0; i--) { + if (process_cape_part_number[i] == '.') + process_cape_part_number[i] = '\0'; + else + break; + } + + /* Process cape version */ + memset(process_cape_version, 0, sizeof(process_cape_version)); + strncpy(process_cape_version, eeprom_header.version, 4); + for (i = 0; i < 4; i++) { + if (process_cape_version[i] == 0) + process_cape_version[i] = '0'; + } + + printf("BeagleBone Cape: %s (0x%x)\n", eeprom_header.board_name, addr); + + cape = calloc(1, sizeof(struct extension)); + if (!cape) { + printf("Error in memory allocation\n"); + return num_capes; + } + + snprintf(cape->overlay, sizeof(cape->overlay), "%s-%s.dtbo", + process_cape_part_number, process_cape_version); + strncpy(cape->name, eeprom_header.board_name, 32); + strncpy(cape->version, process_cape_version, 4); + strncpy(cape->owner, eeprom_header.manufacturer, 16); + list_add_tail(&cape->list, extension_list); + num_capes++; + } + return num_capes; +} |