From patchwork Sun Jan 22 15:21:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dzmitry Sankouski X-Patchwork-Id: 1730150 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=VHgejbOz; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4P0H6Z08Pbz23gY for ; Mon, 23 Jan 2023 02:22:46 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id BBF88856C7; Sun, 22 Jan 2023 16:22:03 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="VHgejbOz"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id E9FCE850CC; Sun, 22 Jan 2023 16:21:45 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-ed1-x536.google.com (mail-ed1-x536.google.com [IPv6:2a00:1450:4864:20::536]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 6BC5F856B0 for ; Sun, 22 Jan 2023 16:21:41 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=dsankouski@gmail.com Received: by mail-ed1-x536.google.com with SMTP id v5so11895633edc.3 for ; Sun, 22 Jan 2023 07:21:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=PlimmWNA5wiBnf07IXWq46PlzfjNMMm+sFVtwdeHl+E=; b=VHgejbOzIfYe6ooP05kO7aokzBTvqcfC5h5/n866+O0AU0bFk5VcTPlVzsfG/tYH8k CiOfJ2G9AQ3bxT/BjS/0uMf7lSfWZ9zIOBXDBUzaQiAO3MxfgYhTT3P8I5HeBQJWN1b2 f4TIQKJLoJhjp1XuSGVZTMNvlfX9jl+GuHqlmc0qBeRMYBjPCKBBvdyeND0MhxmE9Mkr bWhd2uz3MzXqMJkTp8FuM49Yga+YwY+BPIU0LiVUUKsPPtqsv3TPcS3ssVHSg3n9gW+N IhRmgEdnQNxhwQsWbJk84RZnCqPBvMAcVlTmepA+DshmPNAhj18m9Ai+0Ix0xDW7/QGL nULw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=PlimmWNA5wiBnf07IXWq46PlzfjNMMm+sFVtwdeHl+E=; b=2Bol6/xCFplbKAXqYgAS/TPL3u7RzwyDasBkcR8jDkOKdmxY38Fok7VP9Cf1GVAHVN Y2XHwHfuVk4UyfJGLWiwf6mSEyZD72AaaEcK472Ht+FkN5qRY/rhz9F8bfNCW8J1mFmT 6G9MBTPkTGkIjrPSjgJB4ZTSEP57pUAAgvxak8LluYt8XdnSjPbPFFc4gF37dppv9ESy qQDrbc7tSJfRW/HQc523s4LOsuRsr1u3dlnfDmtDm7bVs45e5VzOBF3ZPzmqyzsQWYbv hUwZiuJx6B34BKIZzutRmL1bBVh5Ffhcxe9GQo8PN8Mw3EDZkxEIrnCGiokBYWbcoefZ Wpxw== X-Gm-Message-State: AFqh2krT3lE+Y1aor3LkIum1ZvkHlXskDnGmIkx1nJdoDlWg3JTqys1Y X8gFt//nsLspmecIg7tbUT5cZsRi9hA= X-Google-Smtp-Source: AMrXdXsOv3BAKf9I3FXzaUbtGBPY7IoJQKKrsUBCcCLmSqkf2upAgpAeF9BJMZmXEbKaTksnn+1nxA== X-Received: by 2002:aa7:d701:0:b0:49a:d3c2:c76f with SMTP id t1-20020aa7d701000000b0049ad3c2c76fmr24069802edq.13.1674400900155; Sun, 22 Jan 2023 07:21:40 -0800 (PST) Received: from localhost.localdomain ([46.216.42.4]) by smtp.googlemail.com with ESMTPSA id a8-20020aa7d908000000b0049dfd6bdc25sm11190075edr.84.2023.01.22.07.21.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 22 Jan 2023 07:21:39 -0800 (PST) From: Dzmitry Sankouski To: u-boot@lists.denx.de Cc: Dzmitry Sankouski , Simon Glass , Mark Kettenis Subject: [PATCH v3 5/5] dm: input: add button_kbd driver Date: Sun, 22 Jan 2023 18:21:25 +0300 Message-Id: <20230122152125.858085-6-dsankouski@gmail.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230122152125.858085-1-dsankouski@gmail.com> References: <20230122152125.858085-1-dsankouski@gmail.com> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 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.103.6 at phobos.denx.de X-Virus-Status: Clean Bootmenu requires an input device with arrows and enter key. A common smartphone luckily has power, volume up/down buttons, which may be used for controlling bootmenu. To use driver, add 'button-kbd' to stdin. Signed-off-by: Dzmitry Sankouski Reviewed-by: Simon Glass --- Changes for v2: - add doc on driver private data struct - use calloc instead of malloc Changes for v3: - none drivers/input/Kconfig | 9 +++ drivers/input/Makefile | 1 + drivers/input/button_kbd.c | 126 +++++++++++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+) create mode 100644 drivers/input/button_kbd.c diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 1c534be005..b9a4e443a3 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -46,6 +46,15 @@ config APPLE_SPI_KEYB laptops based on Apple SoCs. These keyboards use an Apple-specific HID-over-SPI protocol. +config BUTTON_KEYBOARD + bool "Buttons as keyboard" + depends on BUTTON_GPIO + depends on DM_KEYBOARD + help + Enable support for mapping buttons to keycode events. Use linux,code button driver + dt node to define button-event mapping. + For example, an arrows and enter may be implemented to navigate boot menu. + config CROS_EC_KEYB bool "Enable Chrome OS EC keyboard support" depends on INPUT diff --git a/drivers/input/Makefile b/drivers/input/Makefile index ded76bddb2..14c0ea7325 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_$(SPL_TPL_)CROS_EC_KEYB) += cros_ec_keyb.o obj-$(CONFIG_$(SPL_TPL_)OF_CONTROL) += key_matrix.o obj-$(CONFIG_$(SPL_TPL_)DM_KEYBOARD) += input.o keyboard-uclass.o +obj-$(CONFIG_BUTTON_KEYBOARD) += button_kbd.o ifndef CONFIG_SPL_BUILD diff --git a/drivers/input/button_kbd.c b/drivers/input/button_kbd.c new file mode 100644 index 0000000000..99e65f12f0 --- /dev/null +++ b/drivers/input/button_kbd.c @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2023 Dzmitry Sankouski + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * struct button_kbd_priv - driver private data + * + * @input: input configuration + * @button_size: number of buttons found + * @old_state: a pointer to old button states array. Used to determine button state change. + */ +struct button_kbd_priv { + struct input_config *input; + u32 button_size; + u32 *old_state; +}; + +static int button_kbd_start(struct udevice *dev) +{ + struct button_kbd_priv *priv = dev_get_priv(dev); + int i = 0; + struct udevice *button_gpio_devp; + + uclass_foreach_dev_probe(UCLASS_BUTTON, button_gpio_devp) { + struct button_uc_plat *uc_plat = dev_get_uclass_plat(button_gpio_devp); + /* Ignore the top-level button node */ + if (!uc_plat->label) + continue; + debug("Found button %s #%d - %s, probing...\n", + uc_plat->label, i, button_gpio_devp->name); + i++; + } + + priv->button_size = i; + priv->old_state = calloc(i, sizeof(int)); + + return 0; +} + +int button_read_keys(struct input_config *input) +{ + struct button_kbd_priv *priv = dev_get_priv(input->dev); + struct udevice *button_gpio_devp; + struct uclass *uc; + int i = 0; + u32 code, state, state_changed = 0; + + uclass_id_foreach_dev(UCLASS_BUTTON, button_gpio_devp, uc) { + struct button_uc_plat *uc_plat = dev_get_uclass_plat(button_gpio_devp); + /* Ignore the top-level button node */ + if (!uc_plat->label) + continue; + code = button_get_code(button_gpio_devp); + if (!code) + continue; + + state = button_get_state(button_gpio_devp); + state_changed = state != priv->old_state[i]; + + if (state_changed) { + debug("%s: %d\n", uc_plat->label, code); + priv->old_state[i] = state; + input_add_keycode(input, code, state); + } + i++; + } + return 0; +} + +static const struct keyboard_ops button_kbd_ops = { + .start = button_kbd_start, +}; + +static int button_kbd_probe(struct udevice *dev) +{ + struct button_kbd_priv *priv = dev_get_priv(dev); + struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev); + struct stdio_dev *sdev = &uc_priv->sdev; + struct input_config *input = &uc_priv->input; + int ret = 0; + + input_init(input, false); + input_add_tables(input, false); + + /* Register the device. */ + priv->input = input; + input->dev = dev; + input->read_keys = button_read_keys; + strcpy(sdev->name, "button-kbd"); + ret = input_stdio_register(sdev); + if (ret) { + debug("%s: input_stdio_register() failed\n", __func__); + return ret; + } + + return 0; +} + +static const struct udevice_id button_kbd_ids[] = { + { .compatible = "button-kbd" }, + { } +}; + +U_BOOT_DRIVER(button_kbd) = { + .name = "button_kbd", + .id = UCLASS_KEYBOARD, + .of_match = button_kbd_ids, + .ops = &button_kbd_ops, + .priv_auto = sizeof(struct button_kbd_priv), + .probe = button_kbd_probe, +};