diff options
author | Tom Rini <trini@konsulko.com> | 2020-01-06 17:07:49 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2020-01-06 17:07:49 -0500 |
commit | 5a8fa095cb848c60c630a83edf30d4fc46101e90 (patch) | |
tree | 66652768520899ddea6a24a608c1be4ed6ecfcde /drivers/gpio/intel_gpio.c | |
parent | 0b0c6af38738f2c132cfd41a240889acaa031c8f (diff) | |
parent | 8fbbec12f7d2c18f8883f3371cfca74a98b5dd87 (diff) |
Merge branch 'next'
Bring in the following merges:
commit 8fbbec12f7d2c18f8883f3371cfca74a98b5dd87
Merge: 87f69f467a83 63618e71e89b
Author: Tom Rini <trini@konsulko.com>
Date: Fri Jan 3 09:48:47 2020 -0500
Merge https://gitlab.denx.de/u-boot/custodians/u-boot-fsl-qoriq into next
- updates and fixes on ls1028a, lx2, ls1046a, MC-DPSPARSER support
commit 87f69f467a8335b171c71bf217d2625d515acd7c
Merge: c0912f9bbfb2 4466b9970319
Author: Tom Rini <trini@konsulko.com>
Date: Tue Dec 24 08:18:19 2019 -0500
Merge https://gitlab.denx.de/u-boot/custodians/u-boot-mpc85xx into next
- Enable DM driver on ppc/km boards
- Enable DM_USB for some of NXP powerpc platforms: P5040, T4240, T208x,
T104x, P4080, P2041, P2020, P1020, P3041
- Some updates in mpc85xx-ddr driver, km boards
commit c0912f9bbfb26dd03d189953678691b799d35b6e
Merge: 533c9f5714bd a1d6dc3f8407
Author: Tom Rini <trini@konsulko.com>
Date: Wed Dec 18 07:20:19 2019 -0500
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
commit 533c9f5714bdba79dc6f2629284d4c1a08a611d1
Merge: 553cb0688782 033e18b47bd0
Author: Tom Rini <trini@konsulko.com>
Date: Tue Dec 17 07:53:08 2019 -0500
Merge tag '20191217-for-next' of https://gitlab.denx.de/u-boot/custodians/u-boot-i2c into next
i2c: for next
- misc: i2c_eeprom:
Add partition support and add ability to query size
of eeprom device and partitions
- i2c common:
add support for offset overflow in to address and add
sandbox tests for it.
commit 553cb06887825314e74a9bdac337467c77d1db88
Merge: f39abbbc531e b4f98b3b16ec
Author: Tom Rini <trini@konsulko.com>
Date: Thu Dec 12 08:18:59 2019 -0500
Merge tag 'dm-next-13dec19' of https://gitlab.denx.de/u-boot/custodians/u-boot-dm into next
buildman improvements including toolchain environment feature
sandbox unicode support in serial
Diffstat (limited to 'drivers/gpio/intel_gpio.c')
-rw-r--r-- | drivers/gpio/intel_gpio.c | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/drivers/gpio/intel_gpio.c b/drivers/gpio/intel_gpio.c new file mode 100644 index 00000000000..4bf1c9ddc4e --- /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, +}; |