X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fgpio%2Fzynq_gpio.c;h=442ba196cae000c7f8e82fe9933aa15a918f225c;hb=1471fadf69493141e990b078d8b8a3b215008f31;hp=3a995f610cb3e8acae8f7a6f8220c2365272e5d3;hpb=404a00c7c9fff1ef2ba5e33c585ff3c950757f34;p=u-boot diff --git a/drivers/gpio/zynq_gpio.c b/drivers/gpio/zynq_gpio.c index 3a995f610c..442ba196ca 100644 --- a/drivers/gpio/zynq_gpio.c +++ b/drivers/gpio/zynq_gpio.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Xilinx Zynq GPIO device driver * @@ -5,14 +6,12 @@ * * Most of code taken from linux kernel driver (linux/drivers/gpio/gpio-zynq.c) * Copyright (C) 2009 - 2014 Xilinx, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ */ #include #include #include -#include +#include #include #include @@ -189,7 +188,7 @@ static int gpio_is_valid(unsigned gpio, struct udevice *dev) { struct zynq_gpio_privdata *priv = dev_get_priv(dev); - return (gpio >= 0) && (gpio < priv->p_data->ngpio); + return gpio < priv->p_data->ngpio; } static int check_gpio(unsigned gpio, struct udevice *dev) @@ -299,11 +298,32 @@ static int zynq_gpio_direction_output(struct udevice *dev, unsigned gpio, return 0; } +static int zynq_gpio_get_function(struct udevice *dev, unsigned offset) +{ + u32 reg; + unsigned int bank_num, bank_pin_num; + struct zynq_gpio_privdata *priv = dev_get_priv(dev); + + if (check_gpio(offset, dev) < 0) + return -1; + + zynq_gpio_get_bank_pin(offset, &bank_num, &bank_pin_num, dev); + + /* set the GPIO pin as output */ + reg = readl(priv->base + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); + reg &= BIT(bank_pin_num); + if (reg) + return GPIOF_OUTPUT; + else + return GPIOF_INPUT; +} + static const struct dm_gpio_ops gpio_zynq_ops = { .direction_input = zynq_gpio_direction_input, .direction_output = zynq_gpio_direction_output, .get_value = zynq_gpio_get_value, .set_value = zynq_gpio_set_value, + .get_function = zynq_gpio_get_function, }; static const struct udevice_id zynq_gpio_ids[] = { @@ -354,7 +374,7 @@ static int zynq_gpio_ofdata_to_platdata(struct udevice *dev) { struct zynq_gpio_privdata *priv = dev_get_priv(dev); - priv->base = dev_get_addr(dev); + priv->base = devfdt_get_addr(dev); return 0; }