[PATCH 1/7] dm: button: add an uclass for button

Add a new uclass for button that implements two functions: - button_get_by_label - button_get_status
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com --- drivers/Kconfig | 2 ++ drivers/Makefile | 1 + drivers/button/Kconfig | 12 ++++++++++ drivers/button/Makefile | 5 ++++ drivers/button/button-uclass.c | 47 +++++++++++++++++++++++++++++++++++++ include/button.h | 53 ++++++++++++++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + 7 files changed, 121 insertions(+) create mode 100644 drivers/button/Kconfig create mode 100644 drivers/button/Makefile create mode 100644 drivers/button/button-uclass.c create mode 100644 include/button.h
diff --git a/drivers/Kconfig b/drivers/Kconfig index e34a227..3cb05aa 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -14,6 +14,8 @@ source "drivers/block/Kconfig"
source "drivers/bootcount/Kconfig"
+source "drivers/button/Kconfig" + source "drivers/cache/Kconfig"
source "drivers/clk/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index 94e8c5d..727a713 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0+
+obj-$(CONFIG_$(SPL_TPL_)BUTTON) += button/ obj-$(CONFIG_$(SPL_TPL_)CACHE) += cache/ obj-$(CONFIG_$(SPL_TPL_)CLK) += clk/ obj-$(CONFIG_$(SPL_TPL_)DM) += core/ diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig new file mode 100644 index 0000000..8301858 --- /dev/null +++ b/drivers/button/Kconfig @@ -0,0 +1,12 @@ +menu "Button Support" + +config BUTTON + bool "Enable button support" + depends on DM + help + Many boards have buttons which can be used to change behaviour (reset, ...). + U-Boot provides a uclass API to implement this feature. Button drivers + can provide access to board-specific buttons. Use of the device tree + for configuration is encouraged. + +endmenu diff --git a/drivers/button/Makefile b/drivers/button/Makefile new file mode 100644 index 0000000..0b4c128 --- /dev/null +++ b/drivers/button/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2020 Philippe Reynes philippe.reynes@softathome.com + +obj-$(CONFIG_BUTTON) += button-uclass.o diff --git a/drivers/button/button-uclass.c b/drivers/button/button-uclass.c new file mode 100644 index 0000000..d6cda78 --- /dev/null +++ b/drivers/button/button-uclass.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Philippe Reynes philippe.reynes@softathome.com + * + * Based on led-uclass.c + */ + +#include <common.h> +#include <dm.h> +#include <dm/uclass-internal.h> +#include <button.h> + +int button_get_by_label(const char *label, struct udevice **devp) +{ + struct udevice *dev; + struct uclass *uc; + int ret; + + ret = uclass_get(UCLASS_BUTTON, &uc); + if (ret) + return ret; + uclass_foreach_dev(dev, uc) { + struct button_uc_plat *uc_plat = dev_get_uclass_platdata(dev); + + /* Ignore the top-level button node */ + if (uc_plat->label && !strcmp(label, uc_plat->label)) + return uclass_get_device_tail(dev, 0, devp); + } + + return -ENODEV; +} + +enum button_state_t button_get_state(struct udevice *dev) +{ + struct button_ops *ops = button_get_ops(dev); + + if (!ops->get_state) + return -ENOSYS; + + return ops->get_state(dev); +} + +UCLASS_DRIVER(button) = { + .id = UCLASS_BUTTON, + .name = "button", + .per_device_platdata_auto_alloc_size = sizeof(struct button_uc_plat), +}; diff --git a/include/button.h b/include/button.h new file mode 100644 index 0000000..333fc23 --- /dev/null +++ b/include/button.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2020 Philippe Reynes philippe.reynes@softathome.com + */ + +#ifndef __BUTTON_H +#define __BUTTON_H + +/** + * struct button_uc_plat - Platform data the uclass stores about each device + * + * @label: Button label + */ +struct button_uc_plat { + const char *label; +}; + +enum button_state_t { + BUTTON_OFF = 0, + BUTTON_ON = 1, + BUTTON_COUNT, +}; + +struct button_ops { + /** + * get_state() - get the state of a button + * + * @dev: button device to change + * @return button state button_state_t, or -ve on error + */ + enum button_state_t (*get_state)(struct udevice *dev); +}; + +#define button_get_ops(dev) ((struct button_ops *)(dev)->driver->ops) + +/** + * button_get_by_label() - Find a button device by label + * + * @label: button label to look up + * @devp: Returns the associated device, if found + * @return 0 if found, -ENODEV if not found, other -ve on error + */ +int button_get_by_label(const char *label, struct udevice **devp); + +/** + * button_get_state() - get the state of a button + * + * @dev: button device to change + * @return button state button_state_t, or -ve on error + */ +enum button_state_t button_get_state(struct udevice *dev); + +#endif diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 7837d45..85c7149 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -38,6 +38,7 @@ enum uclass_id { UCLASS_BLK, /* Block device */ UCLASS_BOARD, /* Device information from hardware */ UCLASS_BOOTCOUNT, /* Bootcount backing store */ + UCLASS_BUTTON, /* Button */ UCLASS_CACHE, /* Cache controller */ UCLASS_CLK, /* Clock source, e.g. used by peripherals */ UCLASS_CPU, /* CPU, typically part of an SoC */

