All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefano Babic <sbabic@denx.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH V2 08/20] gpio: Add Rapid GPIO2P driver for i.MX7ULP
Date: Sun, 12 Feb 2017 10:21:27 +0100	[thread overview]
Message-ID: <9d167aee-eef1-7d0c-dfe4-58f663debaca@denx.de> (raw)
In-Reply-To: <1482833066-29291-9-git-send-email-peng.fan@nxp.com>



On 27/12/2016 11:04, Peng Fan wrote:
> Add the imx_rgpio2p driver for Rapid GPIO2P controllers on i.MX7ULP.
> Have added all ports on RGPIO2P_0 and RGPIO2P_1.
> 
> The configurations CONFIG_IMX_RGPIO2P and CONFIG_DM_GPIO must be set
> to y to enable the drivers.
> 
> To use the GPIO function, the IBE and OBE needs to set in IOMUXC.
> We did not set the bits in driver, but leave them to IOMUXC settings
> of the GPIO pins. User should use IMX_GPIO_NR to generate the GPIO number
> for gpio APIs access.
> 
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> Signed-off-by: Ye Li <ye.li@nxp.com>
> Cc: Stefano Babic <sbabic@denx.de>
> ---
> 
> V2:
>  None
> 
>  arch/arm/include/asm/arch-mx7ulp/gpio.h |  22 ++++
>  drivers/gpio/Kconfig                    |   7 +
>  drivers/gpio/Makefile                   |   1 +
>  drivers/gpio/imx_rgpio2p.c              | 224 ++++++++++++++++++++++++++++++++
>  4 files changed, 254 insertions(+)
>  create mode 100644 arch/arm/include/asm/arch-mx7ulp/gpio.h
>  create mode 100644 drivers/gpio/imx_rgpio2p.c
> 
> diff --git a/arch/arm/include/asm/arch-mx7ulp/gpio.h b/arch/arm/include/asm/arch-mx7ulp/gpio.h
> new file mode 100644
> index 0000000..fe41101
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-mx7ulp/gpio.h
> @@ -0,0 +1,22 @@
> +/*
> + * Copyright (C) 2016 Freescale Semiconductor, Inc.
> + *
> + * SPDX-License-Identifier:	GPL-2.0+
> + */
> +
> +#ifndef __ASM_ARCH_MX7ULP_GPIO_H
> +#define __ASM_ARCH_MX7ULP_GPIO_H
> +
> +struct gpio_regs {
> +	u32 gpio_pdor;
> +	u32 gpio_psor;
> +	u32 gpio_pcor;
> +	u32 gpio_ptor;
> +	u32 gpio_pdir;
> +	u32 gpio_pddr;
> +	u32 gpio_gacr;
> +};
> +
> +#define IMX_GPIO_NR(port, index)		((((port)-1)*32)+((index)&31))
> +
> +#endif /* __ASM_ARCH_MX7ULP_GPIO_H */
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index 8d9ab52..dc4108f 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -48,6 +48,13 @@ 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 IMX_RGPIO2P
> +	bool "i.MX7ULP RGPIO2P driver"
> +	depends on DM
> +	default n
> +	help
> +	  This driver supports i.MX7ULP Rapid GPIO2P controller.
> +
>  config LPC32XX_GPIO
>  	bool "LPC32XX GPIO driver"
>  	depends on DM
> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
> index 8939226..27f8068 100644
> --- a/drivers/gpio/Makefile
> +++ b/drivers/gpio/Makefile
> @@ -53,6 +53,7 @@ obj-$(CONFIG_GPIO_UNIPHIER)	+= gpio-uniphier.o
>  obj-$(CONFIG_ZYNQ_GPIO)		+= zynq_gpio.o
>  obj-$(CONFIG_VYBRID_GPIO)	+= vybrid_gpio.o
>  obj-$(CONFIG_HIKEY_GPIO)	+= hi6220_gpio.o
> +obj-$(CONFIG_IMX_RGPIO2P)	+= imx_rgpio2p.o
>  obj-$(CONFIG_PIC32_GPIO)	+= pic32_gpio.o
>  obj-$(CONFIG_MVEBU_GPIO)	+= mvebu_gpio.o
>  obj-$(CONFIG_MSM_GPIO)		+= msm_gpio.o
> diff --git a/drivers/gpio/imx_rgpio2p.c b/drivers/gpio/imx_rgpio2p.c
> new file mode 100644
> index 0000000..886b161
> --- /dev/null
> +++ b/drivers/gpio/imx_rgpio2p.c
> @@ -0,0 +1,224 @@
> +/*
> + * Copyright 2016 Freescale Semiconductor, Inc.
> + *
> + * RGPIO2P driver for the Freescale i.MX7ULP.
> + *
> + * SPDX-License-Identifier:	GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <errno.h>
> +#include <fdtdec.h>
> +#include <asm/gpio.h>
> +#include <asm/io.h>
> +#include <malloc.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +enum imx_rgpio2p_direction {
> +	IMX_RGPIO2P_DIRECTION_IN,
> +	IMX_RGPIO2P_DIRECTION_OUT,
> +};
> +
> +#define GPIO_PER_BANK			32
> +
> +struct imx_rgpio2p_data {
> +	struct gpio_regs *regs;
> +};
> +
> +struct imx_rgpio2p_plat {
> +	int bank_index;
> +	struct gpio_regs *regs;
> +};
> +
> +static int imx_rgpio2p_is_output(struct gpio_regs *regs, int offset)
> +{
> +	u32 val;
> +
> +	val = readl(&regs->gpio_pddr);
> +
> +	return val & (1 << offset) ? 1 : 0;
> +}
> +
> +static void imx_rgpio2p_bank_direction(struct gpio_regs *regs, int offset,
> +				    enum imx_rgpio2p_direction direction)
> +{
> +	u32 l;
> +
> +	l = readl(&regs->gpio_pddr);
> +
> +	switch (direction) {
> +	case IMX_RGPIO2P_DIRECTION_OUT:
> +		l |= 1 << offset;
> +		break;
> +	case IMX_RGPIO2P_DIRECTION_IN:
> +		l &= ~(1 << offset);
> +	}
> +	writel(l, &regs->gpio_pddr);
> +}
> +
> +static void imx_rgpio2p_bank_set_value(struct gpio_regs *regs, int offset,
> +				    int value)
> +{
> +	if (value)
> +		writel((1 << offset), &regs->gpio_psor);
> +	else
> +		writel((1 << offset), &regs->gpio_pcor);
> +}
> +
> +static int imx_rgpio2p_bank_get_value(struct gpio_regs *regs, int offset)
> +{
> +	return (readl(&regs->gpio_pdir) >> offset) & 0x01;
> +}
> +
> +static int  imx_rgpio2p_direction_input(struct udevice *dev, unsigned offset)
> +{
> +	struct imx_rgpio2p_data *bank = dev_get_priv(dev);
> +
> +	/* Configure GPIO direction as input. */
> +	imx_rgpio2p_bank_direction(bank->regs, offset, IMX_RGPIO2P_DIRECTION_IN);
> +
> +	return 0;
> +}
> +
> +static int imx_rgpio2p_direction_output(struct udevice *dev, unsigned offset,
> +				       int value)
> +{
> +	struct imx_rgpio2p_data *bank = dev_get_priv(dev);
> +
> +	/* Configure GPIO output value. */
> +	imx_rgpio2p_bank_set_value(bank->regs, offset, value);
> +
> +	/* Configure GPIO direction as output. */
> +	imx_rgpio2p_bank_direction(bank->regs, offset, IMX_RGPIO2P_DIRECTION_OUT);
> +
> +	return 0;
> +}
> +
> +static int imx_rgpio2p_get_value(struct udevice *dev, unsigned offset)
> +{
> +	struct imx_rgpio2p_data *bank = dev_get_priv(dev);
> +
> +	return imx_rgpio2p_bank_get_value(bank->regs, offset);
> +}
> +
> +static int imx_rgpio2p_set_value(struct udevice *dev, unsigned offset,
> +				 int value)
> +{
> +	struct imx_rgpio2p_data *bank = dev_get_priv(dev);
> +
> +	imx_rgpio2p_bank_set_value(bank->regs, offset, value);
> +
> +	return 0;
> +}
> +
> +static int imx_rgpio2p_get_function(struct udevice *dev, unsigned offset)
> +{
> +	struct imx_rgpio2p_data *bank = dev_get_priv(dev);
> +
> +	/* GPIOF_FUNC is not implemented yet */
> +	if (imx_rgpio2p_is_output(bank->regs, offset))
> +		return GPIOF_OUTPUT;
> +	else
> +		return GPIOF_INPUT;
> +}
> +
> +static const struct dm_gpio_ops imx_rgpio2p_ops = {
> +	.direction_input	= imx_rgpio2p_direction_input,
> +	.direction_output	= imx_rgpio2p_direction_output,
> +	.get_value		= imx_rgpio2p_get_value,
> +	.set_value		= imx_rgpio2p_set_value,
> +	.get_function		= imx_rgpio2p_get_function,
> +};
> +
> +static int imx_rgpio2p_probe(struct udevice *dev)
> +{
> +	struct imx_rgpio2p_data *bank = dev_get_priv(dev);
> +	struct imx_rgpio2p_plat *plat = dev_get_platdata(dev);
> +	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
> +	int banknum;
> +	char name[18], *str;
> +
> +	banknum = plat->bank_index;
> +	sprintf(name, "GPIO%d_", banknum + 1);
> +	str = strdup(name);
> +	if (!str)
> +		return -ENOMEM;
> +	uc_priv->bank_name = str;
> +	uc_priv->gpio_count = GPIO_PER_BANK;
> +	bank->regs = plat->regs;
> +
> +	return 0;
> +}
> +
> +static int imx_rgpio2p_bind(struct udevice *dev)
> +{
> +	struct imx_rgpio2p_plat *plat = dev->platdata;
> +	fdt_addr_t addr;
> +
> +	/*
> +	 * If platdata already exsits, directly return.
> +	 * Actually only when DT is not supported, platdata
> +	 * is statically initialized in U_BOOT_DEVICES.Here
> +	 * will return.
> +	 */
> +	if (plat)
> +		return 0;
> +
> +	addr = dev_get_addr_index(dev, 1);
> +	if (addr == FDT_ADDR_T_NONE)
> +		return -ENODEV;
> +
> +	/*
> +	 * TODO:
> +	 * When every board is converted to driver model and DT is supported,
> +	 * this can be done by auto-alloc feature, but not using calloc
> +	 * to alloc memory for platdata.
> +	 */
> +	plat = calloc(1, sizeof(*plat));
> +	if (!plat)
> +		return -ENOMEM;
> +
> +	plat->regs = (struct gpio_regs *)addr;
> +	plat->bank_index = dev->req_seq;
> +	dev->platdata = plat;
> +
> +	return 0;
> +}
> +
> +
> +static const struct udevice_id imx_rgpio2p_ids[] = {
> +	{ .compatible = "fsl,imx7ulp-gpio" },
> +	{ }
> +};
> +
> +U_BOOT_DRIVER(imx_rgpio2p) = {
> +	.name	= "imx_rgpio2p",
> +	.id	= UCLASS_GPIO,
> +	.ops	= &imx_rgpio2p_ops,
> +	.probe	= imx_rgpio2p_probe,
> +	.priv_auto_alloc_size = sizeof(struct imx_rgpio2p_plat),
> +	.of_match = imx_rgpio2p_ids,
> +	.bind	= imx_rgpio2p_bind,
> +};
> +
> +#if !CONFIG_IS_ENABLED(OF_CONTROL)
> +static const struct imx_rgpio2p_plat imx_plat[] = {
> +	{ 0, (struct gpio_regs *)RGPIO2P_GPIO1_BASE_ADDR },
> +	{ 1, (struct gpio_regs *)RGPIO2P_GPIO2_BASE_ADDR },
> +	{ 2, (struct gpio_regs *)RGPIO2P_GPIO3_BASE_ADDR },
> +	{ 3, (struct gpio_regs *)RGPIO2P_GPIO4_BASE_ADDR },
> +	{ 4, (struct gpio_regs *)RGPIO2P_GPIO5_BASE_ADDR },
> +	{ 5, (struct gpio_regs *)RGPIO2P_GPIO6_BASE_ADDR },
> +};
> +
> +U_BOOT_DEVICES(imx_rgpio2ps) = {
> +	{ "imx_rgpio2p", &imx_plat[0] },
> +	{ "imx_rgpio2p", &imx_plat[1] },
> +	{ "imx_rgpio2p", &imx_plat[2] },
> +	{ "imx_rgpio2p", &imx_plat[3] },
> +	{ "imx_rgpio2p", &imx_plat[4] },
> +	{ "imx_rgpio2p", &imx_plat[5] },
> +};
> +#endif
> 

