From patchwork Tue Apr 20 08:25:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kory Maincent X-Patchwork-Id: 1468236 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FPcH23rdzz9vDc for ; Tue, 20 Apr 2021 18:26:54 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 398DD82B11; Tue, 20 Apr 2021 10:26:29 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id C6C2B82B0B; Tue, 20 Apr 2021 10:25:59 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id A40D282AD8 for ; Tue, 20 Apr 2021 10:25:50 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=kory.maincent@bootlin.com Received: from localhost.localdomain (pop.92-184-110-32.mobile.abo.orange.fr [92.184.110.32]) (Authenticated sender: kory.maincent@bootlin.com) by relay10.mail.gandi.net (Postfix) with ESMTPSA id 3823A240004; Tue, 20 Apr 2021 08:25:49 +0000 (UTC) From: Kory Maincent To: u-boot@lists.denx.de Cc: thomas.petazzoni@bootlin.com, jkridner@beagleboard.org, drew@beagleboard.org, robertcnelson@gmail.com, maxime@cerno.tech, trini@konsulko.com, andre.przywara@arm.com Subject: [PATCH v4 04/10] ti/common: add support for extension_scan_board function Date: Tue, 20 Apr 2021 10:25:35 +0200 Message-Id: <20210420082541.28757-5-kory.maincent@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210420082541.28757-1-kory.maincent@bootlin.com> References: <20210420082541.28757-1-kory.maincent@bootlin.com> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.4 at phobos.denx.de X-Virus-Status: Clean The BeagleBone platforms all use a common mechanism to discover and identify extension boards (called "capes"): each extension board has an I2C-connected EEPROM describing itself. This patch implements a generic extension_scan_board() feature that can be used by all BeagleBone platforms to read those I2C EEPROMs and fill in the list of "extension" structures. Following commits will enable this common logic on two BeagleBone platforms. Signed-off-by: Kory Maincent --- Change Since v1: - Use CAPE_EEPROM_BUS_NUM in Kconfig in place of the board header board/ti/common/Kconfig | 6 +++ board/ti/common/Makefile | 1 + board/ti/common/cape_detect.c | 96 +++++++++++++++++++++++++++++++++++ board/ti/common/cape_detect.h | 28 ++++++++++ 4 files changed, 131 insertions(+) create mode 100644 board/ti/common/cape_detect.c create mode 100644 board/ti/common/cape_detect.h diff --git a/board/ti/common/Kconfig b/board/ti/common/Kconfig index 9ead7ca038..49edd98014 100644 --- a/board/ti/common/Kconfig +++ b/board/ti/common/Kconfig @@ -16,6 +16,12 @@ config EEPROM_CHIP_ADDRESS default 0x50 depends on TI_I2C_BOARD_DETECT +config CAPE_EEPROM_BUS_NUM + int "Cape EEPROM's I2C bus address" + range 0 8 + default 2 + depends on CMD_EXTENSION + config TI_COMMON_CMD_OPTIONS bool "Enable cmd options on TI platforms" imply CMD_ASKENV diff --git a/board/ti/common/Makefile b/board/ti/common/Makefile index cb97f226ae..3172d87b46 100644 --- a/board/ti/common/Makefile +++ b/board/ti/common/Makefile @@ -2,3 +2,4 @@ # Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/ obj-${CONFIG_TI_I2C_BOARD_DETECT} += board_detect.o +obj-${CONFIG_CMD_EXTENSION} += cape_detect.o diff --git a/board/ti/common/cape_detect.c b/board/ti/common/cape_detect.c new file mode 100644 index 0000000000..2e6105cfbf --- /dev/null +++ b/board/ti/common/cape_detect.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2021 + * Köry Maincent, Bootlin, + */ + +#include +#include +#include +#include + +#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; +} diff --git a/board/ti/common/cape_detect.h b/board/ti/common/cape_detect.h new file mode 100644 index 0000000000..b0d5c9f18b --- /dev/null +++ b/board/ti/common/cape_detect.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2021 + * Köry Maincent, Bootlin, + */ + +#ifndef __CAPE_DETECT_H +#define __CAPE_DETECT_H + +struct am335x_cape_eeprom_id { + unsigned int header; + char eeprom_rev[2]; + char board_name[32]; + char version[4]; + char manufacturer[16]; + char part_number[16]; +}; + +#define CAPE_EEPROM_FIRST_ADDR 0x54 +#define CAPE_EEPROM_LAST_ADDR 0x57 + +#define CAPE_EEPROM_ADDR_LEN 0x10 + +#define CAPE_MAGIC 0xEE3355AA + +int extension_board_scan(struct list_head *extension_list); + +#endif /* __CAPE_DETECT_H */