From patchwork Wed Jun 19 15:31:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukasz Majewski X-Patchwork-Id: 1118780 X-Patchwork-Delegate: sbabic@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=denx.de Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 45TTTR31F3z9s6w for ; Thu, 20 Jun 2019 01:32:11 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 9AD08C21DD7; Wed, 19 Jun 2019 15:31:48 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=KHOP_BIG_TO_CC autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 2D78AC21D8E; Wed, 19 Jun 2019 15:31:46 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id E2FE1C21DB3; Wed, 19 Jun 2019 15:31:44 +0000 (UTC) Received: from mail-out.m-online.net (mail-out.m-online.net [212.18.0.10]) by lists.denx.de (Postfix) with ESMTPS id 039CFC21E07 for ; Wed, 19 Jun 2019 15:31:41 +0000 (UTC) Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 45TTSr5JBcz1rbM7; Wed, 19 Jun 2019 17:31:40 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 45TTSr465sz1qqkH; Wed, 19 Jun 2019 17:31:40 +0200 (CEST) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id r9-IRmhvzG1d; Wed, 19 Jun 2019 17:31:38 +0200 (CEST) X-Auth-Info: R9jLo9QvYZ1H7C9r4/q4b2y1/UurS6YZvVDCPhGmGys= Received: from localhost.localdomain (85-222-111-42.dynamic.chello.pl [85.222.111.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPSA; Wed, 19 Jun 2019 17:31:38 +0200 (CEST) From: Lukasz Majewski To: Stefano Babic , Fabio Estevam , Simon Glass , Tom Rini , u-boot@lists.denx.de, Jagan Teki , Marcel Ziswiler , Adam Ford , Peng Fan , Marek Vasut , Shyam Saini , Michael Nazzareno Trimarchi , Angelo Compagnucci Date: Wed, 19 Jun 2019 17:31:05 +0200 Message-Id: <20190619153107.18881-5-lukma@denx.de> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190619153107.18881-1-lukma@denx.de> References: <20190619153107.18881-1-lukma@denx.de> Subject: [U-Boot] [PATCH v6 4/6] gpio: mxs: Add support for DM/DTS in the mxs_gpio.c driver (DM_GPIO) X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" This patch adds support for DM/DTS in the mxs_gpio.c driver. Information regarding per gpio controller pin number is passed via DTS. Signed-off-by: Lukasz Majewski Reviewed-by: Marek Vasut --- Changes in v6: None Changes in v5: - Update tags ("gpio: mxs") Changes in v4: - Use BIT() macro instead of 1 << offset - Use devfdt_get_addr to get gpio number - Use gpio-ranges property to setup gpios Changes in v3: - Set more appropriate tags Changes in v2: - Use #if !CONFIG_IS_ENABLED(DM_GPIO) instead of plain #ifdef CONFIG_DM_GPIO drivers/gpio/mxs_gpio.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) diff --git a/drivers/gpio/mxs_gpio.c b/drivers/gpio/mxs_gpio.c index c2c8a25886..b2451fdda8 100644 --- a/drivers/gpio/mxs_gpio.c +++ b/drivers/gpio/mxs_gpio.c @@ -51,6 +51,7 @@ void mxs_gpio_init(void) } } +#if !CONFIG_IS_ENABLED(DM_GPIO) int gpio_get_value(unsigned gpio) { uint32_t bank = PAD_BANK(gpio); @@ -127,3 +128,150 @@ int name_to_gpio(const char *name) return (bank << MXS_PAD_BANK_SHIFT) | (pin << MXS_PAD_PIN_SHIFT); } +#else /* CONFIG_DM_GPIO */ +#include +#include +#include +#define MXS_MAX_GPIO_PER_BANK 32 + +DECLARE_GLOBAL_DATA_PTR; +/* + * According to i.MX28 Reference Manual: + * 'i.MX28 Applications Processor Reference Manual, Rev. 1, 2010' + * The i.MX28 has following number of GPIOs available: + * Bank 0: 0-28 -> 29 PINS + * Bank 1: 0-31 -> 32 PINS + * Bank 2: 0-27 -> 28 PINS + * Bank 3: 0-30 -> 31 PINS + * Bank 4: 0-20 -> 21 PINS + */ + +struct mxs_gpio_priv { + unsigned int bank; +}; + +static int mxs_gpio_get_value(struct udevice *dev, unsigned offset) +{ + struct mxs_gpio_priv *priv = dev_get_priv(dev); + struct mxs_register_32 *reg = + (struct mxs_register_32 *)(MXS_PINCTRL_BASE + + PINCTRL_DIN(priv->bank)); + + return (readl(®->reg) >> offset) & 1; +} + +static int mxs_gpio_set_value(struct udevice *dev, unsigned offset, + int value) +{ + struct mxs_gpio_priv *priv = dev_get_priv(dev); + struct mxs_register_32 *reg = + (struct mxs_register_32 *)(MXS_PINCTRL_BASE + + PINCTRL_DOUT(priv->bank)); + if (value) + writel(BIT(offset), ®->reg_set); + else + writel(BIT(offset), ®->reg_clr); + + return 0; +} + +static int mxs_gpio_direction_input(struct udevice *dev, unsigned offset) +{ + struct mxs_gpio_priv *priv = dev_get_priv(dev); + struct mxs_register_32 *reg = + (struct mxs_register_32 *)(MXS_PINCTRL_BASE + + PINCTRL_DOE(priv->bank)); + + writel(BIT(offset), ®->reg_clr); + + return 0; +} + +static int mxs_gpio_direction_output(struct udevice *dev, unsigned offset, + int value) +{ + struct mxs_gpio_priv *priv = dev_get_priv(dev); + struct mxs_register_32 *reg = + (struct mxs_register_32 *)(MXS_PINCTRL_BASE + + PINCTRL_DOE(priv->bank)); + + mxs_gpio_set_value(dev, offset, value); + + writel(BIT(offset), ®->reg_set); + + return 0; +} + +static int mxs_gpio_get_function(struct udevice *dev, unsigned offset) +{ + struct mxs_gpio_priv *priv = dev_get_priv(dev); + struct mxs_register_32 *reg = + (struct mxs_register_32 *)(MXS_PINCTRL_BASE + + PINCTRL_DOE(priv->bank)); + bool is_output = !!(readl(®->reg) >> offset); + + return is_output ? GPIOF_OUTPUT : GPIOF_INPUT; +} + +static const struct dm_gpio_ops gpio_mxs_ops = { + .direction_input = mxs_gpio_direction_input, + .direction_output = mxs_gpio_direction_output, + .get_value = mxs_gpio_get_value, + .set_value = mxs_gpio_set_value, + .get_function = mxs_gpio_get_function, +}; + +static int mxs_gpio_probe(struct udevice *dev) +{ + struct mxs_gpio_priv *priv = dev_get_priv(dev); + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + struct fdtdec_phandle_args args; + int node = dev_of_offset(dev); + char name[16], *str; + fdt_addr_t addr; + int ret; + + addr = devfdt_get_addr(dev); + if (addr == FDT_ADDR_T_NONE) { + printf("%s: No 'reg' property defined!\n", __func__); + return -EINVAL; + } + + priv->bank = (unsigned int)addr; + + snprintf(name, sizeof(name), "GPIO%d_", priv->bank); + str = strdup(name); + if (!str) + return -ENOMEM; + + uc_priv->bank_name = str; + + ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, node, "gpio-ranges", + NULL, 3, 0, &args); + if (ret) + printf("%s: 'gpio-ranges' not defined - using default!\n", + __func__); + + uc_priv->gpio_count = ret == 0 ? args.args[2] : MXS_MAX_GPIO_PER_BANK; + + debug("%s: %s: %d pins\n", __func__, uc_priv->bank_name, + uc_priv->gpio_count); + + return 0; +} + +static const struct udevice_id mxs_gpio_ids[] = { + { .compatible = "fsl,imx23-gpio" }, + { .compatible = "fsl,imx28-gpio" }, + { } +}; + +U_BOOT_DRIVER(gpio_mxs) = { + .name = "gpio_mxs", + .id = UCLASS_GPIO, + .ops = &gpio_mxs_ops, + .probe = mxs_gpio_probe, + .priv_auto_alloc_size = sizeof(struct mxs_gpio_priv), + .of_match = mxs_gpio_ids, +}; +#endif /* CONFIG_DM_GPIO */