[U-Boot] [PATCH 0/5] dm: gpio: add BMIPS gpio support

Broadcom MIPS SoCs have one or two GPIO banks, depending on the number of gpios present: BCM6345 => 16 GPIOs / 1 bank BCM6328 => 32 GPIOs / 1 bank BCM6358 => 40 GPIOs / 2 banks BCM63268 => 52 GPIOs / 2 banks
typedef struct GpioControl { uint32 GPIODirHi; /* 0 */ uint32 GPIODir; /* 4 */ uint32 GPIOioHi; /* 8 */ uint32 GPIOio; /* C */ }
Álvaro Fernández Rojas (5): dm: gpio: add BCM6345 gpio driver mips: bmips: add bcm6345-gpio driver support for BCM6358 mips: bmips: add bcm6345-gpio driver support for BCM6328 mips: bmips: add bcm6345-gpio driver support for BCM63268 mips: bmips: add Huawei HG556a gpio-leds
arch/mips/dts/brcm,bcm63268.dtsi | 19 ++++++ arch/mips/dts/brcm,bcm6328.dtsi | 9 +++ arch/mips/dts/brcm,bcm6358.dtsi | 19 ++++++ arch/mips/dts/huawei,hg556a.dts | 73 +++++++++++++++++++++ configs/huawei_hg556a_ram_defconfig | 4 ++ drivers/gpio/Kconfig | 6 ++ drivers/gpio/Makefile | 1 + drivers/gpio/bcm6345_gpio.c | 125 ++++++++++++++++++++++++++++++++++++ 8 files changed, 256 insertions(+) create mode 100644 drivers/gpio/bcm6345_gpio.c

