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 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} 97