Patchwork [U-Boot,v2,1/2] gpio: Add GPIO driver framework for Marvell SoCs

login
register
mail settings
Submitter Ajay Bhargav
Date July 22, 2011, 7:16 a.m.
Message ID <1311318994-20660-1-git-send-email-ajay.bhargav@einfochips.com>
Download mbox | patch
Permalink /patch/106232/
State Superseded
Headers show

Comments

Ajay Bhargav - July 22, 2011, 7:16 a.m.
This patch adds generic GPIO driver framework support for Marvell SoCs.

To enable GPIO driver define CONFIG_MARVELL_GPIO and for GPIO commands
define CONFIG_CMD_GPIO in your board configuration file.

Signed-off-by: Ajay Bhargav <ajay.bhargav@einfochips.com>
---
 drivers/gpio/Makefile |    1 +
 drivers/gpio/mvgpio.c |  114 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 115 insertions(+), 0 deletions(-)
 create mode 100644 drivers/gpio/mvgpio.c
Simon Guinot - Aug. 2, 2011, 2:10 p.m.
Hi Ajay,

On Fri, Jul 22, 2011 at 12:46:33PM +0530, Ajay Bhargav wrote:
> This patch adds generic GPIO driver framework support for Marvell SoCs.
> 
> To enable GPIO driver define CONFIG_MARVELL_GPIO and for GPIO commands
> define CONFIG_CMD_GPIO in your board configuration file.
> 
> Signed-off-by: Ajay Bhargav <ajay.bhargav@einfochips.com>
> ---
>  drivers/gpio/Makefile |    1 +
>  drivers/gpio/mvgpio.c |  114 +++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 115 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/gpio/mvgpio.c

... snip ...