This driver is based on linux/arch/mips/bcm63xx/gpio.c, simplified to allow defining one or two independent banks for each Broadcom SoC.
Signed-off-by: Álvaro Fernández Rojas noltari@gmail.com --- drivers/gpio/Kconfig | 6 +++ drivers/gpio/Makefile | 1 + drivers/gpio/bcm6345_gpio.c | 125 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 drivers/gpio/bcm6345_gpio.c
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index c95e9ac..9f04061 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -21,6 +21,12 @@ config ALTERA_PIO Select this to enable PIO for Altera devices. Please find details on the "Embedded Peripherals IP User Guide" of Altera.
+config BCM6345_GPIO + bool "BCM6345 GPIO driver" + depends on DM_GPIO && ARCH_BMIPS + help + This driver supports the GPIO banks on BCM6345 SoCs. + config DWAPB_GPIO bool "DWAPB GPIO driver" depends on DM && DM_GPIO diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 27f8068..0484428 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_DM_74X164) += 74x164_gpio.o
obj-$(CONFIG_AT91_GPIO) += at91_gpio.o obj-$(CONFIG_ATMEL_PIO4) += atmel_pio4.o +obj-$(CONFIG_BCM6345_GPIO) += bcm6345_gpio.o obj-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o obj-$(CONFIG_INTEL_BROADWELL_GPIO) += intel_broadwell_gpio.o obj-$(CONFIG_KIRKWOOD_GPIO) += kw_gpio.o diff --git a/drivers/gpio/bcm6345_gpio.c b/drivers/gpio/bcm6345_gpio.c new file mode 100644 index 0000000..4a72eb9 --- /dev/null +++ b/drivers/gpio/bcm6345_gpio.c @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2017 Álvaro Fernández Rojas noltari@gmail.com + * + * Derived from linux/arch/mips/bcm63xx/gpio.c: + * Copyright (C) 2008 Maxime Bizon mbizon@freebox.fr + * Copyright (C) 2008-2011 Florian Fainelli florian@openwrt.org + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <errno.h> +#include <asm/gpio.h> +#include <asm/io.h> +#include <dm/device.h> + +DECLARE_GLOBAL_DATA_PTR; + +struct bcm6345_gpio_priv { + void __iomem *reg_dirout; + void __iomem *reg_data; +}; + +static int bcm6345_gpio_get_value(struct udevice *dev, unsigned offset) +{ + struct bcm6345_gpio_priv *priv = dev_get_priv(dev); + + return !!(readl_be(priv->reg_data) & BIT(offset)); +} + +static int bcm6345_gpio_set_value(struct udevice *dev, unsigned offset, + int value) +{ + struct bcm6345_gpio_priv *priv = dev_get_priv(dev); + + if (value) + setbits_be32(priv->reg_data, BIT(offset)); + else + clrbits_be32(priv->reg_data, BIT(offset)); + + return 0; +} + +static int bcm6345_gpio_set_direction(void __iomem *dirout, unsigned offset, + bool input) +{ + if (input) + clrbits_be32(dirout, BIT(offset)); + else + setbits_be32(dirout, BIT(offset)); + + return 0; +} + +static int bcm6345_gpio_direction_input(struct udevice *dev, unsigned offset) +{ + struct bcm6345_gpio_priv *priv = dev_get_priv(dev); + + return bcm6345_gpio_set_direction(priv->reg_dirout, offset, 1); +} + +static int bcm6345_gpio_direction_output(struct udevice *dev, unsigned offset, + int value) +{ + struct bcm6345_gpio_priv *priv = dev_get_priv(dev); + + return bcm6345_gpio_set_direction(priv->reg_dirout, offset, 0); +} + +static int bcm6345_gpio_get_function(struct udevice *dev, unsigned offset) +{ + struct bcm6345_gpio_priv *priv = dev_get_priv(dev); + + if (readl_be(priv->reg_dirout) & BIT(offset)) + return GPIOF_OUTPUT; + else + return GPIOF_INPUT; +} + +static const struct dm_gpio_ops bcm6345_gpio_ops = { + .direction_input = bcm6345_gpio_direction_input, + .direction_output = bcm6345_gpio_direction_output, + .get_value = bcm6345_gpio_get_value, + .set_value = bcm6345_gpio_set_value, + .get_function = bcm6345_gpio_get_function, +}; + +static int bcm6345_gpio_probe(struct udevice *dev) +{ + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + struct bcm6345_gpio_priv *priv = dev_get_priv(dev); + fdt_addr_t data_addr, dirout_addr; + fdt_size_t data_size, dirout_size; + + dirout_addr = dev_get_addr_size_index(dev, 0, &dirout_size); + if (dirout_addr == FDT_ADDR_T_NONE) + return -EINVAL; + + data_addr = dev_get_addr_size_index(dev, 1, &data_size); + if (data_addr == FDT_ADDR_T_NONE) + return -EINVAL; + + priv->reg_data = ioremap(data_addr, data_size); + priv->reg_dirout = ioremap(dirout_addr, dirout_size); + + uc_priv->gpio_count = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), + "ngpios", 32); + uc_priv->bank_name = strdup(dev->name); + + return 0; +} + +static const struct udevice_id bcm6345_gpio_ids[] = { + { .compatible = "brcm,bcm6345-gpio" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(bcm6345_gpio) = { + .name = "bcm6345-gpio", + .id = UCLASS_GPIO, + .of_match = bcm6345_gpio_ids, + .ops = &bcm6345_gpio_ops, + .probe = bcm6345_gpio_probe, + .priv_auto_alloc_size = sizeof(struct bcm6345_gpio_priv), +};

Hi Alvaro,
On 3 May 2017 at 07:07, Álvaro Fernández Rojas noltari@gmail.com wrote:
This driver is based on linux/arch/mips/bcm63xx/gpio.c, simplified to allow defining one or two independent banks for each Broadcom SoC.
Signed-off-by: Álvaro Fernández Rojas noltari@gmail.com
drivers/gpio/Kconfig | 6 +++ drivers/gpio/Makefile | 1 + drivers/gpio/bcm6345_gpio.c | 125 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 drivers/gpio/bcm6345_gpio.c
Reviewed-by: Simon Glass sjg@chromium.org
[...]
+static int bcm6345_gpio_probe(struct udevice *dev) +{
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
struct bcm6345_gpio_priv *priv = dev_get_priv(dev);
fdt_addr_t data_addr, dirout_addr;
fdt_size_t data_size, dirout_size;
dirout_addr = dev_get_addr_size_index(dev, 0, &dirout_size);
if (dirout_addr == FDT_ADDR_T_NONE)
return -EINVAL;
data_addr = dev_get_addr_size_index(dev, 1, &data_size);
if (data_addr == FDT_ADDR_T_NONE)
return -EINVAL;
priv->reg_data = ioremap(data_addr, data_size);
priv->reg_dirout = ioremap(dirout_addr, dirout_size);
uc_priv->gpio_count = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
"ngpios", 32);
uc_priv->bank_name = strdup(dev->name);
I don't think you need strdup(). If you do want this, you should add a remove() function to free it.
return 0;
+}
+static const struct udevice_id bcm6345_gpio_ids[] = {
{ .compatible = "brcm,bcm6345-gpio" },
{ /* sentinel */ }
+};
+U_BOOT_DRIVER(bcm6345_gpio) = {
.name = "bcm6345-gpio",
.id = UCLASS_GPIO,
.of_match = bcm6345_gpio_ids,
.ops = &bcm6345_gpio_ops,
.probe = bcm6345_gpio_probe,
.priv_auto_alloc_size = sizeof(struct bcm6345_gpio_priv),
+};
2.1.4