Add a simple driver which allows use of buttons attached to GPIOs.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com --- drivers/button/Kconfig | 10 ++++ drivers/button/Makefile | 1 + drivers/button/button-gpio.c | 111 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+) create mode 100644 drivers/button/button-gpio.c
diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig index 8301858..7de1a97 100644 --- a/drivers/button/Kconfig +++ b/drivers/button/Kconfig @@ -9,4 +9,14 @@ config BUTTON can provide access to board-specific buttons. Use of the device tree for configuration is encouraged.
+config BUTTON_GPIO + bool "Button gpio" + depends on BUTTON + default n + help + Enable support for buttons which are connected to GPIO lines. These + GPIOs may be on the SoC or some other device which provides GPIOs. + The GPIO driver must used driver model. Buttons are configured using + the device tree. + endmenu diff --git a/drivers/button/Makefile b/drivers/button/Makefile index 0b4c128..fcc10eb 100644 --- a/drivers/button/Makefile +++ b/drivers/button/Makefile @@ -3,3 +3,4 @@ # Copyright (C) 2020 Philippe Reynes philippe.reynes@softathome.com
obj-$(CONFIG_BUTTON) += button-uclass.o +obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o diff --git a/drivers/button/button-gpio.c b/drivers/button/button-gpio.c new file mode 100644 index 0000000..6ad0094 --- /dev/null +++ b/drivers/button/button-gpio.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 Philippe Reynes philippe.reynes@softathome.com + */ + +#include <common.h> +#include <dm.h> +#include <dm/lists.h> +#include <dm/uclass-internal.h> +#include <log.h> +#include <asm/gpio.h> +#include <button.h> + +struct button_gpio_priv { + struct gpio_desc gpio; +}; + +static enum button_state_t button_gpio_get_state(struct udevice *dev) +{ + struct button_gpio_priv *priv = dev_get_priv(dev); + int ret; + + if (!dm_gpio_is_valid(&priv->gpio)) + return -EREMOTEIO; + ret = dm_gpio_get_value(&priv->gpio); + if (ret < 0) + return ret; + + return ret ? BUTTON_ON : BUTTON_OFF; +} + +static int button_gpio_probe(struct udevice *dev) +{ + struct button_uc_plat *uc_plat = dev_get_uclass_platdata(dev); + struct button_gpio_priv *priv = dev_get_priv(dev); + int ret; + + /* Ignore the top-level button node */ + if (!uc_plat->label) + return 0; + + ret = gpio_request_by_name(dev, "gpios", 0, &priv->gpio, GPIOD_IS_IN); + if (ret) + return ret; + + return 0; +} + +static int button_gpio_remove(struct udevice *dev) +{ + /* + * The GPIO driver may have already been removed. We will need to + * address this more generally. + */ + if (IS_ENABLED(CONFIG_SANDBOX)) { + struct button_gpio_priv *priv = dev_get_priv(dev); + + if (dm_gpio_is_valid(&priv->gpio)) + dm_gpio_free(dev, &priv->gpio); + } + + return 0; +} + +static int button_gpio_bind(struct udevice *parent) +{ + struct udevice *dev; + ofnode node; + int ret; + + dev_for_each_subnode(node, parent) { + struct button_uc_plat *uc_plat; + const char *label; + + label = ofnode_read_string(node, "label"); + if (!label) { + debug("%s: node %s has no label\n", __func__, + ofnode_get_name(node)); + return -EINVAL; + } + ret = device_bind_driver_to_node(parent, "button_gpio", + ofnode_get_name(node), + node, &dev); + if (ret) + return ret; + uc_plat = dev_get_uclass_platdata(dev); + uc_plat->label = label; + } + + return 0; +} + +static const struct button_ops button_gpio_ops = { + .get_state = button_gpio_get_state, +}; + +static const struct udevice_id button_gpio_ids[] = { + { .compatible = "button-gpio" }, + { } +}; + +U_BOOT_DRIVER(button_gpio) = { + .name = "button_gpio", + .id = UCLASS_BUTTON, + .of_match = button_gpio_ids, + .ops = &button_gpio_ops, + .priv_auto_alloc_size = sizeof(struct button_gpio_priv), + .bind = button_gpio_bind, + .probe = button_gpio_probe, + .remove = button_gpio_remove, +};