> +int gpio_direction_input(int gp)
> +{
> +	struct gpio_reg *gpio_reg_bank;
> +
> +	if (gp >= MV_MAX_GPIO) {
> +		printf("%s: Invalid GPIO %d\n", __func__, gp);
> +		return -EINVAL;
> +	}
> +
> +	gpio_reg_bank = get_gpio_base(GPIO_TO_REG(gp));
> +	writel(GPIO_TO_BIT(gp), &gpio_reg_bank->gcdr);

AFAIK, Orion and Kirkwood SoCs don't provide bitwise set/clear for
GPIO output/direction registers. Instead, a register must be read
first to leave other bits unchanged (see __set_direction in kw_gpio.c).

Is it possible to handle Armada SoCs GPIOs in a same way ? maybe using
the pin registers (gpxx in the Armada struct gpio_reg array) ?

If not, this code is not Marvell generic but rather specific for Armada
SoCs and then maybe armada_gpio is a better name...

Regards,

Simon
Prafulla Wadaskar - Aug. 3, 2011, 10:18 a.m.
> -----Original Message-----
> From: Simon Guinot [mailto:simon@sequanux.org]
> Sent: Tuesday, August 02, 2011 7:41 PM
> To: Ajay Bhargav
> Cc: Prafulla Wadaskar; u-boot@lists.denx.de
> Subject: Re: [U-Boot] [PATCH v2 1/2] gpio: Add GPIO driver framework for
> Marvell SoCs
> 
> Hi Ajay,
> 
> On Fri, Jul 22, 2011 at 12:46:33PM +0530, Ajay Bhargav wrote:
> > This patch adds generic GPIO driver framework support for Marvell
> SoCs.
> >
> > To enable GPIO driver define CONFIG_MARVELL_GPIO and for GPIO commands
> > define CONFIG_CMD_GPIO in your board configuration file.
> >
> > Signed-off-by: Ajay Bhargav <ajay.bhargav@einfochips.com>
> > ---
> >  drivers/gpio/Makefile |    1 +
> >  drivers/gpio/mvgpio.c |  114
> +++++++++++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 115 insertions(+), 0 deletions(-)
> >  create mode 100644 drivers/gpio/mvgpio.c
> 
> ... snip ...
> 
> > +int gpio_direction_input(int gp)
> > +{
> > +	struct gpio_reg *gpio_reg_bank;
> > +
> > +	if (gp >= MV_MAX_GPIO) {
> > +		printf("%s: Invalid GPIO %d\n", __func__, gp);
> > +		return -EINVAL;
> > +	}
> > +
> > +	gpio_reg_bank = get_gpio_base(GPIO_TO_REG(gp));
> > +	writel(GPIO_TO_BIT(gp), &gpio_reg_bank->gcdr);
> 
> AFAIK, Orion and Kirkwood SoCs don't provide bitwise set/clear for
> GPIO output/direction registers. Instead, a register must be read
> first to leave other bits unchanged (see __set_direction in kw_gpio.c).
> 
> Is it possible to handle Armada SoCs GPIOs in a same way ? maybe using
> the pin registers (gpxx in the Armada struct gpio_reg array) ?
> 
> If not, this code is not Marvell generic but rather specific for Armada
> SoCs and then maybe armada_gpio is a better name...

Hi Simon, you are right.

I think lets keep it mvgpio.c at the moment because most of other Marvell SoC uses this method. Any way Orion and Kirkwood are mainlined, if needed to be supported for this driver we can think of adding some #ifdef or macros to mvgpio.c latter.

Regards..
Prafulla . .

Patch

diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 62ec97d..beca1da 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -27,6 +27,7 @@  LIB 	:= $(obj)libgpio.o
 
 COBJS-$(CONFIG_AT91_GPIO)	+= at91_gpio.o
 COBJS-$(CONFIG_KIRKWOOD_GPIO)	+= kw_gpio.o
+COBJS-$(CONFIG_MARVELL_GPIO)	+= mvgpio.o
 COBJS-$(CONFIG_MARVELL_MFP)	+= mvmfp.o
 COBJS-$(CONFIG_MXC_GPIO)	+= mxc_gpio.o
 COBJS-$(CONFIG_PCA953X)		+= pca953x.o
diff --git a/drivers/gpio/mvgpio.c b/drivers/gpio/mvgpio.c
new file mode 100644
index 0000000..0cc8ed7
--- /dev/null
+++ b/drivers/gpio/mvgpio.c
@@ -0,0 +1,114 @@ 
+/*
+ * (C) Copyright 2011
+ * eInfochips Ltd. <www.einfochips.com>
+ * Written-by: Ajay Bhargav <ajay.bhargav@einfochips.com>
+ *
+ * (C) Copyright 2010
+ * Marvell Semiconductor <www.marvell.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <asm/gpio.h>
+
+#ifndef MV_MAX_GPIO
+#define MV_MAX_GPIO	128
+#endif
+
+int gpio_request(int gp, const char *label)
+{
+	if (gp >= MV_MAX_GPIO) {
+		printf("%s: Invalid GPIO requested %d\n", __func__, gp);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+void gpio_free(int gp)
+{
+}
+
+void gpio_toggle_value(int gp)
+{
+	gpio_set_value(gp, !gpio_get_value(gp));
+}
+
+int gpio_direction_input(int gp)
+{
+	struct gpio_reg *gpio_reg_bank;
+
+	if (gp >= MV_MAX_GPIO) {
+		printf("%s: Invalid GPIO %d\n", __func__, gp);
+		return -EINVAL;
+	}
+
+	gpio_reg_bank = get_gpio_base(GPIO_TO_REG(gp));
+	writel(GPIO_TO_BIT(gp), &gpio_reg_bank->gcdr);
+	return 0;
+}
+
+int gpio_direction_output(int gp, int value)
+{
+	struct gpio_reg *gpio_reg_bank;
+
+	if (gp >= MV_MAX_GPIO) {
+		printf("%s: Invalid GPIO %d\n", __func__, gp);
+		return -EINVAL;
+	}
+
+	gpio_reg_bank = get_gpio_base(GPIO_TO_REG(gp));
+	writel(GPIO_TO_BIT(gp), &gpio_reg_bank->gsdr);
+	gpio_set_value(gp, value);
+	return 0;
+}
+
+int gpio_get_value(int gp)
+{
+	struct gpio_reg *gpio_reg_bank;
+	u32 gp_val;
+
+	if (gp >= MV_MAX_GPIO) {
+		printf("%s: Invalid GPIO %d\n", __func__, gp);
+		return -EINVAL;
+	}
+
+	gpio_reg_bank = get_gpio_base(GPIO_TO_REG(gp));
+	gp_val = readl(&gpio_reg_bank->gplr);
+
+	return GPIO_VAL(gp, gp_val);
+}
+
+void gpio_set_value(int gp, int value)
+{
+	struct gpio_reg *gpio_reg_bank;
+
+	if (gp >= MV_MAX_GPIO) {
+		printf("%s: Invalid GPIO %d\n", __func__, gp);
+		return;
+	}
+
+	gpio_reg_bank = get_gpio_base(GPIO_TO_REG(gp));
+	if (value)
+		writel(GPIO_TO_BIT(gp),	&gpio_reg_bank->gpsr);
+	else
+		writel(GPIO_TO_BIT(gp),	&gpio_reg_bank->gpcr);
+}