Message ID | 1488155205-9305-2-git-send-email-andre.przywara@arm.com |
---|---|
State | Superseded |
Delegated to: | Jagannadha Sutradharudu Teki |
Headers | show |
On Mon, Feb 27, 2017 at 8:26 AM, Andre Przywara <andre.przywara@arm.com> wrote: > Instead of hard-coding GPIO pins used for a certain peripheral, we > should just use the pinctrl information from the DT. > The sun8i-emac driver has some simple implementation of that, so > let's just generalize this and move the code into a more common > location. > On the way we add support for the new, generic pinctrl binding now > used by all Allwinner SoCs. > > Signed-off-by: Andre Przywara <andre.przywara@arm.com> > --- > arch/arm/include/asm/arch-sunxi/gpio.h | 4 ++ > arch/arm/mach-sunxi/pinmux.c | 77 ++++++++++++++++++++++++++++++++++ > 2 files changed, 81 insertions(+) > > diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h > index 85a4ec3..ba8c661 100644 > --- a/arch/arm/include/asm/arch-sunxi/gpio.h > +++ b/arch/arm/include/asm/arch-sunxi/gpio.h > @@ -239,4 +239,8 @@ int axp_gpio_init(void); > static inline int axp_gpio_init(void) { return 0; } > #endif > > +int sunxi_gpio_parse_pin_name(const char *pin_name); > +int sunxi_gpio_setup_dt_pins(const void * volatile fdt_blob, int node, > + const char * mux_name, int mux_sel); > + > #endif /* _SUNXI_GPIO_H */ > diff --git a/arch/arm/mach-sunxi/pinmux.c b/arch/arm/mach-sunxi/pinmux.c > index b026f78..f1e1e8f 100644 > --- a/arch/arm/mach-sunxi/pinmux.c > +++ b/arch/arm/mach-sunxi/pinmux.c > @@ -9,6 +9,9 @@ > #include <common.h> > #include <asm/io.h> > #include <asm/arch/gpio.h> > +#include <fdtdec.h> > +#include <fdt_support.h> > +#include <dt-bindings/pinctrl/sun4i-a10.h> > > void sunxi_gpio_set_cfgbank(struct sunxi_gpio *pio, int bank_offset, u32 val) > { > @@ -69,3 +72,77 @@ int sunxi_gpio_set_pull(u32 pin, u32 val) > > return 0; > } > + > +int sunxi_gpio_parse_pin_name(const char *pin_name) > +{ > + int pin; > + > + if (pin_name[0] != 'P') > + return -1; > + > + if (pin_name[1] < 'A' || pin_name[1] > 'Z') > + return -1; > + > + pin = (pin_name[1] - 'A') << 5; > + pin += simple_strtol(&pin_name[2], NULL, 10); > + > + return pin; > +} > + > +int sunxi_gpio_setup_dt_pins(const void * volatile fdt_blob, int node, > + const char * mux_name, int mux_sel) > +{ > + int drive, pull, pin, i; > + const char *pin_name; > + int offset; > + > + offset = fdtdec_lookup_phandle(fdt_blob, node, "pinctrl-0"); > + if (offset < 0) > + return offset; > + > + drive = fdt_getprop_u32_default_node(fdt_blob, offset, 0, > + "drive-strength", 0); > + if (drive) { > + if (drive <= 10) > + drive = SUN4I_PINCTRL_10_MA; > + else if (drive <= 20) > + drive = SUN4I_PINCTRL_20_MA; > + else if (drive <= 30) > + drive = SUN4I_PINCTRL_30_MA; > + else > + drive = SUN4I_PINCTRL_40_MA; > + } else { > + drive = fdt_getprop_u32_default_node(fdt_blob, offset, 0, > + "allwinner,drive", 4); You should use a different default, something invalid. > + } > + > + if (fdt_get_property(fdt_blob, offset, "bias-pull-up", NULL)) > + pull = SUN4I_PINCTRL_PULL_UP; > + else if (fdt_get_property(fdt_blob, offset, "bias-disable", NULL)) > + pull = SUN4I_PINCTRL_NO_PULL; > + else if (fdt_get_property(fdt_blob, offset, "bias-pull-down", NULL)) > + pull = SUN4I_PINCTRL_PULL_DOWN; > + else > + pull = fdt_getprop_u32_default_node(fdt_blob, offset, 0, > + "allwinner,pull", 0); Same here. > + > + for (i = 0; ; i++) { > + pin_name = fdt_stringlist_get(fdt_blob, offset, > + "allwinner,pins", i, NULL); > + if (!pin_name) { > + pin_name = fdt_stringlist_get(fdt_blob, offset, > + "pins", i, NULL); > + if (!pin_name) > + break; > + } > + pin = sunxi_gpio_parse_pin_name(pin_name); > + if (pin < 0) > + continue; > + > + sunxi_gpio_set_cfgpin(pin, mux_sel); > + sunxi_gpio_set_drv(pin, drive); > + sunxi_gpio_set_pull(pin, pull); As the defaults implied by the bindings are to not touch the settings if they aren't specified, as in "whatever the hardware was set to". This applies to both drive strength and bias/pull. Regards ChenYu > + } > + > + return i; > +} > -- > 2.8.2 >
On Mon, Feb 27, 2017 at 12:26:40AM +0000, Andre Przywara wrote: > Instead of hard-coding GPIO pins used for a certain peripheral, we > should just use the pinctrl information from the DT. > The sun8i-emac driver has some simple implementation of that, so > let's just generalize this and move the code into a more common > location. > On the way we add support for the new, generic pinctrl binding now > used by all Allwinner SoCs. > > Signed-off-by: Andre Przywara <andre.przywara@arm.com> > --- > arch/arm/include/asm/arch-sunxi/gpio.h | 4 ++ > arch/arm/mach-sunxi/pinmux.c | 77 ++++++++++++++++++++++++++++++++++ > 2 files changed, 81 insertions(+) > > diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h > index 85a4ec3..ba8c661 100644 > --- a/arch/arm/include/asm/arch-sunxi/gpio.h > +++ b/arch/arm/include/asm/arch-sunxi/gpio.h > @@ -239,4 +239,8 @@ int axp_gpio_init(void); > static inline int axp_gpio_init(void) { return 0; } > #endif > > +int sunxi_gpio_parse_pin_name(const char *pin_name); > +int sunxi_gpio_setup_dt_pins(const void * volatile fdt_blob, int node, > + const char * mux_name, int mux_sel); > + > #endif /* _SUNXI_GPIO_H */ > diff --git a/arch/arm/mach-sunxi/pinmux.c b/arch/arm/mach-sunxi/pinmux.c > index b026f78..f1e1e8f 100644 > --- a/arch/arm/mach-sunxi/pinmux.c > +++ b/arch/arm/mach-sunxi/pinmux.c > @@ -9,6 +9,9 @@ > #include <common.h> > #include <asm/io.h> > #include <asm/arch/gpio.h> > +#include <fdtdec.h> > +#include <fdt_support.h> > +#include <dt-bindings/pinctrl/sun4i-a10.h> > > void sunxi_gpio_set_cfgbank(struct sunxi_gpio *pio, int bank_offset, u32 val) > { > @@ -69,3 +72,77 @@ int sunxi_gpio_set_pull(u32 pin, u32 val) > > return 0; > } > + > +int sunxi_gpio_parse_pin_name(const char *pin_name) > +{ > + int pin; > + > + if (pin_name[0] != 'P') > + return -1; > + > + if (pin_name[1] < 'A' || pin_name[1] > 'Z') > + return -1; > + > + pin = (pin_name[1] - 'A') << 5; > + pin += simple_strtol(&pin_name[2], NULL, 10); > + > + return pin; > +} That function already exists, sunxi_name_to_gpio. Maxime
Hi, On 27/02/17 10:07, Maxime Ripard wrote: > On Mon, Feb 27, 2017 at 12:26:40AM +0000, Andre Przywara wrote: >> Instead of hard-coding GPIO pins used for a certain peripheral, we >> should just use the pinctrl information from the DT. >> The sun8i-emac driver has some simple implementation of that, so >> let's just generalize this and move the code into a more common >> location. >> On the way we add support for the new, generic pinctrl binding now >> used by all Allwinner SoCs. >> >> Signed-off-by: Andre Przywara <andre.przywara@arm.com> >> --- >> arch/arm/include/asm/arch-sunxi/gpio.h | 4 ++ >> arch/arm/mach-sunxi/pinmux.c | 77 ++++++++++++++++++++++++++++++++++ >> 2 files changed, 81 insertions(+) >> >> diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h >> index 85a4ec3..ba8c661 100644 >> --- a/arch/arm/include/asm/arch-sunxi/gpio.h >> +++ b/arch/arm/include/asm/arch-sunxi/gpio.h >> @@ -239,4 +239,8 @@ int axp_gpio_init(void); >> static inline int axp_gpio_init(void) { return 0; } >> #endif >> >> +int sunxi_gpio_parse_pin_name(const char *pin_name); >> +int sunxi_gpio_setup_dt_pins(const void * volatile fdt_blob, int node, >> + const char * mux_name, int mux_sel); >> + >> #endif /* _SUNXI_GPIO_H */ >> diff --git a/arch/arm/mach-sunxi/pinmux.c b/arch/arm/mach-sunxi/pinmux.c >> index b026f78..f1e1e8f 100644 >> --- a/arch/arm/mach-sunxi/pinmux.c >> +++ b/arch/arm/mach-sunxi/pinmux.c >> @@ -9,6 +9,9 @@ >> #include <common.h> >> #include <asm/io.h> >> #include <asm/arch/gpio.h> >> +#include <fdtdec.h> >> +#include <fdt_support.h> >> +#include <dt-bindings/pinctrl/sun4i-a10.h> >> >> void sunxi_gpio_set_cfgbank(struct sunxi_gpio *pio, int bank_offset, u32 val) >> { >> @@ -69,3 +72,77 @@ int sunxi_gpio_set_pull(u32 pin, u32 val) >> >> return 0; >> } >> + >> +int sunxi_gpio_parse_pin_name(const char *pin_name) >> +{ >> + int pin; >> + >> + if (pin_name[0] != 'P') >> + return -1; >> + >> + if (pin_name[1] < 'A' || pin_name[1] > 'Z') >> + return -1; >> + >> + pin = (pin_name[1] - 'A') << 5; >> + pin += simple_strtol(&pin_name[2], NULL, 10); >> + >> + return pin; >> +} > > That function already exists, sunxi_name_to_gpio. Indeed, I found this yesterday _after_ sending the patches ;-) For some reasons I missed that when I originally wrote the patches, sorry for that. Cheers, Andre.
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index 85a4ec3..ba8c661 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -239,4 +239,8 @@ int axp_gpio_init(void); static inline int axp_gpio_init(void) { return 0; } #endif +int sunxi_gpio_parse_pin_name(const char *pin_name); +int sunxi_gpio_setup_dt_pins(const void * volatile fdt_blob, int node, + const char * mux_name, int mux_sel); + #endif /* _SUNXI_GPIO_H */ diff --git a/arch/arm/mach-sunxi/pinmux.c b/arch/arm/mach-sunxi/pinmux.c index b026f78..f1e1e8f 100644 --- a/arch/arm/mach-sunxi/pinmux.c +++ b/arch/arm/mach-sunxi/pinmux.c @@ -9,6 +9,9 @@ #include <common.h> #include <asm/io.h> #include <asm/arch/gpio.h> +#include <fdtdec.h> +#include <fdt_support.h> +#include <dt-bindings/pinctrl/sun4i-a10.h> void sunxi_gpio_set_cfgbank(struct sunxi_gpio *pio, int bank_offset, u32 val) { @@ -69,3 +72,77 @@ int sunxi_gpio_set_pull(u32 pin, u32 val) return 0; } + +int sunxi_gpio_parse_pin_name(const char *pin_name) +{ + int pin; + + if (pin_name[0] != 'P') + return -1; + + if (pin_name[1] < 'A' || pin_name[1] > 'Z') + return -1; + + pin = (pin_name[1] - 'A') << 5; + pin += simple_strtol(&pin_name[2], NULL, 10); + + return pin; +} + +int sunxi_gpio_setup_dt_pins(const void * volatile fdt_blob, int node, + const char * mux_name, int mux_sel) +{ + int drive, pull, pin, i; + const char *pin_name; + int offset; + + offset = fdtdec_lookup_phandle(fdt_blob, node, "pinctrl-0"); + if (offset < 0) + return offset; + + drive = fdt_getprop_u32_default_node(fdt_blob, offset, 0, + "drive-strength", 0); + if (drive) { + if (drive <= 10) + drive = SUN4I_PINCTRL_10_MA; + else if (drive <= 20) + drive = SUN4I_PINCTRL_20_MA; + else if (drive <= 30) + drive = SUN4I_PINCTRL_30_MA; + else + drive = SUN4I_PINCTRL_40_MA; + } else { + drive = fdt_getprop_u32_default_node(fdt_blob, offset, 0, + "allwinner,drive", 4); + } + + if (fdt_get_property(fdt_blob, offset, "bias-pull-up", NULL)) + pull = SUN4I_PINCTRL_PULL_UP; + else if (fdt_get_property(fdt_blob, offset, "bias-disable", NULL)) + pull = SUN4I_PINCTRL_NO_PULL; + else if (fdt_get_property(fdt_blob, offset, "bias-pull-down", NULL)) + pull = SUN4I_PINCTRL_PULL_DOWN; + else + pull = fdt_getprop_u32_default_node(fdt_blob, offset, 0, + "allwinner,pull", 0); + + for (i = 0; ; i++) { + pin_name = fdt_stringlist_get(fdt_blob, offset, + "allwinner,pins", i, NULL); + if (!pin_name) { + pin_name = fdt_stringlist_get(fdt_blob, offset, + "pins", i, NULL); + if (!pin_name) + break; + } + pin = sunxi_gpio_parse_pin_name(pin_name); + if (pin < 0) + continue; + + sunxi_gpio_set_cfgpin(pin, mux_sel); + sunxi_gpio_set_drv(pin, drive); + sunxi_gpio_set_pull(pin, pull); + } + + return i; +}
Instead of hard-coding GPIO pins used for a certain peripheral, we should just use the pinctrl information from the DT. The sun8i-emac driver has some simple implementation of that, so let's just generalize this and move the code into a more common location. On the way we add support for the new, generic pinctrl binding now used by all Allwinner SoCs. Signed-off-by: Andre Przywara <andre.przywara@arm.com> --- arch/arm/include/asm/arch-sunxi/gpio.h | 4 ++ arch/arm/mach-sunxi/pinmux.c | 77 ++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+)