Reviewed-by : Stefano Babic <sbabic@denx.de>

Best regards,
Stefano Babic

-- 
=====================================================================
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================

  reply	other threads:[~2017-02-12  9:21 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-27 10:04 [U-Boot] [PATCH V2 00/20] imx: add i.MX7ULP support Peng Fan
2016-12-27 10:04 ` [U-Boot] [PATCH V2 01/20] imx: mx7ulp: Add mx7ulp to Kconfig Peng Fan
2017-02-12  8:39   ` Stefano Babic
2016-12-27 10:04 ` [U-Boot] [PATCH V2 02/20] imx: mx7ulp: add registers header file Peng Fan
2017-02-12  8:40   ` Stefano Babic
2016-12-27 10:04 ` [U-Boot] [PATCH V2 03/20] imx: mx7ulp: add iomux driver to support IOMUXC0 and IOMUXC1 Peng Fan
2017-02-12  8:45   ` Stefano Babic
2016-12-27 10:04 ` [U-Boot] [PATCH V2 04/20] imx: mx7ulp: Add clock framework and functions Peng Fan
2017-02-12  9:12   ` Stefano Babic
2016-12-27 10:04 ` [U-Boot] [PATCH V2 05/20] imx: mx7ulp: Add soc level initialization codes " Peng Fan
2017-02-12  9:19   ` Stefano Babic
2017-02-22  6:48     ` Peng Fan
2016-12-27 10:04 ` [U-Boot] [PATCH V2 06/20] imx: mx7ulp: handle all the lpuarts in get_lpuart_clk Peng Fan
2017-02-12  9:20   ` Stefano Babic
2016-12-27 10:04 ` [U-Boot] [PATCH V2 07/20] imx: mx7ulp: Implement the clock functions for i2c driver Peng Fan
2017-02-12  9:20   ` Stefano Babic
2016-12-27 10:04 ` [U-Boot] [PATCH V2 08/20] gpio: Add Rapid GPIO2P driver for i.MX7ULP Peng Fan
2017-02-12  9:21   ` Stefano Babic [this message]
2016-12-27 10:04 ` [U-Boot] [PATCH V2 09/20] mxc_ocotp: Update driver to support OCOTP controller on i.MX7ULP Peng Fan
2017-02-12  9:22   ` Stefano Babic
2016-12-27 10:04 ` [U-Boot] [PATCH V2 10/20] mx7ulp: Add iomux pins header file Peng Fan
2016-12-27 10:04 ` [U-Boot] [PATCH V2 11/20] wdog: Add the watchdog driver for MX7ULP Peng Fan
2017-02-12  9:25   ` Stefano Babic
2017-02-22  6:59     ` Peng Fan
2017-02-22  8:18       ` Stefano Babic
2016-12-27 10:04 ` [U-Boot] [PATCH V2 12/20] pinctrl: Add i.MX7ULP pinctrl driver Peng Fan
2017-01-12  5:07   ` Simon Glass
2017-02-12  9:25   ` Stefano Babic
2016-12-27 10:04 ` [U-Boot] [PATCH V2 13/20] i2c: lpi2c: add lpi2c driver for i.MX7ULP Peng Fan
2016-12-27 10:04 ` [U-Boot] [PATCH V2 14/20] serial: lpuart: restructure lpuart driver Peng Fan
2016-12-29  9:28   ` Bhuvanchandra DV
2017-02-12  9:27   ` Stefano Babic
2016-12-27 10:04 ` [U-Boot] [PATCH V2 15/20] serial: lpuart: add i.MX7ULP support Peng Fan
2016-12-27 10:04 ` [U-Boot] [PATCH V2 16/20] mx7ulp: Add HAB boot support Peng Fan
2017-02-12  9:28   ` Stefano Babic
2016-12-27 10:04 ` [U-Boot] [PATCH V2 17/20] arm: dts: add i.MX7ULP dtsi file Peng Fan
2016-12-27 10:04 ` [U-Boot] [PATCH V2 18/20] mmc: fsl_esdhc: support i.MX7ULP Peng Fan
2016-12-27 22:17   ` Jaehoon Chung
2017-02-12  9:29   ` Stefano Babic
2016-12-27 10:04 ` [U-Boot] [PATCH V2 19/20] imx: imx7ulp: add EVK board support Peng Fan
2016-12-27 10:04 ` [U-Boot] [PATCH V2 20/20] imx: mx7ulp_evk: enable mmc/regulator support Peng Fan
2016-12-27 11:22   ` Fabio Estevam
2016-12-27 12:07     ` Peng Fan
2017-01-03  9:05       ` Peng Fan
2017-01-12  2:23         ` Peng Fan
2017-01-12  2:24           ` Peng Fan
2017-02-08  8:36 ` [U-Boot] [PATCH V2 00/20] imx: add i.MX7ULP support Peng Fan
2017-02-08 12:16   ` Stefano Babic

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=9d167aee-eef1-7d0c-dfe4-58f663debaca@denx.de \
    --to=sbabic@denx.de \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.