This SoC has one gpio bank divided into two 32 bit registers, with a total of 40 GPIOs.
Signed-off-by: Álvaro Fernández Rojas noltari@gmail.com --- arch/mips/dts/brcm,bcm6358.dtsi | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6358.dtsi b/arch/mips/dts/brcm,bcm6358.dtsi index 48322fb..4c94555 100644 --- a/arch/mips/dts/brcm,bcm6358.dtsi +++ b/arch/mips/dts/brcm,bcm6358.dtsi @@ -73,6 +73,25 @@ mask = <0x1>; };
+ gpio1: gpio-controller@fffe0080 { + compatible = "brcm,bcm6345-gpio"; + reg = <0xfffe0080 0x4>, <0xfffe0088 0x4>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + + status = "disabled"; + }; + + gpio0: gpio-controller@fffe0084 { + compatible = "brcm,bcm6345-gpio"; + reg = <0xfffe0084 0x4>, <0xfffe008c 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; + uart0: serial@fffe0100 { compatible = "brcm,bcm6345-uart"; reg = <0xfffe0100 0x18>;

On 3 May 2017 at 07:07, Álvaro Fernández Rojas noltari@gmail.com wrote:
This SoC has one gpio bank divided into two 32 bit registers, with a total of 40 GPIOs.
Signed-off-by: Álvaro Fernández Rojas noltari@gmail.com
arch/mips/dts/brcm,bcm6358.dtsi | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org

This SoC has one gpio bank with a total of 32 GPIOs.
Signed-off-by: Álvaro Fernández Rojas noltari@gmail.com --- arch/mips/dts/brcm,bcm6328.dtsi | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6328.dtsi b/arch/mips/dts/brcm,bcm6328.dtsi index b287239..30c2ee8 100644 --- a/arch/mips/dts/brcm,bcm6328.dtsi +++ b/arch/mips/dts/brcm,bcm6328.dtsi @@ -63,6 +63,15 @@ mask = <0x1>; };
+ gpio: gpio-controller@10000084 { + compatible = "brcm,bcm6345-gpio"; + reg = <0x10000084 0x4>, <0x1000008c 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; + uart0: serial@10000100 { compatible = "brcm,bcm6345-uart"; reg = <0x10000100 0x18>;

On 3 May 2017 at 07:07, Álvaro Fernández Rojas noltari@gmail.com wrote:
This SoC has one gpio bank with a total of 32 GPIOs.
Signed-off-by: Álvaro Fernández Rojas noltari@gmail.com
arch/mips/dts/brcm,bcm6328.dtsi | 9 +++++++++ 1 file changed, 9 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org

This SoC has one gpio bank divided into two 32 bit registers, with a total of 52 GPIOs.
Signed-off-by: Álvaro Fernández Rojas noltari@gmail.com --- arch/mips/dts/brcm,bcm63268.dtsi | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm63268.dtsi b/arch/mips/dts/brcm,bcm63268.dtsi index 3d81047..3eda77d 100644 --- a/arch/mips/dts/brcm,bcm63268.dtsi +++ b/arch/mips/dts/brcm,bcm63268.dtsi @@ -63,6 +63,25 @@ mask = <0x1>; };
+ gpio1: gpio-controller@100000c0 { + compatible = "brcm,bcm6345-gpio"; + reg = <0x100000c0 0x4>, <0x100000c8 0x4>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <20>; + + status = "disabled"; + }; + + gpio0: gpio-controller@100000c4 { + compatible = "brcm,bcm6345-gpio"; + reg = <0x100000c4 0x4>, <0x100000cc 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; + uart0: serial@10000180 { compatible = "brcm,bcm6345-uart"; reg = <0x10000180 0x18>;

On 3 May 2017 at 07:07, Álvaro Fernández Rojas noltari@gmail.com wrote:
This SoC has one gpio bank divided into two 32 bit registers, with a total of 52 GPIOs.
Signed-off-by: Álvaro Fernández Rojas noltari@gmail.com
arch/mips/dts/brcm,bcm63268.dtsi | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org

This board has several LEDs attached to gpio0.
Signed-off-by: Álvaro Fernández Rojas noltari@gmail.com --- arch/mips/dts/huawei,hg556a.dts | 73 +++++++++++++++++++++++++++++++++++++ configs/huawei_hg556a_ram_defconfig | 4 ++ 2 files changed, 77 insertions(+)
diff --git a/arch/mips/dts/huawei,hg556a.dts b/arch/mips/dts/huawei,hg556a.dts index 6775909..31c7d7e 100644 --- a/arch/mips/dts/huawei,hg556a.dts +++ b/arch/mips/dts/huawei,hg556a.dts @@ -19,6 +19,79 @@ chosen { stdout-path = "serial0:115200n8"; }; + + gpio-leds { + compatible = "gpio-leds"; + + message_red { + label = "HG556a:red:message"; + gpios = <&gpio0 0 GPIO_ACTIVE_LOW>; + }; + + hspa_red { + label = "HG556a:red:hspa"; + gpios = <&gpio0 1 GPIO_ACTIVE_LOW>; + }; + + dsl_red { + label = "HG556a:red:dsl"; + gpios = <&gpio0 2 GPIO_ACTIVE_LOW>; + }; + + power_red { + label = "HG556a:red:power"; + gpios = <&gpio0 3 GPIO_ACTIVE_LOW>; + }; + + all_red { + label = "HG556a:red:all"; + gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; + }; + + lan1_green { + label = "HG556a:green:lan1"; + gpios = <&gpio0 12 GPIO_ACTIVE_LOW>; + }; + + lan1_red { + label = "HG556a:red:lan1"; + gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; + }; + + lan2_green { + label = "HG556a:green:lan2"; + gpios = <&gpio0 15 GPIO_ACTIVE_LOW>; + }; + + lan2_red { + label = "HG556a:red:lan2"; + gpios = <&gpio0 22 GPIO_ACTIVE_LOW>; + }; + + lan3_green { + label = "HG556a:green:lan3"; + gpios = <&gpio0 23 GPIO_ACTIVE_LOW>; + }; + + lan3_red { + label = "HG556a:red:lan3"; + gpios = <&gpio0 26 GPIO_ACTIVE_LOW>; + }; + + lan4_green { + label = "HG556a:green:lan4"; + gpios = <&gpio0 27 GPIO_ACTIVE_LOW>; + }; + + lan4_red { + label = "HG556a:red:lan4"; + gpios = <&gpio0 28 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&gpio0 { + status = "okay"; };
&pflash { diff --git a/configs/huawei_hg556a_ram_defconfig b/configs/huawei_hg556a_ram_defconfig index ca00c4d..ccfdf1d 100644 --- a/configs/huawei_hg556a_ram_defconfig +++ b/configs/huawei_hg556a_ram_defconfig @@ -1,5 +1,6 @@ CONFIG_ARCH_BMIPS=y CONFIG_BAUDRATE=115200 +CONFIG_BCM6345_GPIO=y CONFIG_BCM6345_SERIAL=y CONFIG_BMIPS_BOOT_RAM=y CONFIG_BOARD_HUAWEI_HG556A=y @@ -17,6 +18,7 @@ CONFIG_CMD_FLASH=y # CONFIG_CMD_GPIO is not set # CONFIG_CMD_IMLS is not set # CONFIG_CMD_IMPORTENV is not set +CONFIG_CMD_LED=y CONFIG_CMD_LICENSE=y CONFIG_CMD_LOADB=y # CONFIG_CMD_LOADS is not set @@ -32,6 +34,8 @@ CONFIG_DISPLAY_CPUINFO=y CONFIG_DM_GPIO=y CONFIG_DM_SERIAL=y CONFIG_HUSH_PARSER=y +CONFIG_LED=y +CONFIG_LED_GPIO=y CONFIG_MIPS=y # CONFIG_MIPS_BOOT_CMDLINE_LEGACY is not set # CONFIG_MIPS_BOOT_ENV_LEGACY is not set

On 3 May 2017 at 07:07, Álvaro Fernández Rojas noltari@gmail.com wrote:
This board has several LEDs attached to gpio0.
Signed-off-by: Álvaro Fernández Rojas noltari@gmail.com
arch/mips/dts/huawei,hg556a.dts | 73 +++++++++++++++++++++++++++++++++++++ configs/huawei_hg556a_ram_defconfig | 4 ++ 2 files changed, 77 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org

Broadcom MIPS SoCs have one or two GPIO banks, depending on the number of gpios present: BCM6345 => 16 GPIOs / 1 bank BCM6328 => 32 GPIOs / 1 bank BCM6358 => 40 GPIOs / 2 banks BCM63268 => 52 GPIOs / 2 banks
typedef struct GpioControl { uint32 GPIODirHi; /* 0 */ uint32 GPIODir; /* 4 */ uint32 GPIOioHi; /* 8 */ uint32 GPIOio; /* C */ }
v2: Introduce changes suggested by Simon Glass
Álvaro Fernández Rojas (5): dm: gpio: add BCM6345 gpio driver mips: bmips: add bcm6345-gpio driver support for BCM6358 mips: bmips: add bcm6345-gpio driver support for BCM6328 mips: bmips: add bcm6345-gpio driver support for BCM63268 mips: bmips: add Huawei HG556a gpio-leds
arch/mips/dts/brcm,bcm63268.dtsi | 19 ++++++ arch/mips/dts/brcm,bcm6328.dtsi | 9 +++ arch/mips/dts/brcm,bcm6358.dtsi | 19 ++++++ arch/mips/dts/huawei,hg556a.dts | 73 +++++++++++++++++++++ configs/huawei_hg556a_ram_defconfig | 4 ++ drivers/gpio/Kconfig | 6 ++ drivers/gpio/Makefile | 1 + drivers/gpio/bcm6345_gpio.c | 125 ++++++++++++++++++++++++++++++++++++ 8 files changed, 256 insertions(+) create mode 100644 drivers/gpio/bcm6345_gpio.c

This driver is based on linux/arch/mips/bcm63xx/gpio.c, simplified to allow defining one or two independent banks for each Broadcom SoC.
Signed-off-by: Álvaro Fernández Rojas noltari@gmail.com Reviewed-by: Simon Glass sjg@chromium.org --- v2: Introduce changes suggested by Simon Glass: - Remove unneeded strdup.
drivers/gpio/Kconfig | 6 +++ drivers/gpio/Makefile | 1 + drivers/gpio/bcm6345_gpio.c | 125 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 drivers/gpio/bcm6345_gpio.c
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index c95e9ac..9f04061 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -21,6 +21,12 @@ config ALTERA_PIO Select this to enable PIO for Altera devices. Please find details on the "Embedded Peripherals IP User Guide" of Altera.
+config BCM6345_GPIO + bool "BCM6345 GPIO driver" + depends on DM_GPIO && ARCH_BMIPS + help + This driver supports the GPIO banks on BCM6345 SoCs. + config DWAPB_GPIO bool "DWAPB GPIO driver" depends on DM && DM_GPIO diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 27f8068..0484428 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_DM_74X164) += 74x164_gpio.o
obj-$(CONFIG_AT91_GPIO) += at91_gpio.o obj-$(CONFIG_ATMEL_PIO4) += atmel_pio4.o +obj-$(CONFIG_BCM6345_GPIO) += bcm6345_gpio.o obj-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o obj-$(CONFIG_INTEL_BROADWELL_GPIO) += intel_broadwell_gpio.o obj-$(CONFIG_KIRKWOOD_GPIO) += kw_gpio.o diff --git a/drivers/gpio/bcm6345_gpio.c b/drivers/gpio/bcm6345_gpio.c new file mode 100644 index 0000000..1c46020 --- /dev/null +++ b/drivers/gpio/bcm6345_gpio.c @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2017 Álvaro Fernández Rojas noltari@gmail.com + * + * Derived from linux/arch/mips/bcm63xx/gpio.c: + * Copyright (C) 2008 Maxime Bizon mbizon@freebox.fr + * Copyright (C) 2008-2011 Florian Fainelli florian@openwrt.org + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <errno.h> +#include <asm/gpio.h> +#include <asm/io.h> +#include <dm/device.h> + +DECLARE_GLOBAL_DATA_PTR; + +struct bcm6345_gpio_priv { + void __iomem *reg_dirout; + void __iomem *reg_data; +}; + +static int bcm6345_gpio_get_value(struct udevice *dev, unsigned offset) +{ + struct bcm6345_gpio_priv *priv = dev_get_priv(dev); + + return !!(readl_be(priv->reg_data) & BIT(offset)); +} + +static int bcm6345_gpio_set_value(struct udevice *dev, unsigned offset, + int value) +{ + struct bcm6345_gpio_priv *priv = dev_get_priv(dev); + + if (value) + setbits_be32(priv->reg_data, BIT(offset)); + else + clrbits_be32(priv->reg_data, BIT(offset)); + + return 0; +} + +static int bcm6345_gpio_set_direction(void __iomem *dirout, unsigned offset, + bool input) +{ + if (input) + clrbits_be32(dirout, BIT(offset)); + else + setbits_be32(dirout, BIT(offset)); + + return 0; +} + +static int bcm6345_gpio_direction_input(struct udevice *dev, unsigned offset) +{ + struct bcm6345_gpio_priv *priv = dev_get_priv(dev); + + return bcm6345_gpio_set_direction(priv->reg_dirout, offset, 1); +} + +static int bcm6345_gpio_direction_output(struct udevice *dev, unsigned offset, + int value) +{ + struct bcm6345_gpio_priv *priv = dev_get_priv(dev); + + return bcm6345_gpio_set_direction(priv->reg_dirout, offset, 0); +} + +static int bcm6345_gpio_get_function(struct udevice *dev, unsigned offset) +{ + struct bcm6345_gpio_priv *priv = dev_get_priv(dev); + + if (readl_be(priv->reg_dirout) & BIT(offset)) + return GPIOF_OUTPUT; + else + return GPIOF_INPUT; +} + +static const struct dm_gpio_ops bcm6345_gpio_ops = { + .direction_input = bcm6345_gpio_direction_input, + .direction_output = bcm6345_gpio_direction_output, + .get_value = bcm6345_gpio_get_value, + .set_value = bcm6345_gpio_set_value, + .get_function = bcm6345_gpio_get_function, +}; + +static int bcm6345_gpio_probe(struct udevice *dev) +{ + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + struct bcm6345_gpio_priv *priv = dev_get_priv(dev); + fdt_addr_t data_addr, dirout_addr; + fdt_size_t data_size, dirout_size; + + dirout_addr = dev_get_addr_size_index(dev, 0, &dirout_size); + if (dirout_addr == FDT_ADDR_T_NONE) + return -EINVAL; + + data_addr = dev_get_addr_size_index(dev, 1, &data_size); + if (data_addr == FDT_ADDR_T_NONE) + return -EINVAL; + + priv->reg_data = ioremap(data_addr, data_size); + priv->reg_dirout = ioremap(dirout_addr, dirout_size); + + uc_priv->gpio_count = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), + "ngpios", 32); + uc_priv->bank_name = dev->name; + + return 0; +} + +static const struct udevice_id bcm6345_gpio_ids[] = { + { .compatible = "brcm,bcm6345-gpio" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(bcm6345_gpio) = { + .name = "bcm6345-gpio", + .id = UCLASS_GPIO, + .of_match = bcm6345_gpio_ids, + .ops = &bcm6345_gpio_ops, + .priv_auto_alloc_size = sizeof(struct bcm6345_gpio_priv), + .probe = bcm6345_gpio_probe, +};

This SoC has one gpio bank divided into two 32 bit registers, with a total of 40 GPIOs.
Signed-off-by: Álvaro Fernández Rojas noltari@gmail.com Reviewed-by: Simon Glass sjg@chromium.org --- v2: no changes.
arch/mips/dts/brcm,bcm6358.dtsi | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6358.dtsi b/arch/mips/dts/brcm,bcm6358.dtsi index 48322fb..4c94555 100644 --- a/arch/mips/dts/brcm,bcm6358.dtsi +++ b/arch/mips/dts/brcm,bcm6358.dtsi @@ -73,6 +73,25 @@ mask = <0x1>; };
+ gpio1: gpio-controller@fffe0080 { + compatible = "brcm,bcm6345-gpio"; + reg = <0xfffe0080 0x4>, <0xfffe0088 0x4>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + + status = "disabled"; + }; + + gpio0: gpio-controller@fffe0084 { + compatible = "brcm,bcm6345-gpio"; + reg = <0xfffe0084 0x4>, <0xfffe008c 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; + uart0: serial@fffe0100 { compatible = "brcm,bcm6345-uart"; reg = <0xfffe0100 0x18>;

This SoC has one gpio bank with a total of 32 GPIOs.
Signed-off-by: Álvaro Fernández Rojas noltari@gmail.com Reviewed-by: Simon Glass sjg@chromium.org --- v2: no changes.
arch/mips/dts/brcm,bcm6328.dtsi | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6328.dtsi b/arch/mips/dts/brcm,bcm6328.dtsi index b287239..30c2ee8 100644 --- a/arch/mips/dts/brcm,bcm6328.dtsi +++ b/arch/mips/dts/brcm,bcm6328.dtsi @@ -63,6 +63,15 @@ mask = <0x1>; };
+ gpio: gpio-controller@10000084 { + compatible = "brcm,bcm6345-gpio"; + reg = <0x10000084 0x4>, <0x1000008c 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; + uart0: serial@10000100 { compatible = "brcm,bcm6345-uart"; reg = <0x10000100 0x18>;

This SoC has one gpio bank divided into two 32 bit registers, with a total of 52 GPIOs.
Signed-off-by: Álvaro Fernández Rojas noltari@gmail.com Reviewed-by: Simon Glass sjg@chromium.org --- v2: no changes.
arch/mips/dts/brcm,bcm63268.dtsi | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm63268.dtsi b/arch/mips/dts/brcm,bcm63268.dtsi index 3d81047..3eda77d 100644 --- a/arch/mips/dts/brcm,bcm63268.dtsi +++ b/arch/mips/dts/brcm,bcm63268.dtsi @@ -63,6 +63,25 @@ mask = <0x1>; };
+ gpio1: gpio-controller@100000c0 { + compatible = "brcm,bcm6345-gpio"; + reg = <0x100000c0 0x4>, <0x100000c8 0x4>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <20>; + + status = "disabled"; + }; + + gpio0: gpio-controller@100000c4 { + compatible = "brcm,bcm6345-gpio"; + reg = <0x100000c4 0x4>, <0x100000cc 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; + uart0: serial@10000180 { compatible = "brcm,bcm6345-uart"; reg = <0x10000180 0x18>;

This board has several LEDs attached to gpio0.
Signed-off-by: Álvaro Fernández Rojas noltari@gmail.com Reviewed-by: Simon Glass sjg@chromium.org --- v2: no changes.
arch/mips/dts/huawei,hg556a.dts | 73 +++++++++++++++++++++++++++++++++++++ configs/huawei_hg556a_ram_defconfig | 4 ++ 2 files changed, 77 insertions(+)
diff --git a/arch/mips/dts/huawei,hg556a.dts b/arch/mips/dts/huawei,hg556a.dts index 6775909..31c7d7e 100644 --- a/arch/mips/dts/huawei,hg556a.dts +++ b/arch/mips/dts/huawei,hg556a.dts @@ -19,6 +19,79 @@ chosen { stdout-path = "serial0:115200n8"; }; + + gpio-leds { + compatible = "gpio-leds"; + + message_red { + label = "HG556a:red:message"; + gpios = <&gpio0 0 GPIO_ACTIVE_LOW>; + }; + + hspa_red { + label = "HG556a:red:hspa"; + gpios = <&gpio0 1 GPIO_ACTIVE_LOW>; + }; + + dsl_red { + label = "HG556a:red:dsl"; + gpios = <&gpio0 2 GPIO_ACTIVE_LOW>; + }; + + power_red { + label = "HG556a:red:power"; + gpios = <&gpio0 3 GPIO_ACTIVE_LOW>; + }; + + all_red { + label = "HG556a:red:all"; + gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; + }; + + lan1_green { + label = "HG556a:green:lan1"; + gpios = <&gpio0 12 GPIO_ACTIVE_LOW>; + }; + + lan1_red { + label = "HG556a:red:lan1"; + gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; + }; + + lan2_green { + label = "HG556a:green:lan2"; + gpios = <&gpio0 15 GPIO_ACTIVE_LOW>; + }; + + lan2_red { + label = "HG556a:red:lan2"; + gpios = <&gpio0 22 GPIO_ACTIVE_LOW>; + }; + + lan3_green { + label = "HG556a:green:lan3"; + gpios = <&gpio0 23 GPIO_ACTIVE_LOW>; + }; + + lan3_red { + label = "HG556a:red:lan3"; + gpios = <&gpio0 26 GPIO_ACTIVE_LOW>; + }; + + lan4_green { + label = "HG556a:green:lan4"; + gpios = <&gpio0 27 GPIO_ACTIVE_LOW>; + }; + + lan4_red { + label = "HG556a:red:lan4"; + gpios = <&gpio0 28 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&gpio0 { + status = "okay"; };
&pflash { diff --git a/configs/huawei_hg556a_ram_defconfig b/configs/huawei_hg556a_ram_defconfig index ca00c4d..ccfdf1d 100644 --- a/configs/huawei_hg556a_ram_defconfig +++ b/configs/huawei_hg556a_ram_defconfig @@ -1,5 +1,6 @@ CONFIG_ARCH_BMIPS=y CONFIG_BAUDRATE=115200 +CONFIG_BCM6345_GPIO=y CONFIG_BCM6345_SERIAL=y CONFIG_BMIPS_BOOT_RAM=y CONFIG_BOARD_HUAWEI_HG556A=y @@ -17,6 +18,7 @@ CONFIG_CMD_FLASH=y # CONFIG_CMD_GPIO is not set # CONFIG_CMD_IMLS is not set # CONFIG_CMD_IMPORTENV is not set +CONFIG_CMD_LED=y CONFIG_CMD_LICENSE=y CONFIG_CMD_LOADB=y # CONFIG_CMD_LOADS is not set @@ -32,6 +34,8 @@ CONFIG_DISPLAY_CPUINFO=y CONFIG_DM_GPIO=y CONFIG_DM_SERIAL=y CONFIG_HUSH_PARSER=y +CONFIG_LED=y +CONFIG_LED_GPIO=y CONFIG_MIPS=y # CONFIG_MIPS_BOOT_CMDLINE_LEGACY is not set # CONFIG_MIPS_BOOT_ENV_LEGACY is not set

Am 03.05.2017 um 15:07 schrieb Álvaro Fernández Rojas:
Broadcom MIPS SoCs have one or two GPIO banks, depending on the number of gpios present: BCM6345 => 16 GPIOs / 1 bank BCM6328 => 32 GPIOs / 1 bank BCM6358 => 40 GPIOs / 2 banks BCM63268 => 52 GPIOs / 2 banks
typedef struct GpioControl { uint32 GPIODirHi; /* 0 */ uint32 GPIODir; /* 4 */ uint32 GPIOioHi; /* 8 */ uint32 GPIOio; /* C */ }
Álvaro Fernández Rojas (5): dm: gpio: add BCM6345 gpio driver mips: bmips: add bcm6345-gpio driver support for BCM6358 mips: bmips: add bcm6345-gpio driver support for BCM6328 mips: bmips: add bcm6345-gpio driver support for BCM63268 mips: bmips: add Huawei HG556a gpio-leds
arch/mips/dts/brcm,bcm63268.dtsi | 19 ++++++ arch/mips/dts/brcm,bcm6328.dtsi | 9 +++ arch/mips/dts/brcm,bcm6358.dtsi | 19 ++++++ arch/mips/dts/huawei,hg556a.dts | 73 +++++++++++++++++++++ configs/huawei_hg556a_ram_defconfig | 4 ++ drivers/gpio/Kconfig | 6 ++ drivers/gpio/Makefile | 1 + drivers/gpio/bcm6345_gpio.c | 125 ++++++++++++++++++++++++++++++++++++ 8 files changed, 256 insertions(+) create mode 100644 drivers/gpio/bcm6345_gpio.c
series applied to u-boot-mips/next, thanks
participants (3)
-
Daniel Schwierzeck
-
Simon Glass
-
Álvaro Fernández Rojas