On Mon, 13 Jul 2020 at 06:56, Philippe Reynes philippe.reynes@softathome.com wrote:
Add a simple driver which allows use of buttons attached to GPIOs.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com
drivers/button/Kconfig | 10 ++++ drivers/button/Makefile | 1 + drivers/button/button-gpio.c | 111 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+) create mode 100644 drivers/button/button-gpio.c
Reviewed-by: Simon Glass sjg@chromium.org
diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig index 8301858..7de1a97 100644 --- a/drivers/button/Kconfig +++ b/drivers/button/Kconfig @@ -9,4 +9,14 @@ config BUTTON can provide access to board-specific buttons. Use of the device tree for configuration is encouraged.
+config BUTTON_GPIO
bool "Button gpio"
depends on BUTTON
default n
not needed
help
Enable support for buttons which are connected to GPIO lines. These
GPIOs may be on the SoC or some other device which provides GPIOs.
The GPIO driver must used driver model. Buttons are configured using
the device tree.
endmenu diff --git a/drivers/button/Makefile b/drivers/button/Makefile index 0b4c128..fcc10eb 100644 --- a/drivers/button/Makefile +++ b/drivers/button/Makefile @@ -3,3 +3,4 @@ # Copyright (C) 2020 Philippe Reynes philippe.reynes@softathome.com
obj-$(CONFIG_BUTTON) += button-uclass.o +obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o diff --git a/drivers/button/button-gpio.c b/drivers/button/button-gpio.c new file mode 100644 index 0000000..6ad0094 --- /dev/null +++ b/drivers/button/button-gpio.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- Copyright (C) 2020 Philippe Reynes philippe.reynes@softathome.com
- */
+#include <common.h> +#include <dm.h> +#include <dm/lists.h> +#include <dm/uclass-internal.h> +#include <log.h> +#include <asm/gpio.h> +#include <button.h>
Please fix order https://www.denx.de/wiki/U-Boot/CodingStyle
+struct button_gpio_priv {
struct gpio_desc gpio;
+};
+static enum button_state_t button_gpio_get_state(struct udevice *dev) +{
struct button_gpio_priv *priv = dev_get_priv(dev);
int ret;
if (!dm_gpio_is_valid(&priv->gpio))
return -EREMOTEIO;
ret = dm_gpio_get_value(&priv->gpio);
if (ret < 0)
return ret;
return ret ? BUTTON_ON : BUTTON_OFF;
+}
+static int button_gpio_probe(struct udevice *dev) +{
struct button_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
struct button_gpio_priv *priv = dev_get_priv(dev);
int ret;
/* Ignore the top-level button node */
if (!uc_plat->label)
return 0;
ret = gpio_request_by_name(dev, "gpios", 0, &priv->gpio, GPIOD_IS_IN);
if (ret)
return ret;
return 0;
+}
+static int button_gpio_remove(struct udevice *dev) +{
/*
* The GPIO driver may have already been removed. We will need to
* address this more generally.
What is needed here?
*/
if (IS_ENABLED(CONFIG_SANDBOX)) {
struct button_gpio_priv *priv = dev_get_priv(dev);
if (dm_gpio_is_valid(&priv->gpio))
dm_gpio_free(dev, &priv->gpio);
}
return 0;
+}
[..]

