mirror of
https://github.com/u-boot/u-boot.git
synced 2025-05-08 19:11:53 +00:00
dm: gpio: Add of-platdata support
Add support for accessing GPIOs using of-plata. This uses the same mechanism as for clocks, but allows use of the xlate() method so that the driver can interpret the parameters. Update the condition for GPIO_HOG so that it is not built into SPL, since it needs SPL_OF_REAL which is not enabled in sandbox_spl. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
3e57ad907c
commit
48609d0789
9 changed files with 93 additions and 9 deletions
|
@ -66,7 +66,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
gpio_b: gpios@1 {
|
gpio_b: gpios@1 {
|
||||||
u-boot,dm-pre-proper;
|
u-boot,dm-spl;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
compatible = "sandbox,gpio";
|
compatible = "sandbox,gpio";
|
||||||
#gpio-cells = <2>;
|
#gpio-cells = <2>;
|
||||||
|
@ -74,6 +74,12 @@
|
||||||
sandbox,gpio-count = <10>;
|
sandbox,gpio-count = <10>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
gpio-test {
|
||||||
|
u-boot,dm-spl;
|
||||||
|
compatible = "sandbox,gpio-test";
|
||||||
|
test-gpios = <&gpio_b 3 0>;
|
||||||
|
};
|
||||||
|
|
||||||
hexagon {
|
hexagon {
|
||||||
compatible = "demo-simple";
|
compatible = "demo-simple";
|
||||||
colour = "white";
|
colour = "white";
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
CONFIG_SYS_TEXT_BASE=0x200000
|
CONFIG_SYS_TEXT_BASE=0x200000
|
||||||
|
CONFIG_SPL_GPIO=y
|
||||||
CONFIG_SPL_LIBCOMMON_SUPPORT=y
|
CONFIG_SPL_LIBCOMMON_SUPPORT=y
|
||||||
CONFIG_SPL_LIBGENERIC_SUPPORT=y
|
CONFIG_SPL_LIBGENERIC_SUPPORT=y
|
||||||
CONFIG_NR_DRAM_BANKS=1
|
CONFIG_NR_DRAM_BANKS=1
|
||||||
|
@ -122,6 +123,7 @@ CONFIG_SANDBOX_GPIO=y
|
||||||
CONFIG_I2C_CROS_EC_TUNNEL=y
|
CONFIG_I2C_CROS_EC_TUNNEL=y
|
||||||
CONFIG_I2C_CROS_EC_LDO=y
|
CONFIG_I2C_CROS_EC_LDO=y
|
||||||
CONFIG_DM_I2C_GPIO=y
|
CONFIG_DM_I2C_GPIO=y
|
||||||
|
# CONFIG_SPL_DM_I2C_GPIO is not set
|
||||||
CONFIG_SYS_I2C_SANDBOX=y
|
CONFIG_SYS_I2C_SANDBOX=y
|
||||||
CONFIG_I2C_MUX=y
|
CONFIG_I2C_MUX=y
|
||||||
CONFIG_I2C_ARB_GPIO_CHALLENGE=y
|
CONFIG_I2C_ARB_GPIO_CHALLENGE=y
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
CONFIG_SYS_TEXT_BASE=0x200000
|
CONFIG_SYS_TEXT_BASE=0x200000
|
||||||
|
CONFIG_SPL_GPIO=y
|
||||||
CONFIG_SPL_LIBCOMMON_SUPPORT=y
|
CONFIG_SPL_LIBCOMMON_SUPPORT=y
|
||||||
CONFIG_SPL_LIBGENERIC_SUPPORT=y
|
CONFIG_SPL_LIBGENERIC_SUPPORT=y
|
||||||
CONFIG_NR_DRAM_BANKS=1
|
CONFIG_NR_DRAM_BANKS=1
|
||||||
|
@ -124,6 +125,7 @@ CONFIG_SANDBOX_GPIO=y
|
||||||
CONFIG_I2C_CROS_EC_TUNNEL=y
|
CONFIG_I2C_CROS_EC_TUNNEL=y
|
||||||
CONFIG_I2C_CROS_EC_LDO=y
|
CONFIG_I2C_CROS_EC_LDO=y
|
||||||
CONFIG_DM_I2C_GPIO=y
|
CONFIG_DM_I2C_GPIO=y
|
||||||
|
# CONFIG_SPL_DM_I2C_GPIO is not set
|
||||||
CONFIG_SYS_I2C_SANDBOX=y
|
CONFIG_SYS_I2C_SANDBOX=y
|
||||||
CONFIG_I2C_MUX=y
|
CONFIG_I2C_MUX=y
|
||||||
CONFIG_I2C_ARB_GPIO_CHALLENGE=y
|
CONFIG_I2C_ARB_GPIO_CHALLENGE=y
|
||||||
|
|
|
@ -33,7 +33,7 @@ obj-$(CONFIG_ROCKCHIP_GPIO) += rk_gpio.o
|
||||||
obj-$(CONFIG_RCAR_GPIO) += gpio-rcar.o
|
obj-$(CONFIG_RCAR_GPIO) += gpio-rcar.o
|
||||||
obj-$(CONFIG_RZA1_GPIO) += gpio-rza1.o
|
obj-$(CONFIG_RZA1_GPIO) += gpio-rza1.o
|
||||||
obj-$(CONFIG_S5P) += s5p_gpio.o
|
obj-$(CONFIG_S5P) += s5p_gpio.o
|
||||||
obj-$(CONFIG_SANDBOX_GPIO) += sandbox.o
|
obj-$(CONFIG_SANDBOX_GPIO) += sandbox.o sandbox_test.o
|
||||||
obj-$(CONFIG_TEGRA_GPIO) += tegra_gpio.o
|
obj-$(CONFIG_TEGRA_GPIO) += tegra_gpio.o
|
||||||
obj-$(CONFIG_TEGRA186_GPIO) += tegra186_gpio.o
|
obj-$(CONFIG_TEGRA186_GPIO) += tegra186_gpio.o
|
||||||
obj-$(CONFIG_DA8XX_GPIO) += da8xx_gpio.o
|
obj-$(CONFIG_DA8XX_GPIO) += da8xx_gpio.o
|
||||||
|
@ -62,7 +62,7 @@ obj-$(CONFIG_OCTEON_GPIO) += octeon_gpio.o
|
||||||
obj-$(CONFIG_MVEBU_GPIO) += mvebu_gpio.o
|
obj-$(CONFIG_MVEBU_GPIO) += mvebu_gpio.o
|
||||||
obj-$(CONFIG_MSM_GPIO) += msm_gpio.o
|
obj-$(CONFIG_MSM_GPIO) += msm_gpio.o
|
||||||
obj-$(CONFIG_$(SPL_)PCF8575_GPIO) += pcf8575_gpio.o
|
obj-$(CONFIG_$(SPL_)PCF8575_GPIO) += pcf8575_gpio.o
|
||||||
obj-$(CONFIG_PM8916_GPIO) += pm8916_gpio.o
|
obj-$(CONFIG_$(SPL_TPL_)PM8916_GPIO) += pm8916_gpio.o
|
||||||
obj-$(CONFIG_MT7620_GPIO) += mt7620_gpio.o
|
obj-$(CONFIG_MT7620_GPIO) += mt7620_gpio.o
|
||||||
obj-$(CONFIG_MT7621_GPIO) += mt7621_gpio.o
|
obj-$(CONFIG_MT7621_GPIO) += mt7621_gpio.o
|
||||||
obj-$(CONFIG_MSCC_SGPIO) += mscc_sgpio.o
|
obj-$(CONFIG_MSCC_SGPIO) += mscc_sgpio.o
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
|
#include <dt-structs.h>
|
||||||
#include <log.h>
|
#include <log.h>
|
||||||
#include <dm/devres.h>
|
#include <dm/devres.h>
|
||||||
#include <dm/device_compat.h>
|
#include <dm/device_compat.h>
|
||||||
|
@ -231,7 +232,7 @@ static int gpio_find_and_xlate(struct gpio_desc *desc,
|
||||||
return gpio_xlate_offs_flags(desc->dev, desc, args);
|
return gpio_xlate_offs_flags(desc->dev, desc, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_GPIO_HOG)
|
#if CONFIG_IS_ENABLED(GPIO_HOG)
|
||||||
|
|
||||||
struct gpio_hog_priv {
|
struct gpio_hog_priv {
|
||||||
struct gpio_desc gpiod;
|
struct gpio_desc gpiod;
|
||||||
|
@ -1226,6 +1227,27 @@ int gpio_get_list_count(struct udevice *dev, const char *list_name)
|
||||||
}
|
}
|
||||||
#endif /* OF_PLATDATA */
|
#endif /* OF_PLATDATA */
|
||||||
|
|
||||||
|
#if CONFIG_IS_ENABLED(OF_PLATDATA)
|
||||||
|
int gpio_request_by_phandle(struct udevice *dev,
|
||||||
|
const struct phandle_2_arg *cells,
|
||||||
|
struct gpio_desc *desc, int flags)
|
||||||
|
{
|
||||||
|
struct ofnode_phandle_args args;
|
||||||
|
struct udevice *gpio_dev;
|
||||||
|
const int index = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = device_get_by_ofplat_idx(cells->idx, &gpio_dev);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
args.args[0] = cells->arg[0];
|
||||||
|
args.args[1] = cells->arg[1];
|
||||||
|
|
||||||
|
return gpio_request_tail(ret, NULL, &args, NULL, index, desc, flags,
|
||||||
|
index > 0, gpio_dev);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc)
|
int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc)
|
||||||
{
|
{
|
||||||
/* For now, we don't do any checking of dev */
|
/* For now, we don't do any checking of dev */
|
||||||
|
@ -1430,7 +1452,7 @@ static int gpio_post_bind(struct udevice *dev)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_GPIO_HOG)) {
|
if (CONFIG_IS_ENABLED(OF_REAL) && IS_ENABLED(CONFIG_GPIO_HOG)) {
|
||||||
dev_for_each_subnode(node, dev) {
|
dev_for_each_subnode(node, dev) {
|
||||||
if (ofnode_read_bool(node, "gpio-hog")) {
|
if (ofnode_read_bool(node, "gpio-hog")) {
|
||||||
const char *name = ofnode_get_name(node);
|
const char *name = ofnode_get_name(node);
|
||||||
|
|
|
@ -323,11 +323,13 @@ static const struct dm_gpio_ops gpio_sandbox_ops = {
|
||||||
|
|
||||||
static int sandbox_gpio_of_to_plat(struct udevice *dev)
|
static int sandbox_gpio_of_to_plat(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
|
if (CONFIG_IS_ENABLED(OF_REAL)) {
|
||||||
|
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
|
||||||
|
|
||||||
uc_priv->gpio_count = dev_read_u32_default(dev, "sandbox,gpio-count",
|
uc_priv->gpio_count =
|
||||||
0);
|
dev_read_u32_default(dev, "sandbox,gpio-count", 0);
|
||||||
uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
|
uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -371,6 +373,8 @@ U_BOOT_DRIVER(sandbox_gpio) = {
|
||||||
|
|
||||||
DM_DRIVER_ALIAS(sandbox_gpio, sandbox_gpio_alias)
|
DM_DRIVER_ALIAS(sandbox_gpio, sandbox_gpio_alias)
|
||||||
|
|
||||||
|
#if CONFIG_IS_ENABLED(PINCTRL)
|
||||||
|
|
||||||
/* pincontrol: used only to check GPIO pin configuration (pinmux command) */
|
/* pincontrol: used only to check GPIO pin configuration (pinmux command) */
|
||||||
|
|
||||||
struct sb_pinctrl_priv {
|
struct sb_pinctrl_priv {
|
||||||
|
@ -579,3 +583,5 @@ U_BOOT_DRIVER(sandbox_pinctrl_gpio) = {
|
||||||
.priv_auto = sizeof(struct sb_pinctrl_priv),
|
.priv_auto = sizeof(struct sb_pinctrl_priv),
|
||||||
ACPI_OPS_PTR(&pinctrl_sandbox_acpi_ops)
|
ACPI_OPS_PTR(&pinctrl_sandbox_acpi_ops)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif /* PINCTRL */
|
||||||
|
|
21
drivers/gpio/sandbox_test.c
Normal file
21
drivers/gpio/sandbox_test.c
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
/*
|
||||||
|
* Sandbox driver for testing GPIOs with of-platdata
|
||||||
|
*
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <asm-generic/gpio.h>
|
||||||
|
|
||||||
|
static const struct udevice_id sandbox_gpio_test_ids[] = {
|
||||||
|
{ .compatible = "sandbox,gpio-test" },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(sandbox_gpio_test) = {
|
||||||
|
.name = "sandbox_gpio_test",
|
||||||
|
.id = UCLASS_MISC,
|
||||||
|
.of_match = sandbox_gpio_test_ids,
|
||||||
|
};
|
|
@ -608,6 +608,11 @@ int gpio_request_list_by_name(struct udevice *dev, const char *list_name,
|
||||||
*/
|
*/
|
||||||
int dm_gpio_request(struct gpio_desc *desc, const char *label);
|
int dm_gpio_request(struct gpio_desc *desc, const char *label);
|
||||||
|
|
||||||
|
struct phandle_2_arg;
|
||||||
|
int gpio_request_by_phandle(struct udevice *dev,
|
||||||
|
const struct phandle_2_arg *cells,
|
||||||
|
struct gpio_desc *desc, int flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gpio_get_list_count() - Returns the number of GPIOs in a list
|
* gpio_get_list_count() - Returns the number of GPIOs in a list
|
||||||
*
|
*
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <dm/test.h>
|
#include <dm/test.h>
|
||||||
#include <test/test.h>
|
#include <test/test.h>
|
||||||
#include <test/ut.h>
|
#include <test/ut.h>
|
||||||
|
#include <asm-generic/gpio.h>
|
||||||
#include <asm/global_data.h>
|
#include <asm/global_data.h>
|
||||||
|
|
||||||
/* Test that we can find a device using of-platdata */
|
/* Test that we can find a device using of-platdata */
|
||||||
|
@ -259,3 +260,22 @@ static int dm_test_of_plat_irq(struct unit_test_state *uts)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
DM_TEST(dm_test_of_plat_irq, UT_TESTF_SCAN_PDATA);
|
DM_TEST(dm_test_of_plat_irq, UT_TESTF_SCAN_PDATA);
|
||||||
|
|
||||||
|
/* Test GPIOs with of-platdata */
|
||||||
|
static int dm_test_of_plat_gpio(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
struct dtd_sandbox_gpio_test *plat;
|
||||||
|
struct udevice *dev;
|
||||||
|
struct gpio_desc desc;
|
||||||
|
|
||||||
|
ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "sandbox_gpio_test",
|
||||||
|
&dev));
|
||||||
|
plat = dev_get_plat(dev);
|
||||||
|
|
||||||
|
ut_assertok(gpio_request_by_phandle(dev, &plat->test_gpios[0], &desc,
|
||||||
|
GPIOD_IS_OUT));
|
||||||
|
ut_asserteq_str("sandbox_gpio", desc.dev->name);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DM_TEST(dm_test_of_plat_gpio, UT_TESTF_SCAN_PDATA);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue