Hello Atsushi, Thank you very much for your comments. Here is an updated version which includes implementation for input/output directions and should take your comments into account. Le dimanche 20 mai 2007, Atsushi Nemoto a écrit : > On Sat, 19 May 2007 21:51:39 +0200, Florian Fainelli <florian.fainelli@xxxxxxxxxxxxx> wrote: > > diff -urN linux-2.6.21.1/include/asm-mips/mach-au1x00/au1xxx_gpio.h > > linux-2.6.21.1.new/include/asm-mips/mach-au1x00/au1xxx_gpio.h --- > > linux-2.6.21.1/include/asm-mips/mach-au1x00/au1xxx_gpio.h 2007-04-27 > > 23:49:26.000000000 +0200 +++ > > linux-2.6.21.1.new/include/asm-mips/mach-au1x00/au1xxx_gpio.h 2007-05-19 > > 21:34:27.000000000 +0200 @@ -1,10 +1,7 @@ > > ... > > > +/* Wrappers for the arch-neutral GPIO API */ > > + > > +static inline int gpio_request(unsigned gpio, const char *label) > > +{ > > + /* Not yet implemented */ > > + return 0; > > +} > > + > > +static inline void gpio_free(unsigned gpio) > > +{ > > + /* Not yet implemented */ > > +} > > + > > +extern int gpio_direction_input(unsigned gpio); > > +extern int gpio_direction_output(unsigned gpio, int value); > > + > > +static inline int gpio_get_value(unsigned gpio) > > +{ > > + return au1xxx_gpio_get_value(gpio); > > +} > > + > > +static inline void gpio_set_value(unsigned gpio, int value) > > +{ > > + au1xxx_gpio_set_value(gpio, value); > > +} > > + > > +static inline int gpio_to_irq(unsigned gpio) > > +{ > > + return gpio; > > +} > > + > > +static inline int irq_to_gpio(unsigned irq) > > +{ > > + return irq; > > +} > > + > > +/* For cansleep */ > > +#include <asm-generic/gpio.h> > > + > > +#endif /* _AU1XXX_GPIO_H_ */ > > These APIs should be usable by "#include <asm/gpio.h>". So move > mach-au1x00/au1xxx_gpio.h to mach-au1x00/gpio.h and include it by > include/asm-mips/gpio.h (as Youichi said). > > And it seems gpio_direction_input()/gpio_direction_output() are not > implemented. A user of the GPIO API _should_ use these interfaces. > > --- > Atsushi Nemoto -- Cordialement, Florian Fainelli ---------------------------------------------
diff -urN linux-2.6.21.1/include/asm-mips/mach-au1x00/au1xxx_gpio.h linux-2.6.21.1.new/include/asm-mips/mach-au1x00/au1xxx_gpio.h --- linux-2.6.21.1/include/asm-mips/mach-au1x00/au1xxx_gpio.h 2007-04-27 23:49:26.000000000 +0200 +++ linux-2.6.21.1.new/include/asm-mips/mach-au1x00/au1xxx_gpio.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,20 +0,0 @@ -#ifndef __AU1XXX_GPIO_H -#define __AU1XXX_GPIO_H - -void au1xxx_gpio1_set_inputs(void); -void au1xxx_gpio_tristate(int signal); -void au1xxx_gpio_write(int signal, int value); -int au1xxx_gpio_read(int signal); - -typedef volatile struct -{ - u32 dir; - u32 reserved; - u32 output; - u32 pinstate; - u32 inten; - u32 enable; - -} AU1X00_GPIO2; - -#endif //__AU1XXX_GPIO_H diff -urN linux-2.6.21.1/include/asm-mips/mach-au1x00/gpio.h linux-2.6.21.1.new/include/asm-mips/mach-au1x00/gpio.h --- linux-2.6.21.1/include/asm-mips/mach-au1x00/gpio.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.21.1.new/include/asm-mips/mach-au1x00/gpio.h 2007-05-21 01:10:22.000000000 +0200 @@ -0,0 +1,69 @@ +#ifndef _AU1XXX_GPIO_H_ +#define _AU1XXX_GPIO_H_ + +#define AU1XXX_GPIO_BASE 200 + +typedef volatile struct +{ + u32 dir; + u32 reserved; + u32 output; + u32 pinstate; + u32 inten; + u32 enable; + +} AU1X00_GPIO2; + +extern int au1xxx_gpio_get_value(unsigned gpio); +extern void au1xxx_gpio_set_value(unsigned gpio, int value); +extern int au1xxx_gpio_direction_input(unsigned gpio); +extern int au1xxx_gpio_direction_output(unsigned gpio, int value); + + +/* Wrappers for the arch-neutral GPIO API */ + +static inline int gpio_request(unsigned gpio, const char *label) +{ + /* Not yet implemented */ + return 0; +} + +static inline void gpio_free(unsigned gpio) +{ + /* Not yet implemented */ +} + +static inline int gpio_direction_input(unsigned gpio) +{ + return au1xxx_gpio_direction_input(gpio); +} + +static inline int gpio_direction_output(unsigned gpio, int value) +{ + return au1xxx_gpio_direction_output(gpio, value); +} + +static inline int gpio_get_value(unsigned gpio) +{ + return au1xxx_gpio_get_value(gpio); +} + +static inline void gpio_set_value(unsigned gpio, int value) +{ + au1xxx_gpio_set_value(gpio, value); +} + +static inline int gpio_to_irq(unsigned gpio) +{ + return gpio; +} + +static inline int irq_to_gpio(unsigned irq) +{ + return irq; +} + +/* For cansleep */ +#include <asm-generic/gpio.h> + +#endif /* _AU1XXX_GPIO_H_ */ diff -urN linux-2.6.21.1/arch/mips/au1000/common/gpio.c linux-2.6.21.1.new/arch/mips/au1000/common/gpio.c --- linux-2.6.21.1/arch/mips/au1000/common/gpio.c 2007-04-27 23:49:26.000000000 +0200 +++ linux-2.6.21.1.new/arch/mips/au1000/common/gpio.c 2007-05-21 01:27:53.000000000 +0200 @@ -1,4 +1,7 @@ /* + * Copyright (C) 2007, OpenWrt.org, Florian Fainelli <florian@xxxxxxxxxxx> + * Architecture specific GPIO support + * * 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 @@ -18,101 +21,128 @@ * 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., * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Notes : + * au1000 SoC have only one GPIO line : GPIO1 + * others have a second one : GPIO2 */ + +#include <linux/autoconf.h> +#include <linux/init.h> +#include <linux/types.h> #include <linux/module.h> -#include <au1000.h> -#include <au1xxx_gpio.h> + +#include <asm/addrspace.h> +#include <asm/io.h> + +#include <asm/mach-au1x00/au1000.h> +#include <asm/gpio.h> #define gpio1 sys #if !defined(CONFIG_SOC_AU1000) static AU1X00_GPIO2 * const gpio2 = (AU1X00_GPIO2 *)GPIO2_BASE; +#define GPIO2_OUTPUT_ENABLE_MASK 0x00010000 -#define GPIO2_OUTPUT_ENABLE_MASK 0x00010000 - -int au1xxx_gpio2_read(int signal) +static int au1xxx_gpio2_read(unsigned gpio) { - signal -= 200; -/* gpio2->dir &= ~(0x01 << signal); //Set GPIO to input */ - return ((gpio2->pinstate >> signal) & 0x01); + gpio -= AU1XXX_GPIO_BASE; + return ((gpio2->pinstate >> gpio) & 0x01); } -void au1xxx_gpio2_write(int signal, int value) +static void au1xxx_gpio2_write(unsigned gpio, int value) { - signal -= 200; + gpio -= AU1XXX_GPIO_BASE; - gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << signal) | - (value << signal); + gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << gpio) | + (value << gpio); } -void au1xxx_gpio2_tristate(int signal) +static int au1xxx_gpio2_direction_input(unsigned gpio) { - signal -= 200; - gpio2->dir &= ~(0x01 << signal); /* Set GPIO to input */ + gpio -= AU1XXX_GPIO_BASE; + gpio2->dir &= ~(0x01 << gpio); + return 0; } -#endif -int au1xxx_gpio1_read(int signal) +static int au1xxx_gpio2_direction_output(unsigned gpio, int value) { -/* gpio1->trioutclr |= (0x01 << signal); */ - return ((gpio1->pinstaterd >> signal) & 0x01); + gpio -= AU1XXX_GPIO_BASE; + gpio2->dir = (0x01 << gpio) | (value << gpio); + return 0; } -void au1xxx_gpio1_write(int signal, int value) +#endif /* !defined(CONFIG_SOC_AU1000) */ + +static int au1xxx_gpio1_read(unsigned gpio) +{ + return ((gpio1->pinstaterd >> gpio) & 0x01); +} + +static void au1xxx_gpio1_write(unsigned gpio, int value) { if(value) - gpio1->outputset = (0x01 << signal); + gpio1->outputset = (0x01 << gpio); else - gpio1->outputclr = (0x01 << signal); /* Output a Zero */ + /* Output a zero */ + gpio1->outputclr = (0x01 << gpio); } -void au1xxx_gpio1_tristate(int signal) +static int au1xxx_gpio1_direction_input(unsigned gpio) { - gpio1->trioutclr = (0x01 << signal); /* Tristate signal */ + gpio1->pininputen = 0;; + return 0; } +static int au1xxx_gpio1_direction_output(unsigned gpio, int value) +{ + gpio1->trioutclr = (0x01 & gpio); + return 0; +} -int au1xxx_gpio_read(int signal) +int au1xxx_gpio_get_value(unsigned gpio) { - if(signal >= 200) + if(gpio >= AU1XXX_GPIO_BASE) #if defined(CONFIG_SOC_AU1000) return 0; #else - return au1xxx_gpio2_read(signal); + return au1xxx_gpio2_read(gpio); #endif else - return au1xxx_gpio1_read(signal); + return au1xxx_gpio1_read(gpio); } -void au1xxx_gpio_write(int signal, int value) +void au1xxx_gpio_set_value(unsigned gpio, int value) { - if(signal >= 200) + if(gpio >= AU1XXX_GPIO_BASE) #if defined(CONFIG_SOC_AU1000) ; #else - au1xxx_gpio2_write(signal, value); + au1xxx_gpio2_write(gpio, value); #endif else - au1xxx_gpio1_write(signal, value); + au1xxx_gpio1_write(gpio, value); } -void au1xxx_gpio_tristate(int signal) +int au1xxx_gpio_direction_input(unsigned gpio) { - if(signal >= 200) + if (gpio >= AU1XXX_GPIO_BASE) #if defined(CONFIG_SOC_AU1000) ; #else - au1xxx_gpio2_tristate(signal); + return au1xxx_gpio2_direction_input(gpio); #endif else - au1xxx_gpio1_tristate(signal); + return au1xxx_gpio1_direction_input(gpio); } -void au1xxx_gpio1_set_inputs(void) +int au1xxx_gpio_direction_output(unsigned gpio, int value) { - gpio1->pininputen = 0; + if (gpio >= AU1XXX_GPIO_BASE) +#if defined(CONFIG_SOC_AU1000) + ; +#else + return au1xxx_gpio2_direction_output(gpio, value); +#endif + else + return au1xxx_gpio1_direction_output(gpio, value); } - -EXPORT_SYMBOL(au1xxx_gpio1_set_inputs); -EXPORT_SYMBOL(au1xxx_gpio_tristate); -EXPORT_SYMBOL(au1xxx_gpio_write); -EXPORT_SYMBOL(au1xxx_gpio_read);
Attachment:
pgpupwmWQHGxg.pgp
Description: PGP signature