From patchwork Thu Sep 25 17:47:46 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 433 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1758822567; bh=IF/dpSxMfm+HJmp06oQKBPg4D1TpMOpPRYmw1dkJ8Js=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=HeyPGC734QzIgGQNDMj/nV1pqJyXM2KIT9TTzzrTDrZ5e5tlXyL54M6rE7RD9vZ4f e5UCvnkZLjPeoq692h1rqk5rIDYfkyVT7iV5U5H1Imaftrl/SrrVNFjvvgd4oJCLuD 22dWuvCI54t8nvTA7ONEjLfuh2dtdKuvkfIiZeNK8m/t8jHyH4QcCTnFsoSDRkw2vB 5xVuvbJJFyQtjevHa5g/oB8IeYoMVQPW05E2z2XcWtpIZEPx2mWtpE0CMaBRZi5g96 xVYVSEb74afABPlEATEh6B7v9/YnUrelS5g0VDvjc1YWJKm9DwKKZsIygm4qZig7M/ /rif2lb/YAz7A== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 9853B67D93 for ; Thu, 25 Sep 2025 11:49:27 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id MtPFBdykE6K9 for ; Thu, 25 Sep 2025 11:49:27 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1758822567; bh=IF/dpSxMfm+HJmp06oQKBPg4D1TpMOpPRYmw1dkJ8Js=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=HeyPGC734QzIgGQNDMj/nV1pqJyXM2KIT9TTzzrTDrZ5e5tlXyL54M6rE7RD9vZ4f e5UCvnkZLjPeoq692h1rqk5rIDYfkyVT7iV5U5H1Imaftrl/SrrVNFjvvgd4oJCLuD 22dWuvCI54t8nvTA7ONEjLfuh2dtdKuvkfIiZeNK8m/t8jHyH4QcCTnFsoSDRkw2vB 5xVuvbJJFyQtjevHa5g/oB8IeYoMVQPW05E2z2XcWtpIZEPx2mWtpE0CMaBRZi5g96 xVYVSEb74afABPlEATEh6B7v9/YnUrelS5g0VDvjc1YWJKm9DwKKZsIygm4qZig7M/ /rif2lb/YAz7A== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 8807167D82 for ; Thu, 25 Sep 2025 11:49:27 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1758822565; bh=AgBbD1gVN1ju+ylAzSp67yz35G2wI/B42A18pK+Zr2Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=i0D44Mdvi8TyBRN6TfiS7Z+hQbwvkm9Hpqh++nnCIdNBpDYhgDLK+Plac0pk0zZjq w0MaL1rTUEenOm+dHcy/ZaMhPH5poZg1RVLQuiDRs/RMJzASdOtnBvuu17UAmlszw8 SMIpbKJKAS/e9x/bFbhyjYAlukPuV+BPf7KNqgSN9yeSF1OgwCmtw+ZI8pclB2ITBO 0b/C1VerKeBsU3BbruPLUduWjWXn8tMRsTRr9XuDxRfUwbd2ceEOb+eqg0KeHm+Bm2 7YjNWXoSYsg3v4P7QCmv6C2XzR98utk+XTXhxu6DeOWMPI8ce+XVbPBm4ljX+If5uL HRDsJhyO0BLdQ== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 9757567D90; Thu, 25 Sep 2025 11:49:25 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id h8ZWdFtNIwQq; Thu, 25 Sep 2025 11:49:25 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1758822563; bh=hnVJUhmcJwon94FdIEZtbjzRiLVr8FDIxuP5bWEks8A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=C5zhNlxzGtymvxdkBumAQ2Eg8ydfj9hBrYJrhJhQ6bIyH1HfGCp7JzpVMEX5agVC3 UyC5LH76Ae1YXcObNA26wzhyASxldCk464aueVbNXNvTgvain1tmMbSXDlb7YF10+h CegVh+VqaU8LHFjLzpCJqNMQwrx+3OMO7dJr/SkmW0fQLjIt5FNHu9PLtvNwKNOO9d BvUXjalRQlB5rEp+UmNQvqn9g62/Ls88rhgXM0Hnuj3El3CpkxPGGnTBdcFARg/MkV a3bFBJYtdI6vPm0fleTTwkqqA78RnMEDzSO7K0eJRyitWXkMAKIxCSCvlxIEGuJuxr sCELUzrFHjJGQ== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 9B4D367CEF; Thu, 25 Sep 2025 11:49:23 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Thu, 25 Sep 2025 11:47:46 -0600 Message-ID: <20250925174753.3429102-23-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250925174753.3429102-1-sjg@u-boot.org> References: <20250925174753.3429102-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: GEGBNHHEND2SATV2S7CJJBN6MFFCZJ5E X-Message-ID-Hash: GEGBNHHEND2SATV2S7CJJBN6MFFCZJ5E X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Heinrich Schuchardt , Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 22/22] efi: app: Provide a keyboard driver List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Add a keyboard driver which returns keys produced by EFI. This is basically the same as the serial driver but it doesn't combine input and output into one driver, allowing more control when using a separate screen. Add the required devicetree fragment for ARM (only). Signed-off-by: Simon Glass --- arch/arm/dts/efi-arm_app.dts | 4 + drivers/input/Kconfig | 14 +++ drivers/input/Makefile | 2 + drivers/input/efi_keyb.c | 173 +++++++++++++++++++++++++++++++++++ 4 files changed, 193 insertions(+) create mode 100644 drivers/input/efi_keyb.c diff --git a/arch/arm/dts/efi-arm_app.dts b/arch/arm/dts/efi-arm_app.dts index d2a008fba6a..1a7ed77e6a8 100644 --- a/arch/arm/dts/efi-arm_app.dts +++ b/arch/arm/dts/efi-arm_app.dts @@ -29,6 +29,10 @@ bootph-some-ram; }; + keyboard { + compatible = "efi-keyboard"; + }; + mouse { compatible = "efi,mouse"; }; diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 7b34902dd7c..6e19f6f7b3d 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -14,6 +14,7 @@ config TPL_INPUT config DM_KEYBOARD bool "Enable driver model keyboard support" depends on DM + default y if EFI_APP help This adds a uclass for keyboards and implements keyboard support using driver model. The API is implemented by keyboard.h and @@ -63,6 +64,19 @@ config CROS_EC_KEYB Messages are used to request key scans from the EC and these are then decoded into keys by this driver. +config EFI_KEYB + bool "Keyboard on top of EFI" + depends on DM_KEYBOARD && EFI_APP + default y + help + Provides a keyboard driver for EFI. While this is often connected + to the serial driver, that can be confusing on a device which has + both serial and keyboard devices. Provide a separate keyboard + driver. + + For now this is not used, pending further work on teasing this + apart within the EFI subsystem. + config SPL_CROS_EC_KEYB bool "Enable Chrome OS EC keyboard support in SPL" depends on SPL_INPUT diff --git a/drivers/input/Makefile b/drivers/input/Makefile index 4debad9e713..e8888079a1c 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -8,6 +8,8 @@ obj-$(CONFIG_$(PHASE_)OF_CONTROL) += key_matrix.o obj-$(CONFIG_$(PHASE_)DM_KEYBOARD) += input.o keyboard-uclass.o obj-$(CONFIG_BUTTON_KEYBOARD) += button_kbd.o +obj-$(CONFIG_EFI_KEYB) += efi_keyb.o + ifndef CONFIG_XPL_BUILD obj-$(CONFIG_APPLE_SPI_KEYB) += apple_spi_kbd.o diff --git a/drivers/input/efi_keyb.c b/drivers/input/efi_keyb.c new file mode 100644 index 00000000000..0cbb438c6de --- /dev/null +++ b/drivers/input/efi_keyb.c @@ -0,0 +1,173 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * EFI-keyboard input driver + * + * Uses EFI's Simple Text Input Protocol, polling keystrokes and providing them + * to stdio + */ + +#define LOG_CATEGORY LOGC_EFI + +#include +#include +#include +#include +#include +#include +#include + +/* + * struct efi_kbd_priv - private information for the keyboard + * + * @ex_con + */ +struct efi_kbd_priv { + struct efi_simple_text_input_ex_protocol *ex_con; + struct efi_simple_text_input_protocol *con_in; + struct efi_input_key key; + struct efi_key_data exkey; + + bool have_key; +}; + +/** + * efi_kbd_tstc() - Test for a character from EFI + * + * @dev: keyboard device + * Return: 1 if a character is available, 0 otherwise. + */ +static int efi_kbd_tstc(struct udevice *dev) +{ + struct efi_kbd_priv *priv = dev_get_priv(dev); + efi_status_t status; + + /* If we already have a key from a previous check, report it's available */ + if (priv->have_key) + return 1; + + /* wait until we don't see EFI_NOT_READY */ + if (priv->ex_con) { + status = priv->ex_con->read_key_stroke_ex(priv->ex_con, + &priv->exkey); + } else { + status = priv->con_in->read_key_stroke(priv->con_in, + &priv->key); + } + if (!status) { + priv->have_key = true; + return 1; + } + + return 0; +} + +/** + * efi_kbd_getc() - Get a character from EFI + * + * Waits until a key is available and returns the associated character + * + * @dev: stdio device pointer + * Return: character code, or 0 if none + */ +static int efi_kbd_getc(struct udevice *dev) +{ + struct efi_kbd_priv *priv = dev_get_priv(dev); + + if (!efi_kbd_tstc(dev)) + return 0; + + priv->have_key = false; + if (priv->ex_con) { + struct efi_input_key *exkey = &priv->exkey.key; + + log_debug("got exkey %x scan %x\n", exkey->unicode_char, + exkey->scan_code); + return efi_decode_key(exkey); + } else { + struct efi_input_key *key = &priv->key; + + log_debug("got key %x\n", key->unicode_char); + return efi_decode_key(key); + } + + return 0; +} + +/** + * efi_kbd_start() - Start the driver + * + * Reset the keyboard ready for use + * + * Return: 0 on success (always) + */ +static int efi_kbd_start(struct udevice *dev) +{ + struct efi_kbd_priv *priv = dev_get_priv(dev); + + log_debug("keyboard start\n"); + + /* reset keyboard to drop anything pressed during UEFI startup */ + priv->con_in->reset(priv->con_in, true); + if (priv->ex_con) + priv->ex_con->reset(priv->ex_con, true); + priv->have_key = false; + + return 0; +} + +static int efi_kbd_probe(struct udevice *dev) +{ + struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev); + struct efi_system_table *systab = efi_get_sys_table(); + struct stdio_dev *sdev = &uc_priv->sdev; + struct efi_kbd_priv *priv = dev_get_priv(dev); + efi_status_t ret_efi; + int ret; + + log_debug("keyboard probe '%s'\n", dev->name); + priv->con_in = systab->con_in; + + /* Try to get the EFI Simple Text Input EX protocol from console handle */ + if (systab->con_in_handle) { + efi_guid_t ex_guid = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID; + + ret_efi = efi_get_boot()->open_protocol(systab->con_in_handle, + &ex_guid, + (void **)&priv->ex_con, + NULL, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret_efi != EFI_SUCCESS) { + log_debug("Extended input protocol not available\n"); + priv->ex_con = NULL; + } + } + + strcpy(sdev->name, "efi-kbd"); + ret = input_stdio_register(sdev); + if (ret) { + log_err("Failed to register\n"); + return ret; + } + + return 0; +} + +static const struct keyboard_ops efi_kbd_ops = { + .start = efi_kbd_start, + .tstc = efi_kbd_tstc, + .getc = efi_kbd_getc, +}; + +static const struct udevice_id efi_kbd_ids[] = { + { .compatible = "efi-keyboard" }, + { } +}; + +U_BOOT_DRIVER(efi_kbd) = { + .name = "efi_kbd", + .id = UCLASS_KEYBOARD, + .of_match = efi_kbd_ids, + .ops = &efi_kbd_ops, + .priv_auto = sizeof(struct efi_kbd_priv), + .probe = efi_kbd_probe, +};