summaryrefslogtreecommitdiff
path: root/drivers/gpio
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2019-12-18 07:20:19 -0500
committerTom Rini <trini@konsulko.com>2019-12-18 07:20:19 -0500
commitc0912f9bbfb26dd03d189953678691b799d35b6e (patch)
treef879600cd26b8d4678a174854b623941e5dc2ada /drivers/gpio
parent533c9f5714bdba79dc6f2629284d4c1a08a611d1 (diff)
parenta1d6dc3f84071f05574044f337dbdca70fae495d (diff)
Merge branch 'next' of https://gitlab.denx.de/u-boot/custodians/u-boot-x86 into next
- Various x86 common codes updated for TPL/SPL - I2C designware driver updated for PCI - ICH SPI driver updated to support Apollo Lake - Add Intel FSP2 base support - Intel Apollo Lake platform specific drivers support - Add a new board Google Chromebook Coral
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/Kconfig31
-rw-r--r--drivers/gpio/Makefile5
-rw-r--r--drivers/gpio/at91_gpio.c6
-rw-r--r--drivers/gpio/atmel_pio4.c2
-rw-r--r--drivers/gpio/da8xx_gpio.c7
-rw-r--r--drivers/gpio/da8xx_gpio.h2
-rw-r--r--drivers/gpio/intel_gpio.c161
-rw-r--r--drivers/gpio/mxc_gpio.c4
-rw-r--r--drivers/gpio/mxs_gpio.c4
-rw-r--r--drivers/gpio/omap_gpio.c6
-rw-r--r--drivers/gpio/sunxi_gpio.c8
11 files changed, 216 insertions, 20 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index c1ad5d64a3..1de6f5225e 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -14,6 +14,28 @@ config DM_GPIO
particular GPIOs that they provide. The uclass interface
is defined in include/asm-generic/gpio.h.
+config SPL_DM_GPIO
+ bool "Enable Driver Model for GPIO drivers in SPL"
+ depends on DM_GPIO && SPL_DM && SPL_GPIO_SUPPORT
+ default y
+ help
+ Enable driver model for GPIO access in SPL. The standard GPIO
+ interface (gpio_get_value(), etc.) is then implemented by
+ the GPIO uclass. Drivers provide methods to query the
+ particular GPIOs that they provide. The uclass interface
+ is defined in include/asm-generic/gpio.h.
+
+config TPL_DM_GPIO
+ bool "Enable Driver Model for GPIO drivers in TPL"
+ depends on DM_GPIO && TPL_DM && TPL_GPIO_SUPPORT
+ default y
+ help
+ Enable driver model for GPIO access in TPL. The standard GPIO
+ interface (gpio_get_value(), etc.) is then implemented by
+ the GPIO uclass. Drivers provide methods to query the
+ particular GPIOs that they provide. The uclass interface
+ is defined in include/asm-generic/gpio.h.
+
config GPIO_HOG
bool "Enable GPIO hog support"
depends on DM_GPIO
@@ -82,6 +104,15 @@ config INTEL_BROADWELL_GPIO
driver from the common Intel ICH6 driver. It supports a total of
95 GPIOs which can be configured from the device tree.
+config INTEL_GPIO
+ bool "Intel generic GPIO driver"
+ depends on DM_GPIO
+ help
+ Say yes here to select Intel generic GPIO driver. This controller
+ supports recent chips (e.g. Apollo Lake). It permits basic GPIO
+ control including setting pins to input/output. It makes use of its
+ parent pinctrl driver to actually effect changes.
+
config INTEL_ICH6_GPIO
bool "Intel ICH6 compatible legacy GPIO driver"
depends on DM_GPIO
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index ccc49e2eb0..449046b64c 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -7,14 +7,17 @@ ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_DWAPB_GPIO) += dwapb_gpio.o
obj-$(CONFIG_AXP_GPIO) += axp_gpio.o
endif
-obj-$(CONFIG_DM_GPIO) += gpio-uclass.o
+obj-$(CONFIG_$(SPL_TPL_)DM_GPIO) += gpio-uclass.o
obj-$(CONFIG_$(SPL_)DM_PCA953X) += pca953x_gpio.o
+ifdef CONFIG_$(SPL_TPL_)GPIO
obj-$(CONFIG_DM_74X164) += 74x164_gpio.o
+endif
obj-$(CONFIG_AT91_GPIO) += at91_gpio.o
obj-$(CONFIG_ATMEL_PIO4) += atmel_pio4.o
obj-$(CONFIG_BCM6345_GPIO) += bcm6345_gpio.o
+obj-$(CONFIG_INTEL_GPIO) += intel_gpio.o
obj-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o
obj-$(CONFIG_INTEL_BROADWELL_GPIO) += intel_broadwell_gpio.o
obj-$(CONFIG_KIRKWOOD_GPIO) += kw_gpio.o
diff --git a/drivers/gpio/at91_gpio.c b/drivers/gpio/at91_gpio.c
index dbfed72c61..5ea3e77b2d 100644
--- a/drivers/gpio/at91_gpio.c
+++ b/drivers/gpio/at91_gpio.c
@@ -210,7 +210,7 @@ int at91_pio3_set_d_periph(unsigned port, unsigned pin, int use_pullup)
return 0;
}
-#ifdef CONFIG_DM_GPIO
+#if CONFIG_IS_ENABLED(DM_GPIO)
static bool at91_get_port_output(struct at91_port *at91_port, int offset)
{
u32 mask, val;
@@ -457,7 +457,7 @@ int at91_get_pio_value(unsigned port, unsigned pin)
return 0;
}
-#ifndef CONFIG_DM_GPIO
+#if !CONFIG_IS_ENABLED(DM_GPIO)
/* Common GPIO API */
int gpio_request(unsigned gpio, const char *label)
@@ -499,7 +499,7 @@ int gpio_set_value(unsigned gpio, int value)
}
#endif
-#ifdef CONFIG_DM_GPIO
+#if CONFIG_IS_ENABLED(DM_GPIO)
struct at91_port_priv {
struct at91_port *regs;
diff --git a/drivers/gpio/atmel_pio4.c b/drivers/gpio/atmel_pio4.c
index 95a189a50f..8e6f32de1f 100644
--- a/drivers/gpio/atmel_pio4.c
+++ b/drivers/gpio/atmel_pio4.c
@@ -168,7 +168,7 @@ int atmel_pio4_get_pio_input(u32 port, u32 pin)
return (readl(&port_base->pdsr) & mask) ? 1 : 0;
}
-#ifdef CONFIG_DM_GPIO
+#if CONFIG_IS_ENABLED(DM_GPIO)
struct atmel_pioctrl_data {
u32 nbanks;
diff --git a/drivers/gpio/da8xx_gpio.c b/drivers/gpio/da8xx_gpio.c
index 0a50c68d72..bd5a366aef 100644
--- a/drivers/gpio/da8xx_gpio.c
+++ b/drivers/gpio/da8xx_gpio.c
@@ -15,7 +15,7 @@
#include "da8xx_gpio.h"
-#ifndef CONFIG_DM_GPIO
+#if !CONFIG_IS_ENABLED(DM_GPIO)
#include <asm/arch/hardware.h>
#include <asm/arch/davinci_misc.h>
@@ -377,7 +377,8 @@ static int _gpio_direction_output(struct davinci_gpio *bank, unsigned int gpio,
_gpio_set_value(bank, gpio, value);
return 0;
}
-#ifndef CONFIG_DM_GPIO
+
+#if !CONFIG_IS_ENABLED(DM_GPIO)
void gpio_info(void)
{
@@ -428,7 +429,7 @@ int gpio_set_value(unsigned int gpio, int value)
return _gpio_set_value(bank, gpio, value);
}
-#else /* CONFIG_DM_GPIO */
+#else /* DM_GPIO */
static struct davinci_gpio *davinci_get_gpio_bank(struct udevice *dev, unsigned int offset)
{
diff --git a/drivers/gpio/da8xx_gpio.h b/drivers/gpio/da8xx_gpio.h
index 1de9ec7f6f..849e8d2dcf 100644
--- a/drivers/gpio/da8xx_gpio.h
+++ b/drivers/gpio/da8xx_gpio.h
@@ -28,7 +28,7 @@ struct davinci_gpio_bank {
#define MAX_NUM_GPIOS 144
#define GPIO_BIT(gp) ((gp) & 0x1F)
-#ifdef CONFIG_DM_GPIO
+#if CONFIG_IS_ENABLED(DM_GPIO)
/* Information about a GPIO bank */
struct davinci_gpio_platdata {
diff --git a/drivers/gpio/intel_gpio.c b/drivers/gpio/intel_gpio.c
new file mode 100644
index 0000000000..4bf1c9ddc4
--- /dev/null
+++ b/drivers/gpio/intel_gpio.c
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 Google LLC
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <p2sb.h>
+#include <pch.h>
+#include <pci.h>
+#include <syscon.h>
+#include <asm/cpu.h>
+#include <asm/gpio.h>
+#include <asm/intel_pinctrl.h>
+#include <asm/intel_pinctrl_defs.h>
+#include <asm/io.h>
+#include <asm/pci.h>
+#include <asm/arch/gpio.h>
+#include <dt-bindings/gpio/x86-gpio.h>
+
+static int intel_gpio_direction_input(struct udevice *dev, uint offset)
+{
+ struct udevice *pinctrl = dev_get_parent(dev);
+ uint config_offset = intel_pinctrl_get_config_reg_addr(pinctrl, offset);
+
+ pcr_clrsetbits32(pinctrl, config_offset,
+ PAD_CFG0_MODE_MASK | PAD_CFG0_TX_STATE |
+ PAD_CFG0_RX_DISABLE,
+ PAD_CFG0_MODE_GPIO | PAD_CFG0_TX_DISABLE);
+
+ return 0;
+}
+
+static int intel_gpio_direction_output(struct udevice *dev, uint offset,
+ int value)
+{
+ struct udevice *pinctrl = dev_get_parent(dev);
+ uint config_offset = intel_pinctrl_get_config_reg_addr(pinctrl, offset);
+
+ pcr_clrsetbits32(dev, config_offset,
+ PAD_CFG0_MODE_MASK | PAD_CFG0_RX_STATE |
+ PAD_CFG0_TX_DISABLE,
+ PAD_CFG0_MODE_GPIO | PAD_CFG0_RX_DISABLE |
+ (value ? PAD_CFG0_TX_STATE : 0));
+
+ return 0;
+}
+
+static int intel_gpio_get_value(struct udevice *dev, uint offset)
+{
+ struct udevice *pinctrl = dev_get_parent(dev);
+ uint mode, rx_tx;
+ u32 reg;
+
+ reg = intel_pinctrl_get_config_reg(pinctrl, offset);
+ mode = (reg & PAD_CFG0_MODE_MASK) >> PAD_CFG0_MODE_SHIFT;
+ if (!mode) {
+ rx_tx = reg & (PAD_CFG0_TX_DISABLE | PAD_CFG0_RX_DISABLE);
+ if (rx_tx == PAD_CFG0_TX_DISABLE)
+ return mode & PAD_CFG0_RX_STATE_BIT ? 1 : 0;
+ else if (rx_tx == PAD_CFG0_RX_DISABLE)
+ return mode & PAD_CFG0_TX_STATE_BIT ? 1 : 0;
+ }
+
+ return 0;
+}
+
+static int intel_gpio_set_value(struct udevice *dev, unsigned offset, int value)
+{
+ struct udevice *pinctrl = dev_get_parent(dev);
+ uint config_offset = intel_pinctrl_get_config_reg_addr(pinctrl, offset);
+
+ pcr_clrsetbits32(dev, config_offset, PAD_CFG0_TX_STATE,
+ value ? PAD_CFG0_TX_STATE : 0);
+
+ return 0;
+}
+
+static int intel_gpio_get_function(struct udevice *dev, uint offset)
+{
+ struct udevice *pinctrl = dev_get_parent(dev);
+ uint mode, rx_tx;
+ u32 reg;
+
+ reg = intel_pinctrl_get_config_reg(pinctrl, offset);
+ mode = (reg & PAD_CFG0_MODE_MASK) >> PAD_CFG0_MODE_SHIFT;
+ if (!mode) {
+ rx_tx = reg & (PAD_CFG0_TX_DISABLE | PAD_CFG0_RX_DISABLE);
+ if (rx_tx == PAD_CFG0_TX_DISABLE)
+ return GPIOF_INPUT;
+ else if (rx_tx == PAD_CFG0_RX_DISABLE)
+ return GPIOF_OUTPUT;
+ }
+
+ return GPIOF_FUNC;
+}
+
+static int intel_gpio_xlate(struct udevice *orig_dev, struct gpio_desc *desc,
+ struct ofnode_phandle_args *args)
+{
+ struct udevice *pinctrl, *dev;
+ int gpio, ret;
+
+ /*
+ * GPIO numbers are global in the device tree so it doesn't matter
+ * which one is used
+ */
+ gpio = args->args[0];
+ ret = intel_pinctrl_get_pad(gpio, &pinctrl, &desc->offset);
+ if (ret)
+ return log_msg_ret("bad", ret);
+ device_find_first_child(pinctrl, &dev);
+ if (!dev)
+ return log_msg_ret("no child", -ENOENT);
+ desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
+ desc->dev = dev;
+
+ return 0;
+}
+
+static int intel_gpio_probe(struct udevice *dev)
+{
+ return 0;
+}
+
+static int intel_gpio_ofdata_to_platdata(struct udevice *dev)
+{
+ struct gpio_dev_priv *upriv = dev_get_uclass_priv(dev);
+ struct intel_pinctrl_priv *pinctrl_priv = dev_get_priv(dev->parent);
+ const struct pad_community *comm = pinctrl_priv->comm;
+
+ upriv->gpio_count = comm->last_pad - comm->first_pad + 1;
+ upriv->bank_name = dev->name;
+
+ return 0;
+}
+
+static const struct dm_gpio_ops gpio_intel_ops = {
+ .direction_input = intel_gpio_direction_input,
+ .direction_output = intel_gpio_direction_output,
+ .get_value = intel_gpio_get_value,
+ .set_value = intel_gpio_set_value,
+ .get_function = intel_gpio_get_function,
+ .xlate = intel_gpio_xlate,
+};
+
+static const struct udevice_id intel_intel_gpio_ids[] = {
+ { .compatible = "intel,gpio" },
+ { }
+};
+
+U_BOOT_DRIVER(gpio_intel) = {
+ .name = "gpio_intel",
+ .id = UCLASS_GPIO,
+ .of_match = intel_intel_gpio_ids,
+ .ops = &gpio_intel_ops,
+ .ofdata_to_platdata = intel_gpio_ofdata_to_platdata,
+ .probe = intel_gpio_probe,
+};
diff --git a/drivers/gpio/mxc_gpio.c b/drivers/gpio/mxc_gpio.c
index 64ab7a303f..6592d141d3 100644
--- a/drivers/gpio/mxc_gpio.c
+++ b/drivers/gpio/mxc_gpio.c
@@ -30,7 +30,7 @@ struct mxc_bank_info {
struct gpio_regs *regs;
};
-#ifndef CONFIG_DM_GPIO
+#if !CONFIG_IS_ENABLED(DM_GPIO)
#define GPIO_TO_PORT(n) ((n) / 32)
/* GPIO port description */
@@ -161,7 +161,7 @@ int gpio_direction_output(unsigned gpio, int value)
}
#endif
-#ifdef CONFIG_DM_GPIO
+#if CONFIG_IS_ENABLED(DM_GPIO)
#include <fdtdec.h>
static int mxc_gpio_is_output(struct gpio_regs *regs, int offset)
{
diff --git a/drivers/gpio/mxs_gpio.c b/drivers/gpio/mxs_gpio.c
index 5795155e3e..77778e9ce5 100644
--- a/drivers/gpio/mxs_gpio.c
+++ b/drivers/gpio/mxs_gpio.c
@@ -128,7 +128,7 @@ int name_to_gpio(const char *name)
return (bank << MXS_PAD_BANK_SHIFT) | (pin << MXS_PAD_PIN_SHIFT);
}
-#else /* CONFIG_DM_GPIO */
+#else /* DM_GPIO */
#include <dm.h>
#include <asm/gpio.h>
#include <dt-structs.h>
@@ -312,4 +312,4 @@ U_BOOT_DRIVER(gpio_mxs) = {
.ofdata_to_platdata = mxs_ofdata_to_platdata,
#endif
};
-#endif /* CONFIG_DM_GPIO */
+#endif /* DM_GPIO */
diff --git a/drivers/gpio/omap_gpio.c b/drivers/gpio/omap_gpio.c
index 0031415d03..4249850f4b 100644
--- a/drivers/gpio/omap_gpio.c
+++ b/drivers/gpio/omap_gpio.c
@@ -30,7 +30,7 @@ DECLARE_GLOBAL_DATA_PTR;
#define OMAP_GPIO_DIR_OUT 0
#define OMAP_GPIO_DIR_IN 1
-#ifdef CONFIG_DM_GPIO
+#if CONFIG_IS_ENABLED(DM_GPIO)
#define GPIO_PER_BANK 32
@@ -121,7 +121,7 @@ static int _get_gpio_value(const struct gpio_bank *bank, int gpio)
return (__raw_readl(reg) & (1 << gpio)) != 0;
}
-#ifndef CONFIG_DM_GPIO
+#if !CONFIG_IS_ENABLED(DM_GPIO)
static inline const struct gpio_bank *get_gpio_bank(int gpio)
{
@@ -377,4 +377,4 @@ U_BOOT_DRIVER(gpio_omap) = {
#endif
};
-#endif /* CONFIG_DM_GPIO */
+#endif /* !DM_GPIO */
diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
index 719efc2cef..9c3a4428e1 100644
--- a/drivers/gpio/sunxi_gpio.c
+++ b/drivers/gpio/sunxi_gpio.c
@@ -28,7 +28,7 @@ struct sunxi_gpio_platdata {
int gpio_count;
};
-#ifndef CONFIG_DM_GPIO
+#if !CONFIG_IS_ENABLED(DM_GPIO)
static int sunxi_gpio_output(u32 pin, u32 val)
{
u32 dat;
@@ -116,7 +116,7 @@ int sunxi_name_to_gpio(const char *name)
return -1;
return group * 32 + pin;
}
-#endif
+#endif /* DM_GPIO */
int sunxi_name_to_gpio_bank(const char *name)
{
@@ -132,7 +132,7 @@ int sunxi_name_to_gpio_bank(const char *name)
return -1;
}
-#ifdef CONFIG_DM_GPIO
+#if CONFIG_IS_ENABLED(DM_GPIO)
/* TODO(sjg@chromium.org): Remove this function and use device tree */
int sunxi_name_to_gpio(const char *name)
{
@@ -373,4 +373,4 @@ U_BOOT_DRIVER(gpio_sunxi) = {
.bind = gpio_sunxi_bind,
.probe = gpio_sunxi_probe,
};
-#endif
+#endif /* DM_GPIO */