Adds a command 'button' that provides the list of buttons supported by the board, and the state of a button.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com --- cmd/Kconfig | 11 ++++++++ cmd/Makefile | 1 + cmd/button.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 cmd/button.c
diff --git a/cmd/Kconfig b/cmd/Kconfig index 192b3b2..750d26a 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1664,6 +1664,17 @@ config CMD_BLOCK_CACHE during development, but also allows the cache to be disabled when it might hurt performance (e.g. when using the ums command).
+config CMD_BUTTON + bool "button" + depends on BUTTON + default y if BUTTON + help + Enable the 'button' command which allows to get the status of + buttons supported by the board. The buttonss can be listed with + 'button list' and state can be known with 'button <label>'. + Any button drivers can be controlled with this command, e.g. + button_gpio. + config CMD_CACHE bool "icache or dcache" help diff --git a/cmd/Makefile b/cmd/Makefile index 974ad48..5ded3a6 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -32,6 +32,7 @@ obj-$(CONFIG_CMD_BOOTSTAGE) += bootstage.o obj-$(CONFIG_CMD_BOOTZ) += bootz.o obj-$(CONFIG_CMD_BOOTI) += booti.o obj-$(CONFIG_CMD_BTRFS) += btrfs.o +obj-$(CONFIG_CMD_BUTTON) += button.o obj-$(CONFIG_CMD_CACHE) += cache.o obj-$(CONFIG_CMD_CBFS) += cbfs.o obj-$(CONFIG_CMD_CLK) += clk.o diff --git a/cmd/button.c b/cmd/button.c new file mode 100644 index 0000000..84ad165 --- /dev/null +++ b/cmd/button.c @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 Philippe Reynes philippe.reynes@softathome.com + * + * Based on led.c + */ + +#include <common.h> +#include <command.h> +#include <dm.h> +#include <button.h> +#include <dm/uclass-internal.h> + +static const char *const state_label[] = { + [BUTTON_OFF] = "off", + [BUTTON_ON] = "on", +}; + +static int show_button_state(struct udevice *dev) +{ + int ret; + + ret = button_get_state(dev); + if (ret >= BUTTON_COUNT) + ret = -EINVAL; + if (ret >= 0) + printf("%s\n", state_label[ret]); + + return ret; +} + +static int list_buttons(void) +{ + struct udevice *dev; + int ret; + + for (uclass_find_first_device(UCLASS_BUTTON, &dev); + dev; + uclass_find_next_device(&dev)) { + struct button_uc_plat *plat = dev_get_uclass_platdata(dev); + + if (!plat->label) + continue; + printf("%-15s ", plat->label); + if (device_active(dev)) { + ret = show_button_state(dev); + if (ret < 0) + printf("Error %d\n", ret); + } else { + printf("<inactive>\n"); + } + } + + return 0; +} + +int do_button(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + const char *button_label; + struct udevice *dev; + int ret; + + /* Validate arguments */ + if (argc < 2) + return CMD_RET_USAGE; + button_label = argv[1]; + if (strncmp(button_label, "list", 4) == 0) + return list_buttons(); + + ret = button_get_by_label(button_label, &dev); + if (ret) { + printf("Button '%s' not found (err=%d)\n", button_label, ret); + return CMD_RET_FAILURE; + } + + ret = show_button_state(dev); + + return 0; +} + +U_BOOT_CMD( + button, 4, 1, do_button, + "manage buttons", + "<button_label> \tGet button state\n" + "button list\t\tShow a list of buttons" +);

On Mon, 13 Jul 2020 at 06:56, Philippe Reynes philippe.reynes@softathome.com wrote:
Adds a command 'button' that provides the list of buttons supported by the board, and the state of a button.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com
cmd/Kconfig | 11 ++++++++ cmd/Makefile | 1 + cmd/button.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 cmd/button.c
Reviewed-by: Simon Glass sjg@chromium.org

Adds two buttons on sandbox so button framework may be tested.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com --- arch/sandbox/dts/sandbox.dtsi | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi index e1f68cd..bd87dac 100644 --- a/arch/sandbox/dts/sandbox.dtsi +++ b/arch/sandbox/dts/sandbox.dtsi @@ -15,6 +15,20 @@ #sound-dai-cells = <1>; };
+ buttons { + compatible = "button-gpio"; + + summer { + gpios = <&gpio_a 3 0>; + label = "summer"; + }; + + christmas { + gpios = <&gpio_a 4 0>; + label = "christmas"; + }; + }; + gpio_a: gpios@0 { u-boot,dm-pre-reloc; gpio-controller;

On Mon, 13 Jul 2020 at 06:56, Philippe Reynes philippe.reynes@softathome.com wrote:
Adds two buttons on sandbox so button framework may be tested.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com
arch/sandbox/dts/sandbox.dtsi | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org
But don't you want this in test.dtsi too if it is for testing?

Enable the support of button (driver and command) on sandbox64.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com --- configs/sandbox64_defconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index a3f049e..89ba504 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -90,6 +90,8 @@ CONFIG_ADC=y CONFIG_ADC_SANDBOX=y CONFIG_AXI=y CONFIG_AXI_SANDBOX=y +CONFIG_BUTTON=y +CONFIG_BUTTON_GPIO=y CONFIG_CLK=y CONFIG_CPU=y CONFIG_DM_DEMO=y

On Mon, 13 Jul 2020 at 06:56, Philippe Reynes philippe.reynes@softathome.com wrote:
Enable the support of button (driver and command) on sandbox64.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com
configs/sandbox64_defconfig | 2 ++ 1 file changed, 2 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org

Enable the support of button (driver and command) on sandbox.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com --- configs/sandbox_defconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 5b75693..67801ed 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -102,6 +102,8 @@ CONFIG_AXI_SANDBOX=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_DM_BOOTCOUNT=y CONFIG_DM_BOOTCOUNT_RTC=y +CONFIG_BUTTON=y +CONFIG_BUTTON_GPIO=y CONFIG_CLK=y CONFIG_CLK_COMPOSITE_CCF=y CONFIG_SANDBOX_CLK_CCF=y

On Mon, 13 Jul 2020 at 06:56, Philippe Reynes philippe.reynes@softathome.com wrote:
Enable the support of button (driver and command) on sandbox.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com
configs/sandbox_defconfig | 2 ++ 1 file changed, 2 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org

Adds tests for the button commands.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com --- arch/sandbox/dts/test.dts | 14 ++++++++++++++ test/py/tests/test_button.py | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 test/py/tests/test_button.py
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 5ce5e28..101d729 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -51,6 +51,20 @@ #sound-dai-cells = <1>; };
+ buttons { + compatible = "button-gpio"; + + summer { + gpios = <&gpio_a 3 0>; + label = "summer"; + }; + + christmas { + gpios = <&gpio_a 4 0>; + label = "christmas"; + }; + }; + cros_ec: cros-ec { reg = <0 0>; compatible = "google,cros-ec-sandbox"; diff --git a/test/py/tests/test_button.py b/test/py/tests/test_button.py new file mode 100644 index 0000000..98067a9 --- /dev/null +++ b/test/py/tests/test_button.py @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: GPL-2.0+ + +import pytest + +@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('cmd_button') +def test_button_exit_statuses(u_boot_console): + """Test that non-input button commands correctly return the command + success/failure status.""" + + expected_response = 'rc:0' + response = u_boot_console.run_command('button list; echo rc:$?') + assert(expected_response in response) + response = u_boot_console.run_command('button summer; echo rc:$?') + assert(expected_response in response) + + expected_response = 'rc:1' + response = u_boot_console.run_command('button nonexistent-button; echo rc:$?') + assert(expected_response in response)

Hi Philippe,
On Mon, 13 Jul 2020 at 06:56, Philippe Reynes philippe.reynes@softathome.com wrote:
Adds tests for the button commands.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com
arch/sandbox/dts/test.dts | 14 ++++++++++++++ test/py/tests/test_button.py | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 test/py/tests/test_button.py
Reviewed-by: Simon Glass sjg@chromium.org
But please also add a test/dm/button.c test that tests the uclass and sandbox device.
Regards, Simon

Hi Philippe,
On Mon, 13 Jul 2020 at 06:56, Philippe Reynes philippe.reynes@softathome.com wrote:
Add a new uclass for button that implements two functions:
- button_get_by_label
- button_get_status
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com
drivers/Kconfig | 2 ++ drivers/Makefile | 1 + drivers/button/Kconfig | 12 ++++++++++ drivers/button/Makefile | 5 ++++ drivers/button/button-uclass.c | 47 +++++++++++++++++++++++++++++++++++++ include/button.h | 53 ++++++++++++++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + 7 files changed, 121 insertions(+) create mode 100644 drivers/button/Kconfig create mode 100644 drivers/button/Makefile create mode 100644 drivers/button/button-uclass.c create mode 100644 include/button.h
Reviewed-by: Simon Glass sjg@chromium.org
Please see below
diff --git a/drivers/Kconfig b/drivers/Kconfig index e34a227..3cb05aa 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -14,6 +14,8 @@ source "drivers/block/Kconfig"
source "drivers/bootcount/Kconfig"
+source "drivers/button/Kconfig"
source "drivers/cache/Kconfig"
source "drivers/clk/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index 94e8c5d..727a713 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0+
+obj-$(CONFIG_$(SPL_TPL_)BUTTON) += button/ obj-$(CONFIG_$(SPL_TPL_)CACHE) += cache/ obj-$(CONFIG_$(SPL_TPL_)CLK) += clk/ obj-$(CONFIG_$(SPL_TPL_)DM) += core/ diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig new file mode 100644 index 0000000..8301858 --- /dev/null +++ b/drivers/button/Kconfig @@ -0,0 +1,12 @@ +menu "Button Support"
+config BUTTON
bool "Enable button support"
depends on DM
help
Many boards have buttons which can be used to change behaviour (reset, ...).
U-Boot provides a uclass API to implement this feature. Button drivers
can provide access to board-specific buttons. Use of the device tree
for configuration is encouraged.
+endmenu diff --git a/drivers/button/Makefile b/drivers/button/Makefile new file mode 100644 index 0000000..0b4c128 --- /dev/null +++ b/drivers/button/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2020 Philippe Reynes philippe.reynes@softathome.com
+obj-$(CONFIG_BUTTON) += button-uclass.o diff --git a/drivers/button/button-uclass.c b/drivers/button/button-uclass.c new file mode 100644 index 0000000..d6cda78 --- /dev/null +++ b/drivers/button/button-uclass.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2020 Philippe Reynes philippe.reynes@softathome.com
- Based on led-uclass.c
- */
+#include <common.h> +#include <dm.h> +#include <dm/uclass-internal.h> +#include <button.h>
this one should go below common.h
+int button_get_by_label(const char *label, struct udevice **devp) +{
struct udevice *dev;
struct uclass *uc;
int ret;
ret = uclass_get(UCLASS_BUTTON, &uc);
if (ret)
return ret;
uclass_foreach_dev(dev, uc) {
uclass_id_foreach_dev
struct button_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
/* Ignore the top-level button node */
if (uc_plat->label && !strcmp(label, uc_plat->label))
return uclass_get_device_tail(dev, 0, devp);
}
return -ENODEV;
+}
+enum button_state_t button_get_state(struct udevice *dev) +{
struct button_ops *ops = button_get_ops(dev);
if (!ops->get_state)
return -ENOSYS;
return ops->get_state(dev);
+}
+UCLASS_DRIVER(button) = {
.id = UCLASS_BUTTON,
.name = "button",
.per_device_platdata_auto_alloc_size = sizeof(struct button_uc_plat),
+}; diff --git a/include/button.h b/include/button.h new file mode 100644 index 0000000..333fc23 --- /dev/null +++ b/include/button.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/*
- Copyright (C) 2020 Philippe Reynes philippe.reynes@softathome.com
- */
+#ifndef __BUTTON_H +#define __BUTTON_H
+/**
- struct button_uc_plat - Platform data the uclass stores about each device
- @label: Button label
- */
+struct button_uc_plat {
const char *label;
+};
comment for this enum:
+enum button_state_t {
BUTTON_OFF = 0,
BUTTON_ON = 1,
BUTTON_COUNT,
+};
+struct button_ops {
/**
* get_state() - get the state of a button
*
* @dev: button device to change
* @return button state button_state_t, or -ve on error
*/
enum button_state_t (*get_state)(struct udevice *dev);
+};
+#define button_get_ops(dev) ((struct button_ops *)(dev)->driver->ops)
+/**
- button_get_by_label() - Find a button device by label
- @label: button label to look up
- @devp: Returns the associated device, if found
- @return 0 if found, -ENODEV if not found, other -ve on error
- */
+int button_get_by_label(const char *label, struct udevice **devp);
+/**
- button_get_state() - get the state of a button
- @dev: button device to change
- @return button state button_state_t, or -ve on error
- */
+enum button_state_t button_get_state(struct udevice *dev);
+#endif diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 7837d45..85c7149 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -38,6 +38,7 @@ enum uclass_id { UCLASS_BLK, /* Block device */ UCLASS_BOARD, /* Device information from hardware */ UCLASS_BOOTCOUNT, /* Bootcount backing store */
UCLASS_BUTTON, /* Button */ UCLASS_CACHE, /* Cache controller */ UCLASS_CLK, /* Clock source, e.g. used by peripherals */ UCLASS_CPU, /* CPU, typically part of an SoC */
-- 2.7.4
Regards, Simon
participants (2)
-
Philippe Reynes
-
Simon Glass