diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2021-03-30 00:55:49 +0200 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2021-03-30 00:55:49 +0200 |
commit | 762bee3e3e9f42cafdb3ead64b7aee37f9b7369f (patch) | |
tree | ac41e90b78bee9bbfb73b4650d519f3081043b6d | |
parent | 22667a63fe3e5fbda7b02ac51d769ad906a385b2 (diff) | |
parent | d28039fccf948a407de69106465caa465b1dcf32 (diff) | |
download | linux-762bee3e3e9f42cafdb3ead64b7aee37f9b7369f.tar.gz |
Merge branch 'ib-bcm63xx' into devel
27 files changed, 5467 insertions, 46 deletions
diff --git a/Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.txt b/Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.txt deleted file mode 100644 index e7853143fa42..000000000000 --- a/Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.txt +++ /dev/null @@ -1,46 +0,0 @@ -Bindings for the Broadcom's brcm,bcm6345-gpio memory-mapped GPIO controllers. - -These bindings can be used on any BCM63xx SoC. However, BCM6338 and BCM6345 -are the only ones which don't need a pinctrl driver. -BCM6338 have 8-bit data and dirout registers, where GPIO state can be read -and/or written, and the direction changed from input to output. -BCM6345 have 16-bit data and dirout registers, where GPIO state can be read -and/or written, and the direction changed from input to output. - -Required properties: - - compatible: should be "brcm,bcm6345-gpio" - - reg-names: must contain - "dat" - data register - "dirout" - direction (output) register - - reg: address + size pairs describing the GPIO register sets; - order must correspond with the order of entries in reg-names - - #gpio-cells: must be set to 2. The first cell is the pin number and - the second cell is used to specify the gpio polarity: - 0 = active high - 1 = active low - - gpio-controller: Marks the device node as a gpio controller. - -Optional properties: - - native-endian: use native endian memory. - -Examples: - - BCM6338: - gpio: gpio-controller@fffe0407 { - compatible = "brcm,bcm6345-gpio"; - reg-names = "dirout", "dat"; - reg = <0xfffe0407 1>, <0xfffe040f 1>; - - #gpio-cells = <2>; - gpio-controller; - }; - - - BCM6345: - gpio: gpio-controller@fffe0406 { - compatible = "brcm,bcm6345-gpio"; - reg-names = "dirout", "dat"; - reg = <0xfffe0406 2>, <0xfffe040a 2>; - native-endian; - - #gpio-cells = <2>; - gpio-controller; - }; diff --git a/Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml b/Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml new file mode 100644 index 000000000000..4d69f79df859 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/gpio/brcm,bcm6345-gpio.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6345 GPIO controller + +maintainers: + - Álvaro Fernández Rojas <noltari@gmail.com> + - Jonas Gorski <jonas.gorski@gmail.com> + +description: |+ + Bindings for Broadcom's BCM63xx memory-mapped GPIO controllers. + + These bindings can be used on any BCM63xx SoC. However, BCM6338 and BCM6345 + are the only ones which don't need a pinctrl driver. + + BCM6338 have 8-bit data and dirout registers, where GPIO state can be read + and/or written, and the direction changed from input to output. + BCM6345 have 16-bit data and dirout registers, where GPIO state can be read + and/or written, and the direction changed from input to output. + BCM6318, BCM6328, BCM6358, BCM6362, BCM6368 and BCM63268 have 32-bit data + and dirout registers, where GPIO state can be read and/or written, and the + direction changed from input to output. + +properties: + compatible: + enum: + - brcm,bcm6318-gpio + - brcm,bcm6328-gpio + - brcm,bcm6345-gpio + - brcm,bcm6358-gpio + - brcm,bcm6362-gpio + - brcm,bcm6368-gpio + - brcm,bcm63268-gpio + + gpio-controller: true + + "#gpio-cells": + const: 2 + + gpio-ranges: + maxItems: 1 + + native-endian: true + + reg: + maxItems: 2 + + reg-names: + items: + - const: dirout + - const: dat + +required: + - compatible + - reg + - reg-names + - gpio-controller + - '#gpio-cells' + +additionalProperties: false + +examples: + - | + gpio@fffe0406 { + compatible = "brcm,bcm6345-gpio"; + reg-names = "dirout", "dat"; + reg = <0xfffe0406 2>, <0xfffe040a 2>; + native-endian; + + gpio-controller; + #gpio-cells = <2>; + }; + + - | + gpio@0 { + compatible = "brcm,bcm63268-gpio"; + reg-names = "dirout", "dat"; + reg = <0x0 0x8>, <0x8 0x8>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 0 52>; + #gpio-cells = <2>; + }; diff --git a/Documentation/devicetree/bindings/mfd/brcm,bcm6318-gpio-sysctl.yaml b/Documentation/devicetree/bindings/mfd/brcm,bcm6318-gpio-sysctl.yaml new file mode 100644 index 000000000000..afc569bc15cf --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/brcm,bcm6318-gpio-sysctl.yaml @@ -0,0 +1,177 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/brcm,bcm6318-gpio-sysctl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6318 GPIO System Controller Device Tree Bindings + +maintainers: + - Álvaro Fernández Rojas <noltari@gmail.com> + - Jonas Gorski <jonas.gorski@gmail.com> + +description: + Broadcom BCM6318 SoC GPIO system controller which provides a register map + for controlling the GPIO and pins of the SoC. + +properties: + "#address-cells": true + + "#size-cells": true + + compatible: + items: + - const: brcm,bcm6318-gpio-sysctl + - const: syscon + - const: simple-mfd + + ranges: + maxItems: 1 + + reg: + maxItems: 1 + +patternProperties: + "^gpio@[0-9a-f]+$": + # Child node + type: object + $ref: "../gpio/brcm,bcm6345-gpio.yaml" + description: + GPIO controller for the SoC GPIOs. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml. + + "^pinctrl@[0-9a-f]+$": + # Child node + type: object + $ref: "../pinctrl/brcm,bcm6318-pinctrl.yaml" + description: + Pin controller for the SoC pins. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml. + +required: + - "#address-cells" + - compatible + - ranges + - reg + - "#size-cells" + +additionalProperties: false + +examples: + - | + syscon@10000080 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "brcm,bcm6318-gpio-sysctl", "syscon", "simple-mfd"; + reg = <0x10000080 0x80>; + ranges = <0 0x10000080 0x80>; + + gpio@0 { + compatible = "brcm,bcm6318-gpio"; + reg-names = "dirout", "dat"; + reg = <0x0 0x8>, <0x8 0x8>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 0 50>; + #gpio-cells = <2>; + }; + + pinctrl: pinctrl@10 { + compatible = "brcm,bcm6318-pinctrl"; + reg = <0x18 0x10>, <0x54 0x18>; + + pinctrl_ephy0_spd_led: ephy0_spd_led-pins { + function = "ephy0_spd_led"; + pins = "gpio0"; + }; + + pinctrl_ephy1_spd_led: ephy1_spd_led-pins { + function = "ephy1_spd_led"; + pins = "gpio1"; + }; + + pinctrl_ephy2_spd_led: ephy2_spd_led-pins { + function = "ephy2_spd_led"; + pins = "gpio2"; + }; + + pinctrl_ephy3_spd_led: ephy3_spd_led-pins { + function = "ephy3_spd_led"; + pins = "gpio3"; + }; + + pinctrl_ephy0_act_led: ephy0_act_led-pins { + function = "ephy0_act_led"; + pins = "gpio4"; + }; + + pinctrl_ephy1_act_led: ephy1_act_led-pins { + function = "ephy1_act_led"; + pins = "gpio5"; + }; + + pinctrl_ephy2_act_led: ephy2_act_led-pins { + function = "ephy2_act_led"; + pins = "gpio6"; + }; + + pinctrl_ephy3_act_led: ephy3_act_led-pins { + function = "ephy3_act_led"; + pins = "gpio7"; + }; + + pinctrl_serial_led: serial_led-pins { + pinctrl_serial_led_data: serial_led_data-pins { + function = "serial_led_data"; + pins = "gpio6"; + }; + + pinctrl_serial_led_clk: serial_led_clk-pins { + function = "serial_led_clk"; + pins = "gpio7"; + }; + }; + + pinctrl_inet_act_led: inet_act_led-pins { + function = "inet_act_led"; + pins = "gpio8"; + }; + + pinctrl_inet_fail_led: inet_fail_led-pins { + function = "inet_fail_led"; + pins = "gpio9"; + }; + + pinctrl_dsl_led: dsl_led-pins { + function = "dsl_led"; + pins = "gpio10"; + }; + + pinctrl_post_fail_led: post_fail_led-pins { + function = "post_fail_led"; + pins = "gpio11"; + }; + + pinctrl_wlan_wps_led: wlan_wps_led-pins { + function = "wlan_wps_led"; + pins = "gpio12"; + }; + + pinctrl_usb_pwron: usb_pwron-pins { + function = "usb_pwron"; + pins = "gpio13"; + }; + + pinctrl_usb_device_led: usb_device_led-pins { + function = "usb_device_led"; + pins = "gpio13"; + }; + + pinctrl_usb_active: usb_active-pins { + function = "usb_active"; + pins = "gpio40"; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/brcm,bcm63268-gpio-sysctl.yaml b/Documentation/devicetree/bindings/mfd/brcm,bcm63268-gpio-sysctl.yaml new file mode 100644 index 000000000000..c7771c86d7c1 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/brcm,bcm63268-gpio-sysctl.yaml @@ -0,0 +1,194 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/brcm,bcm63268-gpio-sysctl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM63268 GPIO System Controller Device Tree Bindings + +maintainers: + - Álvaro Fernández Rojas <noltari@gmail.com> + - Jonas Gorski <jonas.gorski@gmail.com> + +description: + Broadcom BCM63268 SoC GPIO system controller which provides a register map + for controlling the GPIO and pins of the SoC. + +properties: + "#address-cells": true + + "#size-cells": true + + compatible: + items: + - const: brcm,bcm63268-gpio-sysctl + - const: syscon + - const: simple-mfd + + ranges: + maxItems: 1 + + reg: + maxItems: 1 + +patternProperties: + "^gpio@[0-9a-f]+$": + # Child node + type: object + $ref: "../gpio/brcm,bcm6345-gpio.yaml" + description: + GPIO controller for the SoC GPIOs. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml. + + "^pinctrl@[0-9a-f]+$": + # Child node + type: object + $ref: "../pinctrl/brcm,bcm63268-pinctrl.yaml" + description: + Pin controller for the SoC pins. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml. + +required: + - "#address-cells" + - compatible + - ranges + - reg + - "#size-cells" + +additionalProperties: false + +examples: + - | + syscon@100000c0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "brcm,bcm63268-gpio-sysctl", "syscon", "simple-mfd"; + reg = <0x100000c0 0x80>; + ranges = <0 0x100000c0 0x80>; + + gpio@0 { + compatible = "brcm,bcm63268-gpio"; + reg-names = "dirout", "dat"; + reg = <0x0 0x8>, <0x8 0x8>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 0 52>; + #gpio-cells = <2>; + }; + + pinctrl: pinctrl@10 { + compatible = "brcm,bcm63268-pinctrl"; + reg = <0x10 0x4>, <0x18 0x8>, <0x38 0x4>; + + pinctrl_serial_led: serial_led-pins { + pinctrl_serial_led_clk: serial_led_clk-pins { + function = "serial_led_clk"; + pins = "gpio0"; + }; + + pinctrl_serial_led_data: serial_led_data-pins { + function = "serial_led_data"; + pins = "gpio1"; + }; + }; + + pinctrl_hsspi_cs4: hsspi_cs4-pins { + function = "hsspi_cs4"; + pins = "gpio16"; + }; + + pinctrl_hsspi_cs5: hsspi_cs5-pins { + function = "hsspi_cs5"; + pins = "gpio17"; + }; + + pinctrl_hsspi_cs6: hsspi_cs6-pins { + function = "hsspi_cs6"; + pins = "gpio8"; + }; + + pinctrl_hsspi_cs7: hsspi_cs7-pins { + function = "hsspi_cs7"; + pins = "gpio9"; + }; + + pinctrl_adsl_spi: adsl_spi-pins { + pinctrl_adsl_spi_miso: adsl_spi_miso-pins { + function = "adsl_spi_miso"; + pins = "gpio18"; + }; + + pinctrl_adsl_spi_mosi: adsl_spi_mosi-pins { + function = "adsl_spi_mosi"; + pins = "gpio19"; + }; + }; + + pinctrl_vreq_clk: vreq_clk-pins { + function = "vreq_clk"; + pins = "gpio22"; + }; + + pinctrl_pcie_clkreq_b: pcie_clkreq_b-pins { + function = "pcie_clkreq_b"; + pins = "gpio23"; + }; + + pinctrl_robosw_led_clk: robosw_led_clk-pins { + function = "robosw_led_clk"; + pins = "gpio30"; + }; + + pinctrl_robosw_led_data: robosw_led_data-pins { + function = "robosw_led_data"; + pins = "gpio31"; + }; + + pinctrl_nand: nand-pins { + function = "nand"; + group = "nand_grp"; + }; + + pinctrl_gpio35_alt: gpio35_alt-pins { + function = "gpio35_alt"; + pin = "gpio35"; + }; + + pinctrl_dectpd: dectpd-pins { + function = "dectpd"; + group = "dectpd_grp"; + }; + + pinctrl_vdsl_phy_override_0: vdsl_phy_override_0-pins { + function = "vdsl_phy_override_0"; + group = "vdsl_phy_override_0_grp"; + }; + + pinctrl_vdsl_phy_override_1: vdsl_phy_override_1-pins { + function = "vdsl_phy_override_1"; + group = "vdsl_phy_override_1_grp"; + }; + + pinctrl_vdsl_phy_override_2: vdsl_phy_override_2-pins { + function = "vdsl_phy_override_2"; + group = "vdsl_phy_override_2_grp"; + }; + + pinctrl_vdsl_phy_override_3: vdsl_phy_override_3-pins { + function = "vdsl_phy_override_3"; + group = "vdsl_phy_override_3_grp"; + }; + + pinctrl_dsl_gpio8: dsl_gpio8-pins { + function = "dsl_gpio8"; + group = "dsl_gpio8"; + }; + + pinctrl_dsl_gpio9: dsl_gpio9-pins { + function = "dsl_gpio9"; + group = "dsl_gpio9"; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/brcm,bcm6328-gpio-sysctl.yaml b/Documentation/devicetree/bindings/mfd/brcm,bcm6328-gpio-sysctl.yaml new file mode 100644 index 000000000000..33963c11ae62 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/brcm,bcm6328-gpio-sysctl.yaml @@ -0,0 +1,162 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/brcm,bcm6328-gpio-sysctl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6328 GPIO System Controller Device Tree Bindings + +maintainers: + - Álvaro Fernández Rojas <noltari@gmail.com> + - Jonas Gorski <jonas.gorski@gmail.com> + +description: + Broadcom BCM6328 SoC GPIO system controller which provides a register map + for controlling the GPIO and pins of the SoC. + +properties: + "#address-cells": true + + "#size-cells": true + + compatible: + items: + - const: brcm,bcm6328-gpio-sysctl + - const: syscon + - const: simple-mfd + + ranges: + maxItems: 1 + + reg: + maxItems: 1 + +patternProperties: + "^gpio@[0-9a-f]+$": + # Child node + type: object + $ref: "../gpio/brcm,bcm6345-gpio.yaml" + description: + GPIO controller for the SoC GPIOs. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml. + + "^pinctrl@[0-9a-f]+$": + # Child node + type: object + $ref: "../pinctrl/brcm,bcm6328-pinctrl.yaml" + description: + Pin controller for the SoC pins. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml. + +required: + - "#address-cells" + - compatible + - ranges + - reg + - "#size-cells" + +additionalProperties: false + +examples: + - | + syscon@10000080 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "brcm,bcm6328-gpio-sysctl", "syscon", "simple-mfd"; + reg = <0x10000080 0x80>; + ranges = <0 0x10000080 0x80>; + + gpio@0 { + compatible = "brcm,bcm6328-gpio"; + reg-names = "dirout", "dat"; + reg = <0x0 0x8>, <0x8 0x8>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 0 32>; + #gpio-cells = <2>; + }; + + pinctrl: pinctrl@18 { + compatible = "brcm,bcm6328-pinctrl"; + reg = <0x18 0x10>; + + pinctrl_serial_led: serial_led-pins { + pinctrl_serial_led_data: serial_led_data-pins { + function = "serial_led_data"; + pins = "gpio6"; + }; + + pinctrl_serial_led_clk: serial_led_clk-pins { + function = "serial_led_clk"; + pins = "gpio7"; + }; + }; + + pinctrl_inet_act_led: inet_act_led-pins { + function = "inet_act_led"; + pins = "gpio11"; + }; + + pinctrl_pcie_clkreq: pcie_clkreq-pins { + function = "pcie_clkreq"; + pins = "gpio16"; + }; + + pinctrl_ephy0_spd_led: ephy0_spd_led-pins { + function = "led"; + pins = "gpio17"; + }; + + pinctrl_ephy1_spd_led: ephy1_spd_led-pins { + function = "led"; + pins = "gpio18"; + }; + + pinctrl_ephy2_spd_led: ephy2_spd_led-pins { + function = "led"; + pins = "gpio19"; + }; + + pinctrl_ephy3_spd_led: ephy3_spd_led-pins { + function = "led"; + pins = "gpio20"; + }; + + pinctrl_ephy0_act_led: ephy0_act_led-pins { + function = "ephy0_act_led"; + pins = "gpio25"; + }; + + pinctrl_ephy1_act_led: ephy1_act_led-pins { + function = "ephy1_act_led"; + pins = "gpio26"; + }; + + pinctrl_ephy2_act_led: ephy2_act_led-pins { + function = "ephy2_act_led"; + pins = "gpio27"; + }; + + pinctrl_ephy3_act_led: ephy3_act_led-pins { + function = "ephy3_act_led"; + pins = "gpio28"; + }; + + pinctrl_hsspi_cs1: hsspi_cs1-pins { + function = "hsspi_cs1"; + pins = "hsspi_cs1"; + }; + + pinctrl_usb_port1_device: usb_port1_device-pins { + function = "usb_device_port"; + pins = "usb_port1"; + }; + + pinctrl_usb_port1_host: usb_port1_host-pins { + function = "usb_host_port"; + pins = "usb_port1"; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/brcm,bcm6358-gpio-sysctl.yaml b/Documentation/devicetree/bindings/mfd/brcm,bcm6358-gpio-sysctl.yaml new file mode 100644 index 000000000000..3e44bea78b03 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/brcm,bcm6358-gpio-sysctl.yaml @@ -0,0 +1,130 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/brcm,bcm6358-gpio-sysctl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6358 GPIO System Controller Device Tree Bindings + +maintainers: + - Álvaro Fernández Rojas <noltari@gmail.com> + - Jonas Gorski <jonas.gorski@gmail.com> + +description: + Broadcom BCM6358 SoC GPIO system controller which provides a register map + for controlling the GPIO and pins of the SoC. + +properties: + "#address-cells": true + + "#size-cells": true + + compatible: + items: + - const: brcm,bcm6358-gpio-sysctl + - const: syscon + - const: simple-mfd + + ranges: + maxItems: 1 + + reg: + maxItems: 1 + +patternProperties: + "^gpio@[0-9a-f]+$": + # Child node + type: object + $ref: "../gpio/brcm,bcm6345-gpio.yaml" + description: + GPIO controller for the SoC GPIOs. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml. + + "^pinctrl@[0-9a-f]+$": + # Child node + type: object + $ref: "../pinctrl/brcm,bcm6358-pinctrl.yaml" + description: + Pin controller for the SoC pins. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml. + +required: + - "#address-cells" + - compatible + - ranges + - reg + - "#size-cells" + +additionalProperties: false + +examples: + - | + syscon@fffe0080 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "brcm,bcm6358-gpio-sysctl", "syscon", "simple-mfd"; + reg = <0xfffe0080 0x80>; + ranges = <0 0xfffe0080 0x80>; + + gpio@0 { + compatible = "brcm,bcm6358-gpio"; + reg-names = "dirout", "dat"; + reg = <0x0 0x8>, <0x8 0x8>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 0 40>; + #gpio-cells = <2>; + }; + + pinctrl: pinctrl@18 { + compatible = "brcm,bcm6358-pinctrl"; + reg = <0x18 0x4>; + + pinctrl_ebi_cs: ebi_cs-pins { + function = "ebi_cs"; + groups = "ebi_cs_grp"; + }; + + pinctrl_uart1: uart1-pins { + function = "uart1"; + groups = "uart1_grp"; + }; + + pinctrl_serial_led: serial_led-pins { + function = "serial_led"; + groups = "serial_led_grp"; + }; + + pinctrl_legacy_led: legacy_led-pins { + function = "legacy_led"; + groups = "legacy_led_grp"; + }; + + pinctrl_led: led-pins { + function = "led"; + groups = "led_grp"; + }; + + pinctrl_spi_cs_23: spi_cs-pins { + function = "spi_cs"; + groups = "spi_cs_grp"; + }; + + pinctrl_utopia: utopia-pins { + function = "utopia"; + groups = "utopia_grp"; + }; + + pinctrl_pwm_syn_clk: pwm_syn_clk-pins { + function = "pwm_syn_clk"; + groups = "pwm_syn_clk_grp"; + }; + + pinctrl_sys_irq: sys_irq-pins { + function = "sys_irq"; + groups = "sys_irq_grp"; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/brcm,bcm6362-gpio-sysctl.yaml b/Documentation/devicetree/bindings/mfd/brcm,bcm6362-gpio-sysctl.yaml new file mode 100644 index 000000000000..48d14a5fe0d5 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/brcm,bcm6362-gpio-sysctl.yaml @@ -0,0 +1,236 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/brcm,bcm6362-gpio-sysctl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6362 GPIO System Controller Device Tree Bindings + +maintainers: + - Álvaro Fernández Rojas <noltari@gmail.com> + - Jonas Gorski <jonas.gorski@gmail.com> + +description: + Broadcom BCM6362 SoC GPIO system controller which provides a register map + for controlling the GPIO and pins of the SoC. + +properties: + "#address-cells": true + + "#size-cells": true + + compatible: + items: + - const: brcm,bcm6362-gpio-sysctl + - const: syscon + - const: simple-mfd + + ranges: + maxItems: 1 + + reg: + maxItems: 1 + +patternProperties: + "^gpio@[0-9a-f]+$": + # Child node + type: object + $ref: "../gpio/brcm,bcm6345-gpio.yaml" + description: + GPIO controller for the SoC GPIOs. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml. + + "^pinctrl@[0-9a-f]+$": + # Child node + type: object + $ref: "../pinctrl/brcm,bcm6362-pinctrl.yaml" + description: + Pin controller for the SoC pins. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml. + +required: + - "#address-cells" + - compatible + - ranges + - reg + - "#size-cells" + +additionalProperties: false + +examples: + - | + syscon@10000080 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "brcm,bcm6362-gpio-sysctl", "syscon", "simple-mfd"; + reg = <0x10000080 0x80>; + ranges = <0 0x10000080 0x80>; + + gpio@0 { + compatible = "brcm,bcm6362-gpio"; + reg-names = "dirout", "dat"; + reg = <0x0 0x8>, <0x8 0x8>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 0 48>; + #gpio-cells = <2>; + }; + + pinctrl: pinctrl@18 { + compatible = "brcm,bcm6362-pinctrl"; + reg = <0x18 0x10>, <0x38 0x4>; + + pinctrl_usb_device_led: usb_device_led-pins { + function = "usb_device_led"; + pins = "gpio0"; + }; + + pinctrl_sys_irq: sys_irq-pins { + function = "sys_irq"; + pins = "gpio1"; + }; + + pinctrl_serial_led: serial_led-pins { + pinctrl_serial_led_clk: serial_led_clk-pins { + function = "serial_led_clk"; + pins = "gpio2"; + }; + + pinctrl_serial_led_data: serial_led_data-pins { + function = "serial_led_data"; + pins = "gpio3"; + }; + }; + + pinctrl_robosw_led_data: robosw_led_data-pins { + function = "robosw_led_data"; + pins = "gpio4"; + }; + + pinctrl_robosw_led_clk: robosw_led_clk-pins { + function = "robosw_led_clk"; + pins = "gpio5"; + }; + + pinctrl_robosw_led0: robosw_led0-pins { + function = "robosw_led0"; + pins = "gpio6"; + }; + + pinctrl_robosw_led1: robosw_led1-pins { + function = "robosw_led1"; + pins = "gpio7"; + }; + + pinctrl_inet_led: inet_led-pins { + function = "inet_led"; + pins = "gpio8"; + }; + + pinctrl_spi_cs2: spi_cs2-pins { + function = "spi_cs2"; + pins = "gpio9"; + }; + + pinctrl_spi_cs3: spi_cs3-pins { + function = "spi_cs3"; + pins = "gpio10"; + }; + + pinctrl_ntr_pulse: ntr_pulse-pins { + function = "ntr_pulse"; + pins = "gpio11"; + }; + + pinctrl_uart1_scts: uart1_scts-pins { + function = "uart1_scts"; + pins = "gpio12"; + }; + + pinctrl_uart1_srts: uart1_srts-pins { + function = "uart1_srts"; + pins = "gpio13"; + }; + + pinctrl_uart1: uart1-pins { + pinctrl_uart1_sdin: uart1_sdin-pins { + function = "uart1_sdin"; + pins = "gpio14"; + }; + + pinctrl_uart1_sdout: uart1_sdout-pins { + function = "uart1_sdout"; + pins = "gpio15"; + }; + }; + + pinctrl_adsl_spi: adsl_spi-pins { + pinctrl_adsl_spi_miso: adsl_spi_miso-pins { + function = "adsl_spi_miso"; + pins = "gpio16"; + }; + + pinctrl_adsl_spi_mosi: adsl_spi_mosi-pins { + function = "adsl_spi_mosi"; + pins = "gpio17"; + }; + + pinctrl_adsl_spi_clk: adsl_spi_clk-pins { + function = "adsl_spi_clk"; + pins = "gpio18"; + }; + + pinctrl_adsl_spi_cs: adsl_spi_cs-pins { + function = "adsl_spi_cs"; + pins = "gpio19"; + }; + }; + + pinctrl_ephy0_led: ephy0_led-pins { + function = "ephy0_led"; + pins = "gpio20"; + }; + + pinctrl_ephy1_led: ephy1_led-pins { + function = "ephy1_led"; + pins = "gpio21"; + }; + + pinctrl_ephy2_led: ephy2_led-pins { + function = "ephy2_led"; + pins = "gpio22"; + }; + + pinctrl_ephy3_led: ephy3_led-pins { + function = "ephy3_led"; + pins = "gpio23"; + }; + + pinctrl_ext_irq0: ext_irq0-pins { + function = "ext_irq0"; + pins = "gpio24"; + }; + + pinctrl_ext_irq1: ext_irq1-pins { + function = "ext_irq1"; + pins = "gpio25"; + }; + + pinctrl_ext_irq2: ext_irq2-pins { + function = "ext_irq2"; + pins = "gpio26"; + }; + + pinctrl_ext_irq3: ext_irq3-pins { + function = "ext_irq3"; + pins = "gpio27"; + }; + + pinctrl_nand: nand-pins { + function = "nand"; + group = "nand_grp"; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/brcm,bcm6368-gpio-sysctl.yaml b/Documentation/devicetree/bindings/mfd/brcm,bcm6368-gpio-sysctl.yaml new file mode 100644 index 000000000000..307270b0cfed --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/brcm,bcm6368-gpio-sysctl.yaml @@ -0,0 +1,246 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/brcm,bcm6368-gpio-sysctl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6368 GPIO System Controller Device Tree Bindings + +maintainers: + - Álvaro Fernández Rojas <noltari@gmail.com> + - Jonas Gorski <jonas.gorski@gmail.com> + +description: + Broadcom BCM6368 SoC GPIO system controller which provides a register map + for controlling the GPIO and pins of the SoC. + +properties: + "#address-cells": true + + "#size-cells": true + + compatible: + items: + - const: brcm,bcm6368-gpio-sysctl + - const: syscon + - const: simple-mfd + + ranges: + maxItems: 1 + + reg: + maxItems: 1 + +patternProperties: + "^gpio@[0-9a-f]+$": + # Child node + type: object + $ref: "../gpio/brcm,bcm6345-gpio.yaml" + description: + GPIO controller for the SoC GPIOs. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml. + + "^pinctrl@[0-9a-f]+$": + # Child node + type: object + $ref: "../pinctrl/brcm,bcm6368-pinctrl.yaml" + description: + Pin controller for the SoC pins. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml. + +required: + - "#address-cells" + - compatible + - ranges + - reg + - "#size-cells" + +additionalProperties: false + +examples: + - | + syscon@10000080 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "brcm,bcm6368-gpio-sysctl", "syscon", "simple-mfd"; + reg = <0x10000080 0x80>; + ranges = <0 0x10000080 0x80>; + + gpio@0 { + compatible = "brcm,bcm6368-gpio"; + reg-names = "dirout", "dat"; + reg = <0x0 0x8>, <0x8 0x8>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 0 38>; + #gpio-cells = <2>; + }; + + pinctrl: pinctrl@18 { + compatible = "brcm,bcm6368-pinctrl"; + reg = <0x18 0x4>, <0x38 0x4>; + + pinctrl_analog_afe_0: analog_afe_0-pins { + function = "analog_afe_0"; + pins = "gpio0"; + }; + + pinctrl_analog_afe_1: analog_afe_1-pins { + function = "analog_afe_1"; + pins = "gpio1"; + }; + + pinctrl_sys_irq: sys_irq-pins { + function = "sys_irq"; + pins = "gpio2"; + }; + + pinctrl_serial_led: serial_led-pins { + pinctrl_serial_led_data: serial_led_data-pins { + function = "serial_led_data"; + pins = "gpio3"; + }; + + pinctrl_serial_led_clk: serial_led_clk-pins { + function = "serial_led_clk"; + pins = "gpio4"; + }; + }; + + pinctrl_inet_led: inet_led-pins { + function = "inet_led"; + pins = "gpio5"; + }; + + pinctrl_ephy0_led: ephy0_led-pins { + function = "ephy0_led"; + pins = "gpio6"; + }; + + pinctrl_ephy1_led: ephy1_led-pins { + function = "ephy1_led"; + pins = "gpio7"; + }; + + pinctrl_ephy2_led: ephy2_led-pins { + function = "ephy2_led"; + pins = "gpio8"; + }; + + pinctrl_ephy3_led: ephy3_led-pins { + function = "ephy3_led"; + pins = "gpio9"; + }; + + pinctrl_robosw_led_data: robosw_led_data-pins { + function = "robosw_led_data"; + pins = "gpio10"; + }; + + pinctrl_robosw_led_clk: robosw_led_clk-pins { + function = "robosw_led_clk"; + pins = "gpio11"; + }; + + pinctrl_robosw_led0: robosw_led0-pins { + function = "robosw_led0"; + pins = "gpio12"; + }; + + pinctrl_robosw_led1: robosw_led1-pins { + function = "robosw_led1"; + pins = "gpio13"; + }; + + pinctrl_usb_device_led: usb_device_led-pins { + function = "usb_device_led"; + pins = "gpio14"; + }; + + pinctrl_pci: pci-pins { + pinctrl_pci_req1: pci_req1-pins { + function = "pci_req1"; + pins = "gpio16"; + }; + + pinctrl_pci_gnt1: pci_gnt1-pins { + function = "pci_gnt1"; + pins = "gpio17"; + }; + + pinctrl_pci_intb: pci_intb-pins { + function = "pci_intb"; + pins = "gpio18"; + }; + + pinctrl_pci_req0: pci_req0-pins { + function = "pci_req0"; + pins = "gpio19"; + }; + + pinctrl_pci_gnt0: pci_gnt0-pins { + function = "pci_gnt0"; + pins = "gpio20"; + }; + }; + + pinctrl_pcmcia: pcmcia-pins { + pinctrl_pcmcia_cd1: pcmcia_cd1-pins { + function = "pcmcia_cd1"; + pins = "gpio22"; + }; + + pinctrl_pcmcia_cd2: pcmcia_cd2-pins { + function = "pcmcia_cd2"; + pins = "gpio23"; + }; + + pinctrl_pcmcia_vs1: pcmcia_vs1-pins { + function = "pcmcia_vs1"; + pins = "gpio24"; + }; + + pinctrl_pcmcia_vs2: pcmcia_vs2-pins { + function = "pcmcia_vs2"; + pins = "gpio25"; + }; + }; + + pinctrl_ebi_cs2: ebi_cs2-pins { + function = "ebi_cs2"; + pins = "gpio26"; + }; + + pinctrl_ebi_cs3: ebi_cs3-pins { + function = "ebi_cs3"; + pins = "gpio27"; + }; + + pinctrl_spi_cs2: spi_cs2-pins { + function = "spi_cs2"; + pins = "gpio28"; + }; + + pinctrl_spi_cs3: spi_cs3-pins { + function = "spi_cs3"; + pins = "gpio29"; + }; + + pinctrl_spi_cs4: spi_cs4-pins { + function = "spi_cs4"; + pins = "gpio30"; + }; + + pinctrl_spi_cs5: spi_cs5-pins { + function = "spi_cs5"; + pins = "gpio31"; + }; + + pinctrl_uart1: uart1-pins { + function = "uart1"; + group = "uart1_grp"; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml new file mode 100644 index 000000000000..08995a4f854b --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml @@ -0,0 +1,143 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6318-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6318 pin controller + +maintainers: + - Álvaro Fernández Rojas <noltari@gmail.com> + - Jonas Gorski <jonas.gorski@gmail.com> + +description: + Bindings for Broadcom's BCM6318 memory-mapped pin controller. + +properties: + compatible: + const: brcm,bcm6318-pinctrl + + reg: + maxItems: 2 + +patternProperties: + '-pins$': + type: object + $ref: pinmux-node.yaml# + + properties: + function: + enum: [ ephy0_spd_led, ephy1_spd_led, ephy2_spd_led, ephy3_spd_led, + ephy0_act_led, ephy1_act_led, ephy2_act_led, ephy3_act_led, + serial_led_data, serial_led_clk, inet_act_led, inet_fail_led, + dsl_led, post_fail_led, wlan_wps_led, usb_pwron, + usb_device_led, usb_active ] + + pins: + enum: [ gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7, + gpio8, gpio9, gpio10, gpio11, gpio12, gpio13, gpio40 ] + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + pinctrl@18 { + compatible = "brcm,bcm6318-pinctrl"; + reg = <0x18 0x10>, <0x54 0x18>; + + pinctrl_ephy0_spd_led: ephy0_spd_led-pins { + function = "ephy0_spd_led"; + pins = "gpio0"; + }; + + pinctrl_ephy1_spd_led: ephy1_spd_led-pins { + function = "ephy1_spd_led"; + pins = "gpio1"; + }; + + pinctrl_ephy2_spd_led: ephy2_spd_led-pins { + function = "ephy2_spd_led"; + pins = "gpio2"; + }; + + pinctrl_ephy3_spd_led: ephy3_spd_led-pins { + function = "ephy3_spd_led"; + pins = "gpio3"; + }; + + pinctrl_ephy0_act_led: ephy0_act_led-pins { + function = "ephy0_act_led"; + pins = "gpio4"; + }; + + pinctrl_ephy1_act_led: ephy1_act_led-pins { + function = "ephy1_act_led"; + pins = "gpio5"; + }; + + pinctrl_ephy2_act_led: ephy2_act_led-pins { + function = "ephy2_act_led"; + pins = "gpio6"; + }; + + pinctrl_ephy3_act_led: ephy3_act_led-pins { + function = "ephy3_act_led"; + pins = "gpio7"; + }; + + pinctrl_serial_led: serial_led-pins { + pinctrl_serial_led_data: serial_led_data-pins { + function = "serial_led_data"; + pins = "gpio6"; + }; + + pinctrl_serial_led_clk: serial_led_clk-pins { + function = "serial_led_clk"; + pins = "gpio7"; + }; + }; + + pinctrl_inet_act_led: inet_act_led-pins { + function = "inet_act_led"; + pins = "gpio8"; + }; + + pinctrl_inet_fail_led: inet_fail_led-pins { + function = "inet_fail_led"; + pins = "gpio9"; + }; + + pinctrl_dsl_led: dsl_led-pins { + function = "dsl_led"; + pins = "gpio10"; + }; + + pinctrl_post_fail_led: post_fail_led-pins { + function = "post_fail_led"; + pins = "gpio11"; + }; + + pinctrl_wlan_wps_led: wlan_wps_led-pins { + function = "wlan_wps_led"; + pins = "gpio12"; + }; + + pinctrl_usb_pwron: usb_pwron-pins { + function = "usb_pwron"; + pins = "gpio13"; + }; + + pinctrl_usb_device_led: usb_device_led-pins { + function = "usb_device_led"; + pins = "gpio13"; + }; + + pinctrl_usb_active: usb_active-pins { + function = "usb_active"; + pins = "gpio40"; + }; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml new file mode 100644 index 000000000000..58ffed44b3c4 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml @@ -0,0 +1,164 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm63268-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM63268 pin controller + +maintainers: + - Álvaro Fernández Rojas <noltari@gmail.com> + - Jonas Gorski <jonas.gorski@gmail.com> + +description: + Bindings for Broadcom's BCM63268 memory-mapped pin controller. + +properties: + compatible: + const: brcm,bcm63268-pinctrl + + reg: + maxItems: 3 + +patternProperties: + '-pins$': + type: object + $ref: pinmux-node.yaml# + + properties: + function: + enum: [ serial_led_clk, serial_led_data, hsspi_cs4, hsspi_cs5, + hsspi_cs6, hsspi_cs7, adsl_spi_miso, adsl_spi_mosi, + vreq_clk, pcie_clkreq_b, robosw_led_clk, robosw_led_data, + nand, gpio35_alt, dectpd, vdsl_phy_override_0, + vdsl_phy_override_1, vdsl_phy_override_2, + vdsl_phy_override_3, dsl_gpio8, dsl_gpio9 ] + + pins: + enum: [ gpio0, gpio1, gpio16, gpio17, gpio8, gpio9, gpio18, gpio19, + gpio22, gpio23, gpio30, gpio31, nand_grp, gpio35 + dectpd_grp, vdsl_phy_override_0_grp, + vdsl_phy_override_1_grp, vdsl_phy_override_2_grp, + vdsl_phy_override_3_grp, dsl_gpio8, dsl_gpio9 ] + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + pinctrl@10 { + compatible = "brcm,bcm63268-pinctrl"; + reg = <0x10 0x4>, <0x18 0x8>, <0x38 0x4>; + + pinctrl_serial_led: serial_led-pins { + pinctrl_serial_led_clk: serial_led_clk-pins { + function = "serial_led_clk"; + pins = "gpio0"; + }; + + pinctrl_serial_led_data: serial_led_data-pins { + function = "serial_led_data"; + pins = "gpio1"; + }; + }; + + pinctrl_hsspi_cs4: hsspi_cs4-pins { + function = "hsspi_cs4"; + pins = "gpio16"; + }; + + pinctrl_hsspi_cs5: hsspi_cs5-pins { + function = "hsspi_cs5"; + pins = "gpio17"; + }; + + pinctrl_hsspi_cs6: hsspi_cs6-pins { + function = "hsspi_cs6"; + pins = "gpio8"; + }; + + pinctrl_hsspi_cs7: hsspi_cs7-pins { + function = "hsspi_cs7"; + pins = "gpio9"; + }; + + pinctrl_adsl_spi: adsl_spi-pins { + pinctrl_adsl_spi_miso: adsl_spi_miso-pins { + function = "adsl_spi_miso"; + pins = "gpio18"; + }; + + pinctrl_adsl_spi_mosi: adsl_spi_mosi-pins { + function = "adsl_spi_mosi"; + pins = "gpio19"; + }; + }; + + pinctrl_vreq_clk: vreq_clk-pins { + function = "vreq_clk"; + pins = "gpio22"; + }; + + pinctrl_pcie_clkreq_b: pcie_clkreq_b-pins { + function = "pcie_clkreq_b"; + pins = "gpio23"; + }; + + pinctrl_robosw_led_clk: robosw_led_clk-pins { + function = "robosw_led_clk"; + pins = "gpio30"; + }; + + pinctrl_robosw_led_data: robosw_led_data-pins { + function = "robosw_led_data"; + pins = "gpio31"; + }; + + pinctrl_nand: nand-pins { + function = "nand"; + group = "nand_grp"; + }; + + pinctrl_gpio35_alt: gpio35_alt-pins { + function = "gpio35_alt"; + pin = "gpio35"; + }; + + pinctrl_dectpd: dectpd-pins { + function = "dectpd"; + group = "dectpd_grp"; + }; + + pinctrl_vdsl_phy_override_0: vdsl_phy_override_0-pins { + function = "vdsl_phy_override_0"; + group = "vdsl_phy_override_0_grp"; + }; + + pinctrl_vdsl_phy_override_1: vdsl_phy_override_1-pins { + function = "vdsl_phy_override_1"; + group = "vdsl_phy_override_1_grp"; + }; + + pinctrl_vdsl_phy_override_2: vdsl_phy_override_2-pins { + function = "vdsl_phy_override_2"; + group = "vdsl_phy_override_2_grp"; + }; + + pinctrl_vdsl_phy_override_3: vdsl_phy_override_3-pins { + function = "vdsl_phy_override_3"; + group = "vdsl_phy_override_3_grp"; + }; + + pinctrl_dsl_gpio8: dsl_gpio8-pins { + function = "dsl_gpio8"; + group = "dsl_gpio8"; + }; + + pinctrl_dsl_gpio9: dsl_gpio9-pins { + function = "dsl_gpio9"; + group = "dsl_gpio9"; + }; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml new file mode 100644 index 000000000000..0fd24f40afb1 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml @@ -0,0 +1,127 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6328-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6328 pin controller + +maintainers: + - Álvaro Fernández Rojas <noltari@gmail.com> + - Jonas Gorski <jonas.gorski@gmail.com> + +description: + Bindings for Broadcom's BCM6328 memory-mapped pin controller. + +properties: + compatible: + const: brcm,bcm6328-pinctrl + + reg: + maxItems: 1 + +patternProperties: + '-pins$': + type: object + $ref: pinmux-node.yaml# + + properties: + function: + enum: [ serial_led_data, serial_led_clk, inet_act_led, pcie_clkreq, + led, ephy0_act_led, ephy1_act_led, ephy2_act_led, + ephy3_act_led, hsspi_cs1, usb_device_port, usb_host_port ] + + pins: + enum: [ gpio6, gpio7, gpio11, gpio16, gpio17, gpio18, gpio19, + gpio20, gpio25, gpio26, gpio27, gpio28, hsspi_cs1, + usb_port1 ] + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + pinctrl@18 { + compatible = "brcm,bcm6328-pinctrl"; + reg = <0x18 0x10>; + + pinctrl_serial_led: serial_led-pins { + pinctrl_serial_led_data: serial_led_data-pins { + function = "serial_led_data"; + pins = "gpio6"; + }; + + pinctrl_serial_led_clk: serial_led_clk-pins { + function = "serial_led_clk"; + pins = "gpio7"; + }; + }; + + pinctrl_inet_act_led: inet_act_led-pins { + function = "inet_act_led"; + pins = "gpio11"; + }; + + pinctrl_pcie_clkreq: pcie_clkreq-pins { + function = "pcie_clkreq"; + pins = "gpio16"; + }; + + pinctrl_ephy0_spd_led: ephy0_spd_led-pins { + function = "led"; + pins = "gpio17"; + }; + + pinctrl_ephy1_spd_led: ephy1_spd_led-pins { + function = "led"; + pins = "gpio18"; + }; + + pinctrl_ephy2_spd_led: ephy2_spd_led-pins { + function = "led"; + pins = "gpio19"; + }; + + pinctrl_ephy3_spd_led: ephy3_spd_led-pins { + function = "led"; + pins = "gpio20"; + }; + + pinctrl_ephy0_act_led: ephy0_act_led-pins { + function = "ephy0_act_led"; + pins = "gpio25"; + }; + + pinctrl_ephy1_act_led: ephy1_act_led-pins { + function = "ephy1_act_led"; + pins = "gpio26"; + }; + + pinctrl_ephy2_act_led: ephy2_act_led-pins { + function = "ephy2_act_led"; + pins = "gpio27"; + }; + + pinctrl_ephy3_act_led: ephy3_act_led-pins { + function = "ephy3_act_led"; + pins = "gpio28"; + }; + + pinctrl_hsspi_cs1: hsspi_cs1-pins { + function = "hsspi_cs1"; + pins = "hsspi_cs1"; + }; + + pinctrl_usb_port1_device: usb_port1_device-pins { + function = "usb_device_port"; + pins = "usb_port1"; + }; + + pinctrl_usb_port1_host: usb_port1_host-pins { + function = "usb_host_port"; + pins = "usb_port1"; + }; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml new file mode 100644 index 000000000000..0c3ce256aa78 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml @@ -0,0 +1,93 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6358-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6358 pin controller + +maintainers: + - Álvaro Fernández Rojas <noltari@gmail.com> + - Jonas Gorski <jonas.gorski@gmail.com> + +description: + Bindings for Broadcom's BCM6358 memory-mapped pin controller. + +properties: + compatible: + const: brcm,bcm6358-pinctrl + + reg: + maxItems: 1 + +patternProperties: + '-pins$': + type: object + $ref: pinmux-node.yaml# + + properties: + function: + enum: [ ebi_cs, uart1, serial_led, legacy_led, led, spi_cs, utopia, + pwm_syn_clk, sys_irq ] + + pins: + enum: [ ebi_cs_grp, uart1_grp, serial_led_grp, legacy_led_grp, + led_grp, spi_cs_grp, utopia_grp, pwm_syn_clk, sys_irq_grp ] + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + pinctrl@18 { + compatible = "brcm,bcm6358-pinctrl"; + reg = <0x18 0x4>; + + pinctrl_ebi_cs: ebi_cs-pins { + function = "ebi_cs"; + groups = "ebi_cs_grp"; + }; + + pinctrl_uart1: uart1-pins { + function = "uart1"; + groups = "uart1_grp"; + }; + + pinctrl_serial_led: serial_led-pins { + function = "serial_led"; + groups = "serial_led_grp"; + }; + + pinctrl_legacy_led: legacy_led-pins { + function = "legacy_led"; + groups = "legacy_led_grp"; + }; + + pinctrl_led: led-pins { + function = "led"; + groups = "led_grp"; + }; + + pinctrl_spi_cs_23: spi_cs-pins { + function = "spi_cs"; + groups = "spi_cs_grp"; + }; + + pinctrl_utopia: utopia-pins { + function = "utopia"; + groups = "utopia_grp"; + }; + + pinctrl_pwm_syn_clk: pwm_syn_clk-pins { + function = "pwm_syn_clk"; + groups = "pwm_syn_clk_grp"; + }; + + pinctrl_sys_irq: sys_irq-pins { + function = "sys_irq"; + groups = "sys_irq_grp"; + }; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml new file mode 100644 index 000000000000..6f68fee373bd --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml @@ -0,0 +1,206 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6362-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6362 pin controller + +maintainers: + - Álvaro Fernández Rojas <noltari@gmail.com> + - Jonas Gorski <jonas.gorski@gmail.com> + +description: + Bindings for Broadcom's BCM6362 memory-mapped pin controller. + +properties: + compatible: + const: brcm,bcm6362-pinctrl + + reg: + maxItems: 2 + +patternProperties: + '-pins$': + type: object + $ref: pinmux-node.yaml# + + properties: + function: + enum: [ usb_device_led, sys_irq, serial_led_clk, serial_led_data, + robosw_led_data, robosw_led_clk, robosw_led0, robosw_led1, + inet_led, spi_cs2, spi_cs3, ntr_pulse, uart1_scts, + uart1_srts, uart1_sdin, uart1_sdout, adsl_spi_miso, + adsl_spi_mosi, adsl_spi_clk, adsl_spi_cs, ephy0_led, + ephy1_led, ephy2_led, ephy3_led, ext_irq0, ext_irq1, + ext_irq2, ext_irq3, nand ] + + pins: + enum: [ gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7, + gpio8, gpio9, gpio10, gpio11, gpio12, gpio13, gpio14, + gpio15, gpio16, gpio17, gpio18, gpio19, gpio20, gpio21, + gpio22, gpio23, gpio24, gpio25, gpio26, gpio27, nand_grp ] + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + pinctrl@18 { + compatible = "brcm,bcm6362-pinctrl"; + reg = <0x18 0x10>, <0x38 0x4>; + + pinctrl_usb_device_led: usb_device_led-pins { + function = "usb_device_led"; + pins = "gpio0"; + }; + + pinctrl_sys_irq: sys_irq-pins { + function = "sys_irq"; + pins = "gpio1"; + }; + + pinctrl_serial_led: serial_led-pins { + pinctrl_serial_led_clk: serial_led_clk-pins { + function = "serial_led_clk"; + pins = "gpio2"; + }; + + pinctrl_serial_led_data: serial_led_data-pins { + function = "serial_led_data"; + pins = "gpio3"; + }; + }; + + pinctrl_robosw_led_data: robosw_led_data-pins { + function = "robosw_led_data"; + pins = "gpio4"; + }; + + pinctrl_robosw_led_clk: robosw_led_clk-pins { + function = "robosw_led_clk"; + pins = "gpio5"; + }; + + pinctrl_robosw_led0: robosw_led0-pins { + function = "robosw_led0"; + pins = "gpio6"; + }; + + pinctrl_robosw_led1: robosw_led1-pins { + function = "robosw_led1"; + pins = "gpio7"; + }; + + pinctrl_inet_led: inet_led-pins { + function = "inet_led"; + pins = "gpio8"; + }; + + pinctrl_spi_cs2: spi_cs2-pins { + function = "spi_cs2"; + pins = "gpio9"; + }; + + pinctrl_spi_cs3: spi_cs3-pins { + function = "spi_cs3"; + pins = "gpio10"; + }; + + pinctrl_ntr_pulse: ntr_pulse-pins { + function = "ntr_pulse"; + pins = "gpio11"; + }; + + pinctrl_uart1_scts: uart1_scts-pins { + function = "uart1_scts"; + pins = "gpio12"; + }; + + pinctrl_uart1_srts: uart1_srts-pins { + function = "uart1_srts"; + pins = "gpio13"; + }; + + pinctrl_uart1: uart1-pins { + pinctrl_uart1_sdin: uart1_sdin-pins { + function = "uart1_sdin"; + pins = "gpio14"; + }; + + pinctrl_uart1_sdout: uart1_sdout-pins { + function = "uart1_sdout"; + pins = "gpio15"; + }; + }; + + pinctrl_adsl_spi: adsl_spi-pins { + pinctrl_adsl_spi_miso: adsl_spi_miso-pins { + function = "adsl_spi_miso"; + pins = "gpio16"; + }; + + pinctrl_adsl_spi_mosi: adsl_spi_mosi-pins { + function = "adsl_spi_mosi"; + pins = "gpio17"; + }; + + pinctrl_adsl_spi_clk: adsl_spi_clk-pins { + function = "adsl_spi_clk"; + pins = "gpio18"; + }; + + pinctrl_adsl_spi_cs: adsl_spi_cs-pins { + function = "adsl_spi_cs"; + pins = "gpio19"; + }; + }; + + pinctrl_ephy0_led: ephy0_led-pins { + function = "ephy0_led"; + pins = "gpio20"; + }; + + pinctrl_ephy1_led: ephy1_led-pins { + function = "ephy1_led"; + pins = "gpio21"; + }; + + pinctrl_ephy2_led: ephy2_led-pins { + function = "ephy2_led"; + pins = "gpio22"; + }; + + pinctrl_ephy3_led: ephy3_led-pins { + function = "ephy3_led"; + pins = "gpio23"; + }; + + pinctrl_ext_irq0: ext_irq0-pins { + function = "ext_irq0"; + pins = "gpio24"; + }; + + pinctrl_ext_irq1: ext_irq1-pins { + function = "ext_irq1"; + pins = "gpio25"; + }; + + pinctrl_ext_irq2: ext_irq2-pins { + function = "ext_irq2"; + pins = "gpio26"; + }; + + pinctrl_ext_irq3: ext_irq3-pins { + function = "ext_irq3"; + pins = "gpio27"; + }; + + pinctrl_nand: nand-pins { + function = "nand"; + group = "nand_grp"; + }; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml new file mode 100644 index 000000000000..f4168b9f4460 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml @@ -0,0 +1,217 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6368-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6368 pin controller + +maintainers: + - Álvaro Fernández Rojas <noltari@gmail.com> + - Jonas Gorski <jonas.gorski@gmail.com> + +description: + Bindings for Broadcom's BCM6368 memory-mapped pin controller. + +properties: + compatible: + const: brcm,bcm6368-pinctrl + + reg: + maxItems: 2 + +patternProperties: + '-pins$': + type: object + $ref: pinmux-node.yaml# + + properties: + function: + enum: [ analog_afe_0, analog_afe_1, sys_irq, serial_led_data, + serial_led_clk, inet_led, ephy0_led, ephy1_led, ephy2_led, + ephy3_led, robosw_led_data, robosw_led_clk, robosw_led0, + robosw_led1, usb_device_led, pci_req1, pci_gnt1, pci_intb, + pci_req0, pci_gnt0, pcmcia_cd1, pcmcia_cd2, pcmcia_vs1, + pcmcia_vs2, ebi_cs2, ebi_cs3, spi_cs2, spi_cs3, spi_cs4, + spi_cs5, uart1 ] + + pins: + enum: [ gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7, + gpio8, gpio9, gpio10, gpio11, gpio12, gpio13, gpio14, + gpio16, gpio17, gpio18, gpio19, gpio20, gpio22, gpio23, + gpio24, gpio25, gpio26, gpio27, gpio28, gpio29, gpio30, + gpio31, uart1_grp ] + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + pinctrl@18 { + compatible = "brcm,bcm6368-pinctrl"; + reg = <0x18 0x4>, <0x38 0x4>; + + pinctrl_analog_afe_0: analog_afe_0-pins { + function = "analog_afe_0"; + pins = "gpio0"; + }; + + pinctrl_analog_afe_1: analog_afe_1-pins { + function = "analog_afe_1"; + pins = "gpio1"; + }; + + pinctrl_sys_irq: sys_irq-pins { + function = "sys_irq"; + pins = "gpio2"; + }; + + pinctrl_serial_led: serial_led-pins { + pinctrl_serial_led_data: serial_led_data-pins { + function = "serial_led_data"; + pins = "gpio3"; + }; + + pinctrl_serial_led_clk: serial_led_clk-pins { + function = "serial_led_clk"; + pins = "gpio4"; + }; + }; + + pinctrl_inet_led: inet_led-pins { + function = "inet_led"; + pins = "gpio5"; + }; + + pinctrl_ephy0_led: ephy0_led-pins { + function = "ephy0_led"; + pins = "gpio6"; + }; + + pinctrl_ephy1_led: ephy1_led-pins { + function = "ephy1_led"; + pins = "gpio7"; + }; + + pinctrl_ephy2_led: ephy2_led-pins { + function = "ephy2_led"; + pins = "gpio8"; + }; + + pinctrl_ephy3_led: ephy3_led-pins { + function = "ephy3_led"; + pins = "gpio9"; + }; + + pinctrl_robosw_led_data: robosw_led_data-pins { + function = "robosw_led_data"; + pins = "gpio10"; + }; + + pinctrl_robosw_led_clk: robosw_led_clk-pins { + function = "robosw_led_clk"; + pins = "gpio11"; + }; + + pinctrl_robosw_led0: robosw_led0-pins { + function = "robosw_led0"; + pins = "gpio12"; + }; + + pinctrl_robosw_led1: robosw_led1-pins { + function = "robosw_led1"; + pins = "gpio13"; + }; + + pinctrl_usb_device_led: usb_device_led-pins { + function = "usb_device_led"; + pins = "gpio14"; + }; + + pinctrl_pci: pci-pins { + pinctrl_pci_req1: pci_req1-pins { + function = "pci_req1"; + pins = "gpio16"; + }; + + pinctrl_pci_gnt1: pci_gnt1-pins { + function = "pci_gnt1"; + pins = "gpio17"; + }; + + pinctrl_pci_intb: pci_intb-pins { + function = "pci_intb"; + pins = "gpio18"; + }; + + pinctrl_pci_req0: pci_req0-pins { + function = "pci_req0"; + pins = "gpio19"; + }; + + pinctrl_pci_gnt0: pci_gnt0-pins { + function = "pci_gnt0"; + pins = "gpio20"; + }; + }; + + pinctrl_pcmcia: pcmcia-pins { + pinctrl_pcmcia_cd1: pcmcia_cd1-pins { + function = "pcmcia_cd1"; + pins = "gpio22"; + }; + + pinctrl_pcmcia_cd2: pcmcia_cd2-pins { + function = "pcmcia_cd2"; + pins = "gpio23"; + }; + + pinctrl_pcmcia_vs1: pcmcia_vs1-pins { + function = "pcmcia_vs1"; + pins = "gpio24"; + }; + + pinctrl_pcmcia_vs2: pcmcia_vs2-pins { + function = "pcmcia_vs2"; + pins = "gpio25"; + }; + }; + + pinctrl_ebi_cs2: ebi_cs2-pins { + function = "ebi_cs2"; + pins = "gpio26"; + }; + + pinctrl_ebi_cs3: ebi_cs3-pins { + function = "ebi_cs3"; + pins = "gpio27"; + }; + + pinctrl_spi_cs2: spi_cs2-pins { + function = "spi_cs2"; + pins = "gpio28"; + }; + + pinctrl_spi_cs3: spi_cs3-pins { + function = "spi_cs3"; + pins = "gpio29"; + }; + + pinctrl_spi_cs4: spi_cs4-pins { + function = "spi_cs4"; + pins = "gpio30"; + }; + + pinctrl_spi_cs5: spi_cs5-pins { + function = "spi_cs5"; + pins = "gpio31"; + }; + + pinctrl_uart1: uart1-pins { + function = "uart1"; + group = "uart1_grp"; + }; + }; diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c index 5412cb3b0b2a..134cedf151a7 100644 --- a/drivers/gpio/gpio-regmap.c +++ b/drivers/gpio/gpio-regmap.c @@ -254,6 +254,11 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config chip->names = config->names; chip->label = config->label ?: dev_name(config->parent); +#if defined(CONFIG_OF_GPIO) + /* gpiolib will use of_node of the parent if chip->of_node is NULL */ + chip->of_node = to_of_node(config->fwnode); +#endif /* CONFIG_OF_GPIO */ + /* * If our regmap is fast_io we should probably set can_sleep to false. * Right now, the regmap doesn't save this property, nor is there any diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig index 0ed14de0134c..33660e8fec05 100644 --- a/drivers/pinctrl/bcm/Kconfig +++ b/drivers/pinctrl/bcm/Kconfig @@ -29,6 +29,61 @@ config PINCTRL_BCM2835 help Say Y here to enable the Broadcom BCM2835 GPIO driver. +config PINCTRL_BCM63XX + bool + select GENERIC_PINCONF + select GPIO_REGMAP + select PINCONF + select PINMUX + +config PINCTRL_BCM6318 + bool "Broadcom BCM6318 GPIO driver" + depends on (BMIPS_GENERIC || COMPILE_TEST) + select PINCTRL_BCM63XX + default BMIPS_GENERIC + help + Say Y here to enable the Broadcom BCM6318 GPIO driver. + +config PINCTRL_BCM6328 + bool "Broadcom BCM6328 GPIO driver" + depends on (BMIPS_GENERIC || COMPILE_TEST) + select PINCTRL_BCM63XX + default BMIPS_GENERIC + help + Say Y here to enable the Broadcom BCM6328 GPIO driver. + +config PINCTRL_BCM6358 + bool "Broadcom BCM6358 GPIO driver" + depends on (BMIPS_GENERIC || COMPILE_TEST) + select PINCTRL_BCM63XX + default BMIPS_GENERIC + help + Say Y here to enable the Broadcom BCM6358 GPIO driver. + +config PINCTRL_BCM6362 + bool "Broadcom BCM6362 GPIO driver" + depends on (BMIPS_GENERIC || COMPILE_TEST) + select PINCTRL_BCM63XX + default BMIPS_GENERIC + help + Say Y here to enable the Broadcom BCM6362 GPIO driver. + +config PINCTRL_BCM6368 + bool "Broadcom BCM6368 GPIO driver" + depends on (BMIPS_GENERIC || COMPILE_TEST) + select PINCTRL_BCM63XX + default BMIPS_GENERIC + help + Say Y here to enable the Broadcom BCM6368 GPIO driver. + +config PINCTRL_BCM63268 + bool "Broadcom BCM63268 GPIO driver" + depends on (BMIPS_GENERIC || COMPILE_TEST) + select PINCTRL_BCM63XX + default BMIPS_GENERIC + help + Say Y here to enable the Broadcom BCM63268 GPIO driver. + config PINCTRL_IPROC_GPIO bool "Broadcom iProc GPIO (with PINCONF) driver" depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST) diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile index 79d5e49fdd9a..00c7b7775e63 100644 --- a/drivers/pinctrl/bcm/Makefile +++ b/drivers/pinctrl/bcm/Makefile @@ -3,6 +3,13 @@ obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o +obj-$(CONFIG_PINCTRL_BCM63XX) += pinctrl-bcm63xx.o +obj-$(CONFIG_PINCTRL_BCM6318) += pinctrl-bcm6318.o +obj-$(CONFIG_PINCTRL_BCM6328) += pinctrl-bcm6328.o +obj-$(CONFIG_PINCTRL_BCM6358) += pinctrl-bcm6358.o +obj-$(CONFIG_PINCTRL_BCM6362) += pinctrl-bcm6362.o +obj-$(CONFIG_PINCTRL_BCM6368) += pinctrl-bcm6368.o +obj-$(CONFIG_PINCTRL_BCM63268) += pinctrl-bcm63268.o obj-$(CONFIG_PINCTRL_IPROC_GPIO) += pinctrl-iproc-gpio.o obj-$(CONFIG_PINCTRL_CYGNUS_MUX) += pinctrl-cygnus-mux.o obj-$(CONFIG_PINCTRL_NS) += pinctrl-ns.o diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6318.c b/drivers/pinctrl/bcm/pinctrl-bcm6318.c new file mode 100644 index 000000000000..77fd9b58067d --- /dev/null +++ b/drivers/pinctrl/bcm/pinctrl-bcm6318.c @@ -0,0 +1,498 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for BCM6318 GPIO unit (pinctrl + GPIO) + * + * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com> + * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com> + */ + +#include <linux/bits.h> +#include <linux/gpio/driver.h> +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/pinctrl/pinmux.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include "../pinctrl-utils.h" + +#include "pinctrl-bcm63xx.h" + +#define BCM6318_NUM_GPIOS 50 +#define BCM6318_NUM_MUX 48 + +#define BCM6318_MODE_REG 0x18 +#define BCM6318_MUX_REG 0x1c +#define BCM6328_MUX_MASK GENMASK(1, 0) +#define BCM6318_PAD_REG 0x54 +#define BCM6328_PAD_MASK GENMASK(3, 0) + +struct bcm6318_pingroup { + const char *name; + const unsigned * const pins; + const unsigned num_pins; +}; + +struct bcm6318_function { + const char *name; + const char * const *groups; + const unsigned num_groups; + + unsigned mode_val:1; + unsigned mux_val:2; +}; + +static const struct pinctrl_pin_desc bcm6318_pins[] = { + PINCTRL_PIN(0, "gpio0"), + PINCTRL_PIN(1, "gpio1"), + PINCTRL_PIN(2, "gpio2"), + PINCTRL_PIN(3, "gpio3"), + PINCTRL_PIN(4, "gpio4"), + PINCTRL_PIN(5, "gpio5"), + PINCTRL_PIN(6, "gpio6"), + PINCTRL_PIN(7, "gpio7"), + PINCTRL_PIN(8, "gpio8"), + PINCTRL_PIN(9, "gpio9"), + PINCTRL_PIN(10, "gpio10"), + PINCTRL_PIN(11, "gpio11"), + PINCTRL_PIN(12, "gpio12"), + PINCTRL_PIN(13, "gpio13"), + PINCTRL_PIN(14, "gpio14"), + PINCTRL_PIN(15, "gpio15"), + PINCTRL_PIN(16, "gpio16"), + PINCTRL_PIN(17, "gpio17"), + PINCTRL_PIN(18, "gpio18"), + PINCTRL_PIN(19, "gpio19"), + PINCTRL_PIN(20, "gpio20"), + PINCTRL_PIN(21, "gpio21"), + PINCTRL_PIN(22, "gpio22"), + PINCTRL_PIN(23, "gpio23"), + PINCTRL_PIN(24, "gpio24"), + PINCTRL_PIN(25, "gpio25"), + PINCTRL_PIN(26, "gpio26"), + PINCTRL_PIN(27, "gpio27"), + PINCTRL_PIN(28, "gpio28"), + PINCTRL_PIN(29, "gpio29"), + PINCTRL_PIN(30, "gpio30"), + PINCTRL_PIN(31, "gpio31"), + PINCTRL_PIN(32, "gpio32"), + PINCTRL_PIN(33, "gpio33"), + PINCTRL_PIN(34, "gpio34"), + PINCTRL_PIN(35, "gpio35"), + PINCTRL_PIN(36, "gpio36"), + PINCTRL_PIN(37, "gpio37"), + PINCTRL_PIN(38, "gpio38"), + PINCTRL_PIN(39, "gpio39"), + PINCTRL_PIN(40, "gpio40"), + PINCTRL_PIN(41, "gpio41"), + PINCTRL_PIN(42, "gpio42"), + PINCTRL_PIN(43, "gpio43"), + PINCTRL_PIN(44, "gpio44"), + PINCTRL_PIN(45, "gpio45"), + PINCTRL_PIN(46, "gpio46"), + PINCTRL_PIN(47, "gpio47"), + PINCTRL_PIN(48, "gpio48"), + PINCTRL_PIN(49, "gpio49"), +}; + +static unsigned gpio0_pins[] = { 0 }; +static unsigned gpio1_pins[] = { 1 }; +static unsigned gpio2_pins[] = { 2 }; +static unsigned gpio3_pins[] = { 3 }; +static unsigned gpio4_pins[] = { 4 }; +static unsigned gpio5_pins[] = { 5 }; +static unsigned gpio6_pins[] = { 6 }; +static unsigned gpio7_pins[] = { 7 }; +static unsigned gpio8_pins[] = { 8 }; +static unsigned gpio9_pins[] = { 9 }; +static unsigned gpio10_pins[] = { 10 }; +static unsigned gpio11_pins[] = { 11 }; +static unsigned gpio12_pins[] = { 12 }; +static unsigned gpio13_pins[] = { 13 }; +static unsigned gpio14_pins[] = { 14 }; +static unsigned gpio15_pins[] = { 15 }; +static unsigned gpio16_pins[] = { 16 }; +static unsigned gpio17_pins[] = { 17 }; +static unsigned gpio18_pins[] = { 18 }; +static unsigned gpio19_pins[] = { 19 }; +static unsigned gpio20_pins[] = { 20 }; +static unsigned gpio21_pins[] = { 21 }; +static unsigned gpio22_pins[] = { 22 }; +static unsigned gpio23_pins[] = { 23 }; +static unsigned gpio24_pins[] = { 24 }; +static unsigned gpio25_pins[] = { 25 }; +static unsigned gpio26_pins[] = { 26 }; +static unsigned gpio27_pins[] = { 27 }; +static unsigned gpio28_pins[] = { 28 }; +static unsigned gpio29_pins[] = { 29 }; +static unsigned gpio30_pins[] = { 30 }; +static unsigned gpio31_pins[] = { 31 }; +static unsigned gpio32_pins[] = { 32 }; +static unsigned gpio33_pins[] = { 33 }; +static unsigned gpio34_pins[] = { 34 }; +static unsigned gpio35_pins[] = { 35 }; +static unsigned gpio36_pins[] = { 36 }; +static unsigned gpio37_pins[] = { 37 }; +static unsigned gpio38_pins[] = { 38 }; +static unsigned gpio39_pins[] = { 39 }; +static unsigned gpio40_pins[] = { 40 }; +static unsigned gpio41_pins[] = { 41 }; +static unsigned gpio42_pins[] = { 42 }; +static unsigned gpio43_pins[] = { 43 }; +static unsigned gpio44_pins[] = { 44 }; +static unsigned gpio45_pins[] = { 45 }; +static unsigned gpio46_pins[] = { 46 }; +static unsigned gpio47_pins[] = { 47 }; +static unsigned gpio48_pins[] = { 48 }; +static unsigned gpio49_pins[] = { 49 }; + +#define BCM6318_GROUP(n) \ + { \ + .name = #n, \ + .pins = n##_pins, \ + .num_pins = ARRAY_SIZE(n##_pins), \ + } + +static struct bcm6318_pingroup bcm6318_groups[] = { + BCM6318_GROUP(gpio0), + BCM6318_GROUP(gpio1), + BCM6318_GROUP(gpio2), + BCM6318_GROUP(gpio3), + BCM6318_GROUP(gpio4), + BCM6318_GROUP(gpio5), + BCM6318_GROUP(gpio6), + BCM6318_GROUP(gpio7), + BCM6318_GROUP(gpio8), + BCM6318_GROUP(gpio9), + BCM6318_GROUP(gpio10), + BCM6318_GROUP(gpio11), + BCM6318_GROUP(gpio12), + BCM6318_GROUP(gpio13), + BCM6318_GROUP(gpio14), + BCM6318_GROUP(gpio15), + BCM6318_GROUP(gpio16), + BCM6318_GROUP(gpio17), + BCM6318_GROUP(gpio18), + BCM6318_GROUP(gpio19), + BCM6318_GROUP(gpio20), + BCM6318_GROUP(gpio21), + BCM6318_GROUP(gpio22), + BCM6318_GROUP(gpio23), + BCM6318_GROUP(gpio24), + BCM6318_GROUP(gpio25), + BCM6318_GROUP(gpio26), + BCM6318_GROUP(gpio27), + BCM6318_GROUP(gpio28), + BCM6318_GROUP(gpio29), + BCM6318_GROUP(gpio30), + BCM6318_GROUP(gpio31), + BCM6318_GROUP(gpio32), + BCM6318_GROUP(gpio33), + BCM6318_GROUP(gpio34), + BCM6318_GROUP(gpio35), + BCM6318_GROUP(gpio36), + BCM6318_GROUP(gpio37), + BCM6318_GROUP(gpio38), + BCM6318_GROUP(gpio39), + BCM6318_GROUP(gpio40), + BCM6318_GROUP(gpio41), + BCM6318_GROUP(gpio42), + BCM6318_GROUP(gpio43), + BCM6318_GROUP(gpio44), + BCM6318_GROUP(gpio45), + BCM6318_GROUP(gpio46), + BCM6318_GROUP(gpio47), + BCM6318_GROUP(gpio48), + BCM6318_GROUP(gpio49), +}; + +/* GPIO_MODE */ +static const char * const led_groups[] = { + "gpio0", + "gpio1", + "gpio2", + "gpio3", + "gpio4", + "gpio5", + "gpio6", + "gpio7", + "gpio8", + "gpio9", + "gpio10", + "gpio11", + "gpio12", + "gpio13", + "gpio14", + "gpio15", + "gpio16", + "gpio17", + "gpio18", + "gpio19", + "gpio20", + "gpio21", + "gpio22", + "gpio23", +}; + +/* PINMUX_SEL */ +static const char * const ephy0_spd_led_groups[] = { + "gpio0", +}; + +static const char * const ephy1_spd_led_groups[] = { + "gpio1", +}; + +static const char * const ephy2_spd_led_groups[] = { + "gpio2", +}; + +static const char * const ephy3_spd_led_groups[] = { + "gpio3", +}; + +static const char * const ephy0_act_led_groups[] = { + "gpio4", +}; + +static const char * const ephy1_act_led_groups[] = { + "gpio5", +}; + +static const char * const ephy2_act_led_groups[] = { + "gpio6", +}; + +static const char * const ephy3_act_led_groups[] = { + "gpio7", +}; + +static const char * const serial_led_data_groups[] = { + "gpio6", +}; + +static const char * const serial_led_clk_groups[] = { + "gpio7", +}; + +static const char * const inet_act_led_groups[] = { + "gpio8", +}; + +static const char * const inet_fail_led_groups[] = { + "gpio9", +}; + +static const char * const dsl_led_groups[] = { + "gpio10", +}; + +static const char * const post_fail_led_groups[] = { + "gpio11", +}; + +static const char * const wlan_wps_led_groups[] = { + "gpio12", +}; + +static const char * const usb_pwron_groups[] = { + "gpio13", +}; + +static const char * const usb_device_led_groups[] = { + "gpio13", +}; + +static const char * const usb_active_groups[] = { + "gpio40", +}; + +#define BCM6318_MODE_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .mode_val = 1, \ + } + +#define BCM6318_MUX_FUN(n, mux) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .mux_val = mux, \ + } + +static const struct bcm6318_function bcm6318_funcs[] = { + BCM6318_MODE_FUN(led), + BCM6318_MUX_FUN(ephy0_spd_led, 1), + BCM6318_MUX_FUN(ephy1_spd_led, 1), + BCM6318_MUX_FUN(ephy2_spd_led, 1), + BCM6318_MUX_FUN(ephy3_spd_led, 1), + BCM6318_MUX_FUN(ephy0_act_led, 1), + BCM6318_MUX_FUN(ephy1_act_led, 1), + BCM6318_MUX_FUN(ephy2_act_led, 1), + BCM6318_MUX_FUN(ephy3_act_led, 1), + BCM6318_MUX_FUN(serial_led_data, 3), + BCM6318_MUX_FUN(serial_led_clk, 3), + BCM6318_MUX_FUN(inet_act_led, 1), + BCM6318_MUX_FUN(inet_fail_led, 1), + BCM6318_MUX_FUN(dsl_led, 1), + BCM6318_MUX_FUN(post_fail_led, 1), + BCM6318_MUX_FUN(wlan_wps_led, 1), + BCM6318_MUX_FUN(usb_pwron, 1), + BCM6318_MUX_FUN(usb_device_led, 2), + BCM6318_MUX_FUN(usb_active, 2), +}; + +static inline unsigned int bcm6318_mux_off(unsigned int pin) +{ + return BCM6318_MUX_REG + (pin / 16) * 4; +} + +static inline unsigned int bcm6318_pad_off(unsigned int pin) +{ + return BCM6318_PAD_REG + (pin / 8) * 4; +} + +static int bcm6318_pinctrl_get_group_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6318_groups); +} + +static const char *bcm6318_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned group) +{ + return bcm6318_groups[group].name; +} + +static int bcm6318_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned group, const unsigned **pins, + unsigned *num_pins) +{ + *pins = bcm6318_groups[group].pins; + *num_pins = bcm6318_groups[group].num_pins; + + return 0; +} + +static int bcm6318_pinctrl_get_func_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6318_funcs); +} + +static const char *bcm6318_pinctrl_get_func_name(struct pinctrl_dev *pctldev, + unsigned selector) +{ + return bcm6318_funcs[selector].name; +} + +static int bcm6318_pinctrl_get_groups(struct pinctrl_dev *pctldev, + unsigned selector, + const char * const **groups, + unsigned * const num_groups) +{ + *groups = bcm6318_funcs[selector].groups; + *num_groups = bcm6318_funcs[selector].num_groups; + + return 0; +} + +static inline void bcm6318_rmw_mux(struct bcm63xx_pinctrl *pc, unsigned pin, + unsigned int mode, unsigned int mux) +{ + if (pin < BCM63XX_BANK_GPIOS) + regmap_update_bits(pc->regs, BCM6318_MODE_REG, BIT(pin), + mode ? BIT(pin) : 0); + + if (pin < BCM6318_NUM_MUX) + regmap_update_bits(pc->regs, + bcm6318_mux_off(pin), + BCM6328_MUX_MASK << ((pin % 16) * 2), + mux << ((pin % 16) * 2)); +} + +static inline void bcm6318_set_pad(struct bcm63xx_pinctrl *pc, unsigned pin, + uint8_t val) +{ + regmap_update_bits(pc->regs, bcm6318_pad_off(pin), + BCM6328_PAD_MASK << ((pin % 8) * 4), + val << ((pin % 8) * 4)); +} + +static int bcm6318_pinctrl_set_mux(struct pinctrl_dev *pctldev, + unsigned selector, unsigned group) +{ + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + const struct bcm6318_pingroup *pg = &bcm6318_groups[group]; + const struct bcm6318_function *f = &bcm6318_funcs[selector]; + + bcm6318_rmw_mux(pc, pg->pins[0], f->mode_val, f->mux_val); + + return 0; +} + +static int bcm6318_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) +{ + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + + /* disable all functions using this pin */ + if (offset < 13) { + /* GPIOs 0-12 use mux 0 as GPIO function */ + bcm6318_rmw_mux(pc, offset, 0, 0); + } else if (offset < 42) { + /* GPIOs 13-41 use mux 3 as GPIO function */ + bcm6318_rmw_mux(pc, offset, 0, 3); + + bcm6318_set_pad(pc, offset, 0); + } + + return 0; +} + +static struct pinctrl_ops bcm6318_pctl_ops = { + .dt_free_map = pinctrl_utils_free_map, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .get_group_name = bcm6318_pinctrl_get_group_name, + .get_group_pins = bcm6318_pinctrl_get_group_pins, + .get_groups_count = bcm6318_pinctrl_get_group_count, +}; + +static struct pinmux_ops bcm6318_pmx_ops = { + .get_function_groups = bcm6318_pinctrl_get_groups, + .get_function_name = bcm6318_pinctrl_get_func_name, + .get_functions_count = bcm6318_pinctrl_get_func_count, + .gpio_request_enable = bcm6318_gpio_request_enable, + .set_mux = bcm6318_pinctrl_set_mux, + .strict = true, +}; + +static const struct bcm63xx_pinctrl_soc bcm6318_soc = { + .ngpios = BCM6318_NUM_GPIOS, + .npins = ARRAY_SIZE(bcm6318_pins), + .pctl_ops = &bcm6318_pctl_ops, + .pins = bcm6318_pins, + .pmx_ops = &bcm6318_pmx_ops, +}; + +static int bcm6318_pinctrl_probe(struct platform_device *pdev) +{ + return bcm63xx_pinctrl_probe(pdev, &bcm6318_soc, NULL); +} + +static const struct of_device_id bcm6318_pinctrl_match[] = { + { .compatible = "brcm,bcm6318-pinctrl", }, + { /* sentinel */ } +}; + +static struct platform_driver bcm6318_pinctrl_driver = { + .probe = bcm6318_pinctrl_probe, + .driver = { + .name = "bcm6318-pinctrl", + .of_match_table = bcm6318_pinctrl_match, + }, +}; + +builtin_platform_driver(bcm6318_pinctrl_driver); diff --git a/drivers/pinctrl/bcm/pinctrl-bcm63268.c b/drivers/pinctrl/bcm/pinctrl-bcm63268.c new file mode 100644 index 000000000000..d4c5fad7fb7d --- /dev/null +++ b/drivers/pinctrl/bcm/pinctrl-bcm63268.c @@ -0,0 +1,643 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for BCM63268 GPIO unit (pinctrl + GPIO) + * + * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com> + * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com> + */ + +#include <linux/bits.h> +#include <linux/gpio/driver.h> +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/pinctrl/pinmux.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include "../pinctrl-utils.h" + +#include "pinctrl-bcm63xx.h" + +#define BCM63268_NUM_GPIOS 52 +#define BCM63268_NUM_LEDS 24 + +#define BCM63268_LED_REG 0x10 +#define BCM63268_MODE_REG 0x18 +#define BCM63268_CTRL_REG 0x1c +#define BCM63268_BASEMODE_REG 0x38 +#define BCM63268_BASEMODE_NAND BIT(2) /* GPIOs 2-7, 24-31 */ +#define BCM63268_BASEMODE_GPIO35 BIT(4) /* GPIO 35 */ +#define BCM63268_BASEMODE_DECTPD BIT(5) /* GPIOs 8/9 */ +#define BCM63268_BASEMODE_VDSL_PHY_0 BIT(6) /* GPIOs 10/11 */ +#define BCM63268_BASEMODE_VDSL_PHY_1 BIT(7) /* GPIOs 12/13 */ +#define BCM63268_BASEMODE_VDSL_PHY_2 BIT(8) /* GPIOs 24/25 */ +#define BCM63268_BASEMODE_VDSL_PHY_3 BIT(9) /* GPIOs 26/27 */ + +enum bcm63268_pinctrl_reg { + BCM63268_LEDCTRL, + BCM63268_MODE, + BCM63268_CTRL, + BCM63268_BASEMODE, +}; + +struct bcm63268_pingroup { + const char *name; + const unsigned * const pins; + const unsigned num_pins; +}; + +struct bcm63268_function { + const char *name; + const char * const *groups; + const unsigned num_groups; + + enum bcm63268_pinctrl_reg reg; + uint32_t mask; +}; + +#define BCM63268_PIN(a, b, basemode) \ + { \ + .number = a, \ + .name = b, \ + .drv_data = (void *)(basemode) \ + } + +static const struct pinctrl_pin_desc bcm63268_pins[] = { + PINCTRL_PIN(0, "gpio0"), + PINCTRL_PIN(1, "gpio1"), + BCM63268_PIN(2, "gpio2", BCM63268_BASEMODE_NAND), + BCM63268_PIN(3, "gpio3", BCM63268_BASEMODE_NAND), + BCM63268_PIN(4, "gpio4", BCM63268_BASEMODE_NAND), + BCM63268_PIN(5, "gpio5", BCM63268_BASEMODE_NAND), + BCM63268_PIN(6, "gpio6", BCM63268_BASEMODE_NAND), + BCM63268_PIN(7, "gpio7", BCM63268_BASEMODE_NAND), + BCM63268_PIN(8, "gpio8", BCM63268_BASEMODE_DECTPD), + BCM63268_PIN(9, "gpio9", BCM63268_BASEMODE_DECTPD), + BCM63268_PIN(10, "gpio10", BCM63268_BASEMODE_VDSL_PHY_0), + BCM63268_PIN(11, "gpio11", BCM63268_BASEMODE_VDSL_PHY_0), + BCM63268_PIN(12, "gpio12", BCM63268_BASEMODE_VDSL_PHY_1), + BCM63268_PIN(13, "gpio13", BCM63268_BASEMODE_VDSL_PHY_1), + PINCTRL_PIN(14, "gpio14"), + PINCTRL_PIN(15, "gpio15"), + PINCTRL_PIN(16, "gpio16"), + PINCTRL_PIN(17, "gpio17"), + PINCTRL_PIN(18, "gpio18"), + PINCTRL_PIN(19, "gpio19"), + PINCTRL_PIN(20, "gpio20"), + PINCTRL_PIN(21, "gpio21"), + PINCTRL_PIN(22, "gpio22"), + PINCTRL_PIN(23, "gpio23"), + BCM63268_PIN(24, "gpio24", + BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_2), + BCM63268_PIN(25, "gpio25", + BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_2), + BCM63268_PIN(26, "gpio26", + BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_3), + BCM63268_PIN(27, "gpio27", + BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_3), + BCM63268_PIN(28, "gpio28", BCM63268_BASEMODE_NAND), + BCM63268_PIN(29, "gpio29", BCM63268_BASEMODE_NAND), + BCM63268_PIN(30, "gpio30", BCM63268_BASEMODE_NAND), + BCM63268_PIN(31, "gpio31", BCM63268_BASEMODE_NAND), + PINCTRL_PIN(32, "gpio32"), + PINCTRL_PIN(33, "gpio33"), + PINCTRL_PIN(34, "gpio34"), + PINCTRL_PIN(35, "gpio35"), + PINCTRL_PIN(36, "gpio36"), + PINCTRL_PIN(37, "gpio37"), + PINCTRL_PIN(38, "gpio38"), + PINCTRL_PIN(39, "gpio39"), + PINCTRL_PIN(40, "gpio40"), + PINCTRL_PIN(41, "gpio41"), + PINCTRL_PIN(42, "gpio42"), + PINCTRL_PIN(43, "gpio43"), + PINCTRL_PIN(44, "gpio44"), + PINCTRL_PIN(45, "gpio45"), + PINCTRL_PIN(46, "gpio46"), + PINCTRL_PIN(47, "gpio47"), + PINCTRL_PIN(48, "gpio48"), + PINCTRL_PIN(49, "gpio49"), + PINCTRL_PIN(50, "gpio50"), + PINCTRL_PIN(51, "gpio51"), +}; + +static unsigned gpio0_pins[] = { 0 }; +static unsigned gpio1_pins[] = { 1 }; +static unsigned gpio2_pins[] = { 2 }; +static unsigned gpio3_pins[] = { 3 }; +static unsigned gpio4_pins[] = { 4 }; +static unsigned gpio5_pins[] = { 5 }; +static unsigned gpio6_pins[] = { 6 }; +static unsigned gpio7_pins[] = { 7 }; +static unsigned gpio8_pins[] = { 8 }; +static unsigned gpio9_pins[] = { 9 }; +static unsigned gpio10_pins[] = { 10 }; +static unsigned gpio11_pins[] = { 11 }; +static unsigned gpio12_pins[] = { 12 }; +static unsigned gpio13_pins[] = { 13 }; +static unsigned gpio14_pins[] = { 14 }; +static unsigned gpio15_pins[] = { 15 }; +static unsigned gpio16_pins[] = { 16 }; +static unsigned gpio17_pins[] = { 17 }; +static unsigned gpio18_pins[] = { 18 }; +static unsigned gpio19_pins[] = { 19 }; +static unsigned gpio20_pins[] = { 20 }; +static unsigned gpio21_pins[] = { 21 }; +static unsigned gpio22_pins[] = { 22 }; +static unsigned gpio23_pins[] = { 23 }; +static unsigned gpio24_pins[] = { 24 }; +static unsigned gpio25_pins[] = { 25 }; +static unsigned gpio26_pins[] = { 26 }; +static unsigned gpio27_pins[] = { 27 }; +static unsigned gpio28_pins[] = { 28 }; +static unsigned gpio29_pins[] = { 29 }; +static unsigned gpio30_pins[] = { 30 }; +static unsigned gpio31_pins[] = { 31 }; +static unsigned gpio32_pins[] = { 32 }; +static unsigned gpio33_pins[] = { 33 }; +static unsigned gpio34_pins[] = { 34 }; +static unsigned gpio35_pins[] = { 35 }; +static unsigned gpio36_pins[] = { 36 }; +static unsigned gpio37_pins[] = { 37 }; +static unsigned gpio38_pins[] = { 38 }; +static unsigned gpio39_pins[] = { 39 }; +static unsigned gpio40_pins[] = { 40 }; +static unsigned gpio41_pins[] = { 41 }; +static unsigned gpio42_pins[] = { 42 }; +static unsigned gpio43_pins[] = { 43 }; +static unsigned gpio44_pins[] = { 44 }; +static unsigned gpio45_pins[] = { 45 }; +static unsigned gpio46_pins[] = { 46 }; +static unsigned gpio47_pins[] = { 47 }; +static unsigned gpio48_pins[] = { 48 }; +static unsigned gpio49_pins[] = { 49 }; +static unsigned gpio50_pins[] = { 50 }; +static unsigned gpio51_pins[] = { 51 }; + +static unsigned nand_grp_pins[] = { + 2, 3, 4, 5, 6, 7, 24, + 25, 26, 27, 28, 29, 30, 31, +}; + +static unsigned dectpd_grp_pins[] = { 8, 9 }; +static unsigned vdsl_phy0_grp_pins[] = { 10, 11 }; +static unsigned vdsl_phy1_grp_pins[] = { 12, 13 }; +static unsigned vdsl_phy2_grp_pins[] = { 24, 25 }; +static unsigned vdsl_phy3_grp_pins[] = { 26, 27 }; + +#define BCM63268_GROUP(n) \ + { \ + .name = #n, \ + .pins = n##_pins, \ + .num_pins = ARRAY_SIZE(n##_pins), \ + } + +static struct bcm63268_pingroup bcm63268_groups[] = { + BCM63268_GROUP(gpio0), + BCM63268_GROUP(gpio1), + BCM63268_GROUP(gpio2), + BCM63268_GROUP(gpio3), + BCM63268_GROUP(gpio4), + BCM63268_GROUP(gpio5), + BCM63268_GROUP(gpio6), + BCM63268_GROUP(gpio7), + BCM63268_GROUP(gpio8), + BCM63268_GROUP(gpio9), + BCM63268_GROUP(gpio10), + BCM63268_GROUP(gpio11), + BCM63268_GROUP(gpio12), + BCM63268_GROUP(gpio13), + BCM63268_GROUP(gpio14), + BCM63268_GROUP(gpio15), + BCM63268_GROUP(gpio16), + BCM63268_GROUP(gpio17), + BCM63268_GROUP(gpio18), + BCM63268_GROUP(gpio19), + BCM63268_GROUP(gpio20), + BCM63268_GROUP(gpio21), + BCM63268_GROUP(gpio22), + BCM63268_GROUP(gpio23), + BCM63268_GROUP(gpio24), + BCM63268_GROUP(gpio25), + BCM63268_GROUP(gpio26), + BCM63268_GROUP(gpio27), + BCM63268_GROUP(gpio28), + BCM63268_GROUP(gpio29), + BCM63268_GROUP(gpio30), + BCM63268_GROUP(gpio31), + BCM63268_GROUP(gpio32), + BCM63268_GROUP(gpio33), + BCM63268_GROUP(gpio34), + BCM63268_GROUP(gpio35), + BCM63268_GROUP(gpio36), + BCM63268_GROUP(gpio37), + BCM63268_GROUP(gpio38), + BCM63268_GROUP(gpio39), + BCM63268_GROUP(gpio40), + BCM63268_GROUP(gpio41), + BCM63268_GROUP(gpio42), + BCM63268_GROUP(gpio43), + BCM63268_GROUP(gpio44), + BCM63268_GROUP(gpio45), + BCM63268_GROUP(gpio46), + BCM63268_GROUP(gpio47), + BCM63268_GROUP(gpio48), + BCM63268_GROUP(gpio49), + BCM63268_GROUP(gpio50), + BCM63268_GROUP(gpio51), + + /* multi pin groups */ + BCM63268_GROUP(nand_grp), + BCM63268_GROUP(dectpd_grp), + BCM63268_GROUP(vdsl_phy0_grp), + BCM63268_GROUP(vdsl_phy1_grp), + BCM63268_GROUP(vdsl_phy2_grp), + BCM63268_GROUP(vdsl_phy3_grp), +}; + +static const char * const led_groups[] = { + "gpio0", + "gpio1", + "gpio2", + "gpio3", + "gpio4", + "gpio5", + "gpio6", + "gpio7", + "gpio8", + "gpio9", + "gpio10", + "gpio11", + "gpio12", + "gpio13", + "gpio14", + "gpio15", + "gpio16", + "gpio17", + "gpio18", + "gpio19", + "gpio20", + "gpio21", + "gpio22", + "gpio23", +}; + +static const char * const serial_led_clk_groups[] = { + "gpio0", +}; + +static const char * const serial_led_data_groups[] = { + "gpio1", +}; + +static const char * const hsspi_cs4_groups[] = { + "gpio16", +}; + +static const char * const hsspi_cs5_groups[] = { + "gpio17", +}; + +static const char * const hsspi_cs6_groups[] = { + "gpio8", +}; + +static const char * const hsspi_cs7_groups[] = { + "gpio9", +}; + +static const char * const uart1_scts_groups[] = { + "gpio10", + "gpio24", +}; + +static const char * const uart1_srts_groups[] = { + "gpio11", + "gpio25", +}; + +static const char * const uart1_sdin_groups[] = { + "gpio12", + "gpio26", +}; + +static const char * const uart1_sdout_groups[] = { + "gpio13", + "gpio27", +}; + +static const char * const ntr_pulse_in_groups[] = { + "gpio14", + "gpio28", +}; + +static const char * const dsl_ntr_pulse_out_groups[] = { + "gpio15", + "gpio29", +}; + +static const char * const adsl_spi_miso_groups[] = { + "gpio18", +}; + +static const char * const adsl_spi_mosi_groups[] = { + "gpio19", +}; + +static const char * const vreg_clk_groups[] = { + "gpio22", +}; + +static const char * const pcie_clkreq_b_groups[] = { + "gpio23", +}; + +static const char * const switch_led_clk_groups[] = { + "gpio30", +}; + +static const char * const switch_led_data_groups[] = { + "gpio31", +}; + +static const char * const wifi_groups[] = { + "gpio32", + "gpio33", + "gpio34", + "gpio35", + "gpio36", + "gpio37", + "gpio38", + "gpio39", + "gpio40", + "gpio41", + "gpio42", + "gpio43", + "gpio44", + "gpio45", + "gpio46", + "gpio47", + "gpio48", + "gpio49", + "gpio50", + "gpio51", +}; + +static const char * const nand_groups[] = { + "nand_grp", +}; + +static const char * const dectpd_groups[] = { + "dectpd_grp", +}; + +static const char * const vdsl_phy_override_0_groups[] = { + "vdsl_phy_override_0_grp", +}; + +static const char * const vdsl_phy_override_1_groups[] = { + "vdsl_phy_override_1_grp", +}; + +static const char * const vdsl_phy_override_2_groups[] = { + "vdsl_phy_override_2_grp", +}; + +static const char * const vdsl_phy_override_3_groups[] = { + "vdsl_phy_override_3_grp", +}; + +#define BCM63268_LED_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .reg = BCM63268_LEDCTRL, \ + } + +#define BCM63268_MODE_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .reg = BCM63268_MODE, \ + } + +#define BCM63268_CTRL_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .reg = BCM63268_CTRL, \ + } + +#define BCM63268_BASEMODE_FUN(n, val) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .reg = BCM63268_BASEMODE, \ + .mask = val, \ + } + +static const struct bcm63268_function bcm63268_funcs[] = { + BCM63268_LED_FUN(led), + BCM63268_MODE_FUN(serial_led_clk), + BCM63268_MODE_FUN(serial_led_data), + BCM63268_MODE_FUN(hsspi_cs6), + BCM63268_MODE_FUN(hsspi_cs7), + BCM63268_MODE_FUN(uart1_scts), + BCM63268_MODE_FUN(uart1_srts), + BCM63268_MODE_FUN(uart1_sdin), + BCM63268_MODE_FUN(uart1_sdout), + BCM63268_MODE_FUN(ntr_pulse_in), + BCM63268_MODE_FUN(dsl_ntr_pulse_out), + BCM63268_MODE_FUN(hsspi_cs4), + BCM63268_MODE_FUN(hsspi_cs5), + BCM63268_MODE_FUN(adsl_spi_miso), + BCM63268_MODE_FUN(adsl_spi_mosi), + BCM63268_MODE_FUN(vreg_clk), + BCM63268_MODE_FUN(pcie_clkreq_b), + BCM63268_MODE_FUN(switch_led_clk), + BCM63268_MODE_FUN(switch_led_data), + BCM63268_CTRL_FUN(wifi), + BCM63268_BASEMODE_FUN(nand, BCM63268_BASEMODE_NAND), + BCM63268_BASEMODE_FUN(dectpd, BCM63268_BASEMODE_DECTPD), + BCM63268_BASEMODE_FUN(vdsl_phy_override_0, + BCM63268_BASEMODE_VDSL_PHY_0), + BCM63268_BASEMODE_FUN(vdsl_phy_override_1, + BCM63268_BASEMODE_VDSL_PHY_1), + BCM63268_BASEMODE_FUN(vdsl_phy_override_2, + BCM63268_BASEMODE_VDSL_PHY_2), + BCM63268_BASEMODE_FUN(vdsl_phy_override_3, + BCM63268_BASEMODE_VDSL_PHY_3), +}; + +static int bcm63268_pinctrl_get_group_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm63268_groups); +} + +static const char *bcm63268_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned group) +{ + return bcm63268_groups[group].name; +} + +static int bcm63268_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned group, + const unsigned **pins, + unsigned *num_pins) +{ + *pins = bcm63268_groups[group].pins; + *num_pins = bcm63268_groups[group].num_pins; + + return 0; +} + +static int bcm63268_pinctrl_get_func_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm63268_funcs); +} + +static const char *bcm63268_pinctrl_get_func_name(struct pinctrl_dev *pctldev, + unsigned selector) +{ + return bcm63268_funcs[selector].name; +} + +static int bcm63268_pinctrl_get_groups(struct pinctrl_dev *pctldev, + unsigned selector, + const char * const **groups, + unsigned * const num_groups) +{ + *groups = bcm63268_funcs[selector].groups; + *num_groups = bcm63268_funcs[selector].num_groups; + + return 0; +} + +static void bcm63268_set_gpio(struct bcm63xx_pinctrl *pc, unsigned pin) +{ + const struct pinctrl_pin_desc *desc = &bcm63268_pins[pin]; + unsigned int basemode = (unsigned long) desc->drv_data; + unsigned int mask = BIT(bcm63xx_bank_pin(pin)); + + if (basemode) + regmap_update_bits(pc->regs, BCM63268_BASEMODE_REG, basemode, + 0); + + if (pin < BCM63XX_BANK_GPIOS) { + /* base mode: 0 => gpio, 1 => mux function */ + regmap_update_bits(pc->regs, BCM63268_MODE_REG, mask, 0); + + /* pins 0-23 might be muxed to led */ + if (pin < BCM63268_NUM_LEDS) + regmap_update_bits(pc->regs, BCM63268_LED_REG, mask, + 0); + } else if (pin < BCM63268_NUM_GPIOS) { + /* ctrl reg: 0 => wifi function, 1 => gpio */ + regmap_update_bits(pc->regs, BCM63268_CTRL_REG, mask, mask); + } +} + +static int bcm63268_pinctrl_set_mux(struct pinctrl_dev *pctldev, + unsigned selector, unsigned group) +{ + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + const struct bcm63268_pingroup *pg = &bcm63268_groups[group]; + const struct bcm63268_function *f = &bcm63268_funcs[selector]; + unsigned i; + unsigned int reg; + unsigned int val, mask; + + for (i = 0; i < pg->num_pins; i++) + bcm63268_set_gpio(pc, pg->pins[i]); + + switch (f->reg) { + case BCM63268_LEDCTRL: + reg = BCM63268_LED_REG; + mask = BIT(pg->pins[0]); + val = BIT(pg->pins[0]); + break; + case BCM63268_MODE: + reg = BCM63268_MODE_REG; + mask = BIT(pg->pins[0]); + val = BIT(pg->pins[0]); + break; + case BCM63268_CTRL: + reg = BCM63268_CTRL_REG; + mask = BIT(pg->pins[0]); + val = 0; + break; + case BCM63268_BASEMODE: + reg = BCM63268_BASEMODE_REG; + mask = f->mask; + val = f->mask; + break; + default: + WARN_ON(1); + return -EINVAL; + } + + regmap_update_bits(pc->regs, reg, mask, val); + + return 0; +} + +static int bcm63268_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) +{ + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + + /* disable all functions using this pin */ + bcm63268_set_gpio(pc, offset); + + return 0; +} + +static struct pinctrl_ops bcm63268_pctl_ops = { + .dt_free_map = pinctrl_utils_free_map, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .get_group_name = bcm63268_pinctrl_get_group_name, + .get_group_pins = bcm63268_pinctrl_get_group_pins, + .get_groups_count = bcm63268_pinctrl_get_group_count, +}; + +static struct pinmux_ops bcm63268_pmx_ops = { + .get_function_groups = bcm63268_pinctrl_get_groups, + .get_function_name = bcm63268_pinctrl_get_func_name, + .get_functions_count = bcm63268_pinctrl_get_func_count, + .gpio_request_enable = bcm63268_gpio_request_enable, + .set_mux = bcm63268_pinctrl_set_mux, + .strict = true, +}; + +static const struct bcm63xx_pinctrl_soc bcm63268_soc = { + .ngpios = BCM63268_NUM_GPIOS, + .npins = ARRAY_SIZE(bcm63268_pins), + .pctl_ops = &bcm63268_pctl_ops, + .pins = bcm63268_pins, + .pmx_ops = &bcm63268_pmx_ops, +}; + +static int bcm63268_pinctrl_probe(struct platform_device *pdev) +{ + return bcm63xx_pinctrl_probe(pdev, &bcm63268_soc, NULL); +} + +static const struct of_device_id bcm63268_pinctrl_match[] = { + { .compatible = "brcm,bcm63268-pinctrl", }, + { /* sentinel */ } +}; + +static struct platform_driver bcm63268_pinctrl_driver = { + .probe = bcm63268_pinctrl_probe, + .driver = { + .name = "bcm63268-pinctrl", + .of_match_table = bcm63268_pinctrl_match, + }, +}; + +builtin_platform_driver(bcm63268_pinctrl_driver); diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6328.c b/drivers/pinctrl/bcm/pinctrl-bcm6328.c new file mode 100644 index 000000000000..c9efce600550 --- /dev/null +++ b/drivers/pinctrl/bcm/pinctrl-bcm6328.c @@ -0,0 +1,404 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for BCM6328 GPIO unit (pinctrl + GPIO) + * + * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com> + * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com> + */ + +#include <linux/bits.h> +#include <linux/gpio/driver.h> +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/pinctrl/pinmux.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include "../pinctrl-utils.h" + +#include "pinctrl-bcm63xx.h" + +#define BCM6328_NUM_GPIOS 32 + +#define BCM6328_MODE_REG 0x18 +#define BCM6328_MUX_HI_REG 0x1c +#define BCM6328_MUX_LO_REG 0x20 +#define BCM6328_MUX_OTHER_REG 0x24 +#define BCM6328_MUX_MASK GENMASK(1, 0) + +struct bcm6328_pingroup { + const char *name; + const unsigned * const pins; + const unsigned num_pins; +}; + +struct bcm6328_function { + const char *name; + const char * const *groups; + const unsigned num_groups; + + unsigned mode_val:1; + unsigned mux_val:2; +}; + +static const unsigned int bcm6328_mux[] = { + BCM6328_MUX_LO_REG, + BCM6328_MUX_HI_REG, + BCM6328_MUX_OTHER_REG +}; + +static const struct pinctrl_pin_desc bcm6328_pins[] = { + PINCTRL_PIN(0, "gpio0"), + PINCTRL_PIN(1, "gpio1"), + PINCTRL_PIN(2, "gpio2"), + PINCTRL_PIN(3, "gpio3"), + PINCTRL_PIN(4, "gpio4"), + PINCTRL_PIN(5, "gpio5"), + PINCTRL_PIN(6, "gpio6"), + PINCTRL_PIN(7, "gpio7"), + PINCTRL_PIN(8, "gpio8"), + PINCTRL_PIN(9, "gpio9"), + PINCTRL_PIN(10, "gpio10"), + PINCTRL_PIN(11, "gpio11"), + PINCTRL_PIN(12, "gpio12"), + PINCTRL_PIN(13, "gpio13"), + PINCTRL_PIN(14, "gpio14"), + PINCTRL_PIN(15, "gpio15"), + PINCTRL_PIN(16, "gpio16"), + PINCTRL_PIN(17, "gpio17"), + PINCTRL_PIN(18, "gpio18"), + PINCTRL_PIN(19, "gpio19"), + PINCTRL_PIN(20, "gpio20"), + PINCTRL_PIN(21, "gpio21"), + PINCTRL_PIN(22, "gpio22"), + PINCTRL_PIN(23, "gpio23"), + PINCTRL_PIN(24, "gpio24"), + PINCTRL_PIN(25, "gpio25"), + PINCTRL_PIN(26, "gpio26"), + PINCTRL_PIN(27, "gpio27"), + PINCTRL_PIN(28, "gpio28"), + PINCTRL_PIN(29, "gpio29"), + PINCTRL_PIN(30, "gpio30"), + PINCTRL_PIN(31, "gpio31"), + + /* + * No idea where they really are; so let's put them according + * to their mux offsets. + */ + PINCTRL_PIN(36, "hsspi_cs1"), + PINCTRL_PIN(38, "usb_p2"), +}; + +static unsigned gpio0_pins[] = { 0 }; +static unsigned gpio1_pins[] = { 1 }; +static unsigned gpio2_pins[] = { 2 }; +static unsigned gpio3_pins[] = { 3 }; +static unsigned gpio4_pins[] = { 4 }; +static unsigned gpio5_pins[] = { 5 }; +static unsigned gpio6_pins[] = { 6 }; +static unsigned gpio7_pins[] = { 7 }; +static unsigned gpio8_pins[] = { 8 }; +static unsigned gpio9_pins[] = { 9 }; +static unsigned gpio10_pins[] = { 10 }; +static unsigned gpio11_pins[] = { 11 }; +static unsigned gpio12_pins[] = { 12 }; +static unsigned gpio13_pins[] = { 13 }; +static unsigned gpio14_pins[] = { 14 }; +static unsigned gpio15_pins[] = { 15 }; +static unsigned gpio16_pins[] = { 16 }; +static unsigned gpio17_pins[] = { 17 }; +static unsigned gpio18_pins[] = { 18 }; +static unsigned gpio19_pins[] = { 19 }; +static unsigned gpio20_pins[] = { 20 }; +static unsigned gpio21_pins[] = { 21 }; +static unsigned gpio22_pins[] = { 22 }; +static unsigned gpio23_pins[] = { 23 }; +static unsigned gpio24_pins[] = { 24 }; +static unsigned gpio25_pins[] = { 25 }; +static unsigned gpio26_pins[] = { 26 }; +static unsigned gpio27_pins[] = { 27 }; +static unsigned gpio28_pins[] = { 28 }; +static unsigned gpio29_pins[] = { 29 }; +static unsigned gpio30_pins[] = { 30 }; +static unsigned gpio31_pins[] = { 31 }; + +static unsigned hsspi_cs1_pins[] = { 36 }; +static unsigned usb_port1_pins[] = { 38 }; + +#define BCM6328_GROUP(n) \ + { \ + .name = #n, \ + .pins = n##_pins, \ + .num_pins = ARRAY_SIZE(n##_pins), \ + } + +static struct bcm6328_pingroup bcm6328_groups[] = { + BCM6328_GROUP(gpio0), + BCM6328_GROUP(gpio1), + BCM6328_GROUP(gpio2), + BCM6328_GROUP(gpio3), + BCM6328_GROUP(gpio4), + BCM6328_GROUP(gpio5), + BCM6328_GROUP(gpio6), + BCM6328_GROUP(gpio7), + BCM6328_GROUP(gpio8), + BCM6328_GROUP(gpio9), + BCM6328_GROUP(gpio10), + BCM6328_GROUP(gpio11), + BCM6328_GROUP(gpio12), + BCM6328_GROUP(gpio13), + BCM6328_GROUP(gpio14), + BCM6328_GROUP(gpio15), + BCM6328_GROUP(gpio16), + BCM6328_GROUP(gpio17), + BCM6328_GROUP(gpio18), + BCM6328_GROUP(gpio19), + BCM6328_GROUP(gpio20), + BCM6328_GROUP(gpio21), + BCM6328_GROUP(gpio22), + BCM6328_GROUP(gpio23), + BCM6328_GROUP(gpio24), + BCM6328_GROUP(gpio25), + BCM6328_GROUP(gpio26), + BCM6328_GROUP(gpio27), + BCM6328_GROUP(gpio28), + BCM6328_GROUP(gpio29), + BCM6328_GROUP(gpio30), + BCM6328_GROUP(gpio31), + + BCM6328_GROUP(hsspi_cs1), + BCM6328_GROUP(usb_port1), +}; + +/* GPIO_MODE */ +static const char * const led_groups[] = { + "gpio0", + "gpio1", + "gpio2", + "gpio3", + "gpio4", + "gpio5", + "gpio6", + "gpio7", + "gpio8", + "gpio9", + "gpio10", + "gpio11", + "gpio12", + "gpio13", + "gpio14", + "gpio15", + "gpio16", + "gpio17", + "gpio18", + "gpio19", + "gpio20", + "gpio21", + "gpio22", + "gpio23", +}; + +/* PINMUX_SEL */ +static const char * const serial_led_data_groups[] = { + "gpio6", +}; + +static const char * const serial_led_clk_groups[] = { + "gpio7", +}; + +static const char * const inet_act_led_groups[] = { + "gpio11", +}; + +static const char * const pcie_clkreq_groups[] = { + "gpio16", +}; + +static const char * const ephy0_act_led_groups[] = { + "gpio25", +}; + +static const char * const ephy1_act_led_groups[] = { + "gpio26", +}; + +static const char * const ephy2_act_led_groups[] = { + "gpio27", +}; + +static const char * const ephy3_act_led_groups[] = { + "gpio28", +}; + +static const char * const hsspi_cs1_groups[] = { + "hsspi_cs1" +}; + +static const char * const usb_host_port_groups[] = { + "usb_port1", +}; + +static const char * const usb_device_port_groups[] = { + "usb_port1", +}; + +#define BCM6328_MODE_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .mode_val = 1, \ + } + +#define BCM6328_MUX_FUN(n, mux) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .mux_val = mux, \ + } + +static const struct bcm6328_function bcm6328_funcs[] = { + BCM6328_MODE_FUN(led), + BCM6328_MUX_FUN(serial_led_data, 2), + BCM6328_MUX_FUN(serial_led_clk, 2), + BCM6328_MUX_FUN(inet_act_led, 1), + BCM6328_MUX_FUN(pcie_clkreq, 2), + BCM6328_MUX_FUN(ephy0_act_led, 1), + BCM6328_MUX_FUN(ephy1_act_led, 1), + BCM6328_MUX_FUN(ephy2_act_led, 1), + BCM6328_MUX_FUN(ephy3_act_led, 1), + BCM6328_MUX_FUN(hsspi_cs1, 2), + BCM6328_MUX_FUN(usb_host_port, 1), + BCM6328_MUX_FUN(usb_device_port, 2), +}; + +static inline unsigned int bcm6328_mux_off(unsigned int pin) +{ + return bcm6328_mux[pin / 16]; +} + +static int bcm6328_pinctrl_get_group_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6328_groups); +} + +static const char *bcm6328_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned group) +{ + return bcm6328_groups[group].name; +} + +static int bcm6328_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned group, const unsigned **pins, + unsigned *num_pins) +{ + *pins = bcm6328_groups[group].pins; + *num_pins = bcm6328_groups[group].num_pins; + + return 0; +} + +static int bcm6328_pinctrl_get_func_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6328_funcs); +} + +static const char *bcm6328_pinctrl_get_func_name(struct pinctrl_dev *pctldev, + unsigned selector) +{ + return bcm6328_funcs[selector].name; +} + +static int bcm6328_pinctrl_get_groups(struct pinctrl_dev *pctldev, + unsigned selector, + const char * const **groups, + unsigned * const num_groups) +{ + *groups = bcm6328_funcs[selector].groups; + *num_groups = bcm6328_funcs[selector].num_groups; + + return 0; +} + +static void bcm6328_rmw_mux(struct bcm63xx_pinctrl *pc, unsigned pin, + unsigned int mode, unsigned int mux) +{ + if (pin < BCM6328_NUM_GPIOS) + regmap_update_bits(pc->regs, BCM6328_MODE_REG, BIT(pin), + mode ? BIT(pin) : 0); + + regmap_update_bits(pc->regs, bcm6328_mux_off(pin), + BCM6328_MUX_MASK << ((pin % 16) * 2), + mux << ((pin % 16) * 2)); +} + +static int bcm6328_pinctrl_set_mux(struct pinctrl_dev *pctldev, + unsigned selector, unsigned group) +{ + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + const struct bcm6328_pingroup *pg = &bcm6328_groups[group]; + const struct bcm6328_function *f = &bcm6328_funcs[selector]; + + bcm6328_rmw_mux(pc, pg->pins[0], f->mode_val, f->mux_val); + + return 0; +} + +static int bcm6328_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) +{ + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + + /* disable all functions using this pin */ + bcm6328_rmw_mux(pc, offset, 0, 0); + + return 0; +} + +static struct pinctrl_ops bcm6328_pctl_ops = { + .dt_free_map = pinctrl_utils_free_map, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .get_group_name = bcm6328_pinctrl_get_group_name, + .get_group_pins = bcm6328_pinctrl_get_group_pins, + .get_groups_count = bcm6328_pinctrl_get_group_count, +}; + +static struct pinmux_ops bcm6328_pmx_ops = { + .get_function_groups = bcm6328_pinctrl_get_groups, + .get_function_name = bcm6328_pinctrl_get_func_name, + .get_functions_count = bcm6328_pinctrl_get_func_count, + .gpio_request_enable = bcm6328_gpio_request_enable, + .set_mux = bcm6328_pinctrl_set_mux, + .strict = true, +}; + +static const struct bcm63xx_pinctrl_soc bcm6328_soc = { + .ngpios = BCM6328_NUM_GPIOS, + .npins = ARRAY_SIZE(bcm6328_pins), + .pctl_ops = &bcm6328_pctl_ops, + .pins = bcm6328_pins, + .pmx_ops = &bcm6328_pmx_ops, +}; + +static int bcm6328_pinctrl_probe(struct platform_device *pdev) +{ + return bcm63xx_pinctrl_probe(pdev, &bcm6328_soc, NULL); +} + +static const struct of_device_id bcm6328_pinctrl_match[] = { + { .compatible = "brcm,bcm6328-pinctrl", }, + { /* sentinel */ } +}; + +static struct platform_driver bcm6328_pinctrl_driver = { + .probe = bcm6328_pinctrl_probe, + .driver = { + .name = "bcm6328-pinctrl", + .of_match_table = bcm6328_pinctrl_match, + }, +}; + +builtin_platform_driver(bcm6328_pinctrl_driver); diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6358.c b/drivers/pinctrl/bcm/pinctrl-bcm6358.c new file mode 100644 index 000000000000..d638578727f3 --- /dev/null +++ b/drivers/pinctrl/bcm/pinctrl-bcm6358.c @@ -0,0 +1,369 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for BCM6358 GPIO unit (pinctrl + GPIO) + * + * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com> + * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com> + */ + +#include <linux/bits.h> +#include <linux/gpio/driver.h> +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/pinctrl/pinmux.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include "../pinctrl-utils.h" + +#include "pinctrl-bcm63xx.h" + +#define BCM6358_NUM_GPIOS 40 + +#define BCM6358_MODE_REG 0x18 +#define BCM6358_MODE_MUX_NONE 0 +#define BCM6358_MODE_MUX_EBI_CS BIT(5) +#define BCM6358_MODE_MUX_UART1 BIT(6) +#define BCM6358_MODE_MUX_SPI_CS BIT(7) +#define BCM6358_MODE_MUX_ASYNC_MODEM BIT(8) +#define BCM6358_MODE_MUX_LEGACY_LED BIT(9) +#define BCM6358_MODE_MUX_SERIAL_LED BIT(10) +#define BCM6358_MODE_MUX_LED BIT(11) +#define BCM6358_MODE_MUX_UTOPIA BIT(12) +#define BCM6358_MODE_MUX_CLKRST BIT(13) +#define BCM6358_MODE_MUX_PWM_SYN_CLK BIT(14) +#define BCM6358_MODE_MUX_SYS_IRQ BIT(15) + +struct bcm6358_pingroup { + const char *name; + const unsigned * const pins; + const unsigned num_pins; + + const uint16_t mode_val; + + /* non-GPIO function muxes require the gpio direction to be set */ + const uint16_t direction; +}; + +struct bcm6358_function { + const char *name; + const char * const *groups; + const unsigned num_groups; +}; + +struct bcm6358_priv { + struct regmap_field *overlays; +}; + +#define BCM6358_GPIO_PIN(a, b, bit1, bit2, bit3) \ + { \ + .number = a, \ + .name = b, \ + .drv_data = (void *)(BCM6358_MODE_MUX_##bit1 | \ + BCM6358_MODE_MUX_##bit2 | \ + BCM6358_MODE_MUX_##bit3), \ + } + +static const struct pinctrl_pin_desc bcm6358_pins[] = { + BCM6358_GPIO_PIN(0, "gpio0", LED, NONE, NONE), + BCM6358_GPIO_PIN(1, "gpio1", LED, NONE, NONE), + BCM6358_GPIO_PIN(2, "gpio2", LED, NONE, NONE), + BCM6358_GPIO_PIN(3, "gpio3", LED, NONE, NONE), + PINCTRL_PIN(4, "gpio4"), + BCM6358_GPIO_PIN(5, "gpio5", SYS_IRQ, NONE, NONE), + BCM6358_GPIO_PIN(6, "gpio6", SERIAL_LED, NONE, NONE), + BCM6358_GPIO_PIN(7, "gpio7", SERIAL_LED, NONE, NONE), + BCM6358_GPIO_PIN(8, "gpio8", PWM_SYN_CLK, NONE, NONE), + BCM6358_GPIO_PIN(9, "gpio09", LEGACY_LED, NONE, NONE), + BCM6358_GPIO_PIN(10, "gpio10", LEGACY_LED, NONE, NONE), + BCM6358_GPIO_PIN(11, "gpio11", LEGACY_LED, NONE, NONE), + BCM6358_GPIO_PIN(12, "gpio12", LEGACY_LED, ASYNC_MODEM, UTOPIA), + BCM6358_GPIO_PIN(13, "gpio13", LEGACY_LED, ASYNC_MODEM, UTOPIA), + BCM6358_GPIO_PIN(14, "gpio14", LEGACY_LED, ASYNC_MODEM, UTOPIA), + BCM6358_GPIO_PIN(15, "gpio15", LEGACY_LED, ASYNC_MODEM, UTOPIA), + PINCTRL_PIN(16, "gpio16"), + PINCTRL_PIN(17, "gpio17"), + PINCTRL_PIN(18, "gpio18"), + PINCTRL_PIN(19, "gpio19"), + PINCTRL_PIN(20, "gpio20"), + PINCTRL_PIN(21, "gpio21"), + BCM6358_GPIO_PIN(22, "gpio22", UTOPIA, NONE, NONE), + BCM6358_GPIO_PIN(23, "gpio23", UTOPIA, NONE, NONE), + BCM6358_GPIO_PIN(24, "gpio24", UTOPIA, NONE, NONE), + BCM6358_GPIO_PIN(25, "gpio25", UTOPIA, NONE, NONE), + BCM6358_GPIO_PIN(26, "gpio26", UTOPIA, NONE, NONE), + BCM6358_GPIO_PIN(27, "gpio27", UTOPIA, NONE, NONE), + BCM6358_GPIO_PIN(28, "gpio28", UTOPIA, UART1, NONE), + BCM6358_GPIO_PIN(29, "gpio29", UTOPIA, UART1, NONE), + BCM6358_GPIO_PIN(30, "gpio30", UTOPIA, UART1, EBI_CS), + BCM6358_GPIO_PIN(31, "gpio31", UTOPIA, UART1, EBI_CS), + BCM6358_GPIO_PIN(32, "gpio32", SPI_CS, NONE, NONE), + BCM6358_GPIO_PIN(33, "gpio33", SPI_CS, NONE, NONE), + PINCTRL_PIN(34, "gpio34"), + PINCTRL_PIN(35, "gpio35"), + PINCTRL_PIN(36, "gpio36"), + PINCTRL_PIN(37, "gpio37"), + PINCTRL_PIN(38, "gpio38"), + PINCTRL_PIN(39, "gpio39"), +}; + +static unsigned ebi_cs_grp_pins[] = { 30, 31 }; + +static unsigned uart1_grp_pins[] = { 28, 29, 30, 31 }; + +static unsigned spi_cs_grp_pins[] = { 32, 33 }; + +static unsigned async_modem_grp_pins[] = { 12, 13, 14, 15 }; + +static unsigned serial_led_grp_pins[] = { 6, 7 }; + +static unsigned legacy_led_grp_pins[] = { 9, 10, 11, 12, 13, 14, 15 }; + +static unsigned led_grp_pins[] = { 0, 1, 2, 3 }; + +static unsigned utopia_grp_pins[] = { + 12, 13, 14, 15, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, +}; + +static unsigned pwm_syn_clk_grp_pins[] = { 8 }; + +static unsigned sys_irq_grp_pins[] = { 5 }; + +#define BCM6358_GPIO_MUX_GROUP(n, bit, dir) \ + { \ + .name = #n, \ + .pins = n##_pins, \ + .num_pins = ARRAY_SIZE(n##_pins), \ + .mode_val = BCM6358_MODE_MUX_##bit, \ + .direction = dir, \ + } + +static const struct bcm6358_pingroup bcm6358_groups[] = { + BCM6358_GPIO_MUX_GROUP(ebi_cs_grp, EBI_CS, 0x3), + BCM6358_GPIO_MUX_GROUP(uart1_grp, UART1, 0x2), + BCM6358_GPIO_MUX_GROUP(spi_cs_grp, SPI_CS, 0x6), + BCM6358_GPIO_MUX_GROUP(async_modem_grp, ASYNC_MODEM, 0x6), + BCM6358_GPIO_MUX_GROUP(legacy_led_grp, LEGACY_LED, 0x7f), + BCM6358_GPIO_MUX_GROUP(serial_led_grp, SERIAL_LED, 0x3), + BCM6358_GPIO_MUX_GROUP(led_grp, LED, 0xf), + BCM6358_GPIO_MUX_GROUP(utopia_grp, UTOPIA, 0x000f), + BCM6358_GPIO_MUX_GROUP(pwm_syn_clk_grp, PWM_SYN_CLK, 0x1), + BCM6358_GPIO_MUX_GROUP(sys_irq_grp, SYS_IRQ, 0x1), +}; + +static const char * const ebi_cs_groups[] = { + "ebi_cs_grp" +}; + +static const char * const uart1_groups[] = { + "uart1_grp" +}; + +static const char * const spi_cs_2_3_groups[] = { + "spi_cs_2_3_grp" +}; + +static const char * const async_modem_groups[] = { + "async_modem_grp" +}; + +static const char * const legacy_led_groups[] = { + "legacy_led_grp", +}; + +static const char * const serial_led_groups[] = { + "serial_led_grp", +}; + +static const char * const led_groups[] = { + "led_grp", +}; + +static const char * const clkrst_groups[] = { + "clkrst_grp", +}; + +static const char * const pwm_syn_clk_groups[] = { + "pwm_syn_clk_grp", +}; + +static const char * const sys_irq_groups[] = { + "sys_irq_grp", +}; + +#define BCM6358_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + } + +static const struct bcm6358_function bcm6358_funcs[] = { + BCM6358_FUN(ebi_cs), + BCM6358_FUN(uart1), + BCM6358_FUN(spi_cs_2_3), + BCM6358_FUN(async_modem), + BCM6358_FUN(legacy_led), + BCM6358_FUN(serial_led), + BCM6358_FUN(led), + BCM6358_FUN(clkrst), + BCM6358_FUN(pwm_syn_clk), + BCM6358_FUN(sys_irq), +}; + +static int bcm6358_pinctrl_get_group_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6358_groups); +} + +static const char *bcm6358_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned group) +{ + return bcm6358_groups[group].name; +} + +static int bcm6358_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned group, const unsigned **pins, + unsigned *num_pins) +{ + *pins = bcm6358_groups[group].pins; + *num_pins = bcm6358_groups[group].num_pins; + + return 0; +} + +static int bcm6358_pinctrl_get_func_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6358_funcs); +} + +static const char *bcm6358_pinctrl_get_func_name(struct pinctrl_dev *pctldev, + unsigned selector) +{ + return bcm6358_funcs[selector].name; +} + +static int bcm6358_pinctrl_get_groups(struct pinctrl_dev *pctldev, + unsigned selector, + const char * const **groups, + unsigned * const num_groups) +{ + *groups = bcm6358_funcs[selector].groups; + *num_groups = bcm6358_funcs[selector].num_groups; + + return 0; +} + +static int bcm6358_pinctrl_set_mux(struct pinctrl_dev *pctldev, + unsigned selector, unsigned group) +{ + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + struct bcm6358_priv *priv = pc->driver_data; + const struct bcm6358_pingroup *pg = &bcm6358_groups[group]; + unsigned int val = pg->mode_val; + unsigned int mask = val; + unsigned pin; + + for (pin = 0; pin < pg->num_pins; pin++) + mask |= (unsigned long)bcm6358_pins[pin].drv_data; + + regmap_field_update_bits(priv->overlays, mask, val); + + for (pin = 0; pin < pg->num_pins; pin++) { + struct pinctrl_gpio_range *range; + unsigned int hw_gpio = bcm6358_pins[pin].number; + + range = pinctrl_find_gpio_range_from_pin(pctldev, hw_gpio); + if (range) { + struct gpio_chip *gc = range->gc; + + if (pg->direction & BIT(pin)) + gc->direction_output(gc, hw_gpio, 0); + else + gc->direction_input(gc, hw_gpio); + } + } + + return 0; +} + +static int bcm6358_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) +{ + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + struct bcm6358_priv *priv = pc->driver_data; + unsigned int mask; + + mask = (unsigned long) bcm6358_pins[offset].drv_data; + if (!mask) + return 0; + + /* disable all functions using this pin */ + return regmap_field_update_bits(priv->overlays, mask, 0); +} + +static struct pinctrl_ops bcm6358_pctl_ops = { + .dt_free_map = pinctrl_utils_free_map, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .get_group_name = bcm6358_pinctrl_get_group_name, + .get_group_pins = bcm6358_pinctrl_get_group_pins, + .get_groups_count = bcm6358_pinctrl_get_group_count, +}; + +static struct pinmux_ops bcm6358_pmx_ops = { + .get_function_groups = bcm6358_pinctrl_get_groups, + .get_function_name = bcm6358_pinctrl_get_func_name, + .get_functions_count = bcm6358_pinctrl_get_func_count, + .gpio_request_enable = bcm6358_gpio_request_enable, + .set_mux = bcm6358_pinctrl_set_mux, + .strict = true, +}; + +static const struct bcm63xx_pinctrl_soc bcm6358_soc = { + .ngpios = BCM6358_NUM_GPIOS, + .npins = ARRAY_SIZE(bcm6358_pins), + .pctl_ops = &bcm6358_pctl_ops, + .pins = bcm6358_pins, + .pmx_ops = &bcm6358_pmx_ops, +}; + +static int bcm6358_pinctrl_probe(struct platform_device *pdev) +{ + struct reg_field overlays = REG_FIELD(BCM6358_MODE_REG, 0, 15); + struct device *dev = &pdev->dev; + struct bcm63xx_pinctrl *pc; + struct bcm6358_priv *priv; + int err; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + err = bcm63xx_pinctrl_probe(pdev, &bcm6358_soc, (void *) priv); + if (err) + return err; + + pc = platform_get_drvdata(pdev); + + priv->overlays = devm_regmap_field_alloc(dev, pc->regs, overlays); + if (IS_ERR(priv->overlays)) + return PTR_ERR(priv->overlays); + + return 0; +} + +static const struct of_device_id bcm6358_pinctrl_match[] = { + { .compatible = "brcm,bcm6358-pinctrl", }, + { /* sentinel */ } +}; + +static struct platform_driver bcm6358_pinctrl_driver = { + .probe = bcm6358_pinctrl_probe, + .driver = { + .name = "bcm6358-pinctrl", + .of_match_table = bcm6358_pinctrl_match, + }, +}; + +builtin_platform_driver(bcm6358_pinctrl_driver); diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6362.c b/drivers/pinctrl/bcm/pinctrl-bcm6362.c new file mode 100644 index 000000000000..eb7ec80353e9 --- /dev/null +++ b/drivers/pinctrl/bcm/pinctrl-bcm6362.c @@ -0,0 +1,617 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for BCM6362 GPIO unit (pinctrl + GPIO) + * + * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com> + * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com> + */ + +#include <linux/bits.h> +#include <linux/gpio/driver.h> +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/pinctrl/pinmux.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include "../pinctrl-utils.h" + +#include "pinctrl-bcm63xx.h" + +#define BCM6362_BANK_GPIOS 32 +#define BCM6362_NUM_GPIOS 48 +#define BCM6362_NUM_LEDS 24 + +#define BCM6362_LED_REG 0x10 +#define BCM6362_MODE_REG 0x18 +#define BCM6362_CTRL_REG 0x1c +#define BCM6362_BASEMODE_REG 0x38 +#define BASEMODE_NAND BIT(2) + +enum bcm6362_pinctrl_reg { + BCM6362_LEDCTRL, + BCM6362_MODE, + BCM6362_CTRL, + BCM6362_BASEMODE, +}; + +struct bcm6362_pingroup { + const char *name; + const unsigned * const pins; + const unsigned num_pins; +}; + +struct bcm6362_function { + const char *name; + const char * const *groups; + const unsigned num_groups; + + enum bcm6362_pinctrl_reg reg; + uint32_t basemode_mask; +}; + +#define BCM6362_PIN(a, b, mask) \ + { \ + .number = a, \ + .name = b, \ + .drv_data = (void *)(mask), \ + } + +static const struct pinctrl_pin_desc bcm6362_pins[] = { + PINCTRL_PIN(0, "gpio0"), + PINCTRL_PIN(1, "gpio1"), + PINCTRL_PIN(2, "gpio2"), + PINCTRL_PIN(3, "gpio3"), + PINCTRL_PIN(4, "gpio4"), + PINCTRL_PIN(5, "gpio5"), + PINCTRL_PIN(6, "gpio6"), + PINCTRL_PIN(7, "gpio7"), + BCM6362_PIN(8, "gpio8", BASEMODE_NAND), + PINCTRL_PIN(9, "gpio9"), + PINCTRL_PIN(10, "gpio10"), + PINCTRL_PIN(11, "gpio11"), + BCM6362_PIN(12, "gpio12", BASEMODE_NAND), + BCM6362_PIN(13, "gpio13", BASEMODE_NAND), + BCM6362_PIN(14, "gpio14", BASEMODE_NAND), + BCM6362_PIN(15, "gpio15", BASEMODE_NAND), + BCM6362_PIN(16, "gpio16", BASEMODE_NAND), + BCM6362_PIN(17, "gpio17", BASEMODE_NAND), + BCM6362_PIN(18, "gpio18", BASEMODE_NAND), + BCM6362_PIN(19, "gpio19", BASEMODE_NAND), + BCM6362_PIN(20, "gpio20", BASEMODE_NAND), + BCM6362_PIN(21, "gpio21", BASEMODE_NAND), + BCM6362_PIN(22, "gpio22", BASEMODE_NAND), + BCM6362_PIN(23, "gpio23", BASEMODE_NAND), + PINCTRL_PIN(24, "gpio24"), + PINCTRL_PIN(25, "gpio25"), + PINCTRL_PIN(26, "gpio26"), + BCM6362_PIN(27, "gpio27", BASEMODE_NAND), + PINCTRL_PIN(28, "gpio28"), + PINCTRL_PIN(29, "gpio29"), + PINCTRL_PIN(30, "gpio30"), + PINCTRL_PIN(31, "gpio31"), + PINCTRL_PIN(32, "gpio32"), + PINCTRL_PIN(33, "gpio33"), + PINCTRL_PIN(34, "gpio34"), + PINCTRL_PIN(35, "gpio35"), + PINCTRL_PIN(36, "gpio36"), + PINCTRL_PIN(37, "gpio37"), + PINCTRL_PIN(38, "gpio38"), + PINCTRL_PIN(39, "gpio39"), + PINCTRL_PIN(40, "gpio40"), + PINCTRL_PIN(41, "gpio41"), + PINCTRL_PIN(42, "gpio42"), + PINCTRL_PIN(43, "gpio43"), + PINCTRL_PIN(44, "gpio44"), + PINCTRL_PIN(45, "gpio45"), + PINCTRL_PIN(46, "gpio46"), + PINCTRL_PIN(47, "gpio47"), +}; + +static unsigned gpio0_pins[] = { 0 }; +static unsigned gpio1_pins[] = { 1 }; +static unsigned gpio2_pins[] = { 2 }; +static unsigned gpio3_pins[] = { 3 }; +static unsigned gpio4_pins[] = { 4 }; +static unsigned gpio5_pins[] = { 5 }; +static unsigned gpio6_pins[] = { 6 }; +static unsigned gpio7_pins[] = { 7 }; +static unsigned gpio8_pins[] = { 8 }; +static unsigned gpio9_pins[] = { 9 }; +static unsigned gpio10_pins[] = { 10 }; +static unsigned gpio11_pins[] = { 11 }; +static unsigned gpio12_pins[] = { 12 }; +static unsigned gpio13_pins[] = { 13 }; +static unsigned gpio14_pins[] = { 14 }; +static unsigned gpio15_pins[] = { 15 }; +static unsigned gpio16_pins[] = { 16 }; +static unsigned gpio17_pins[] = { 17 }; +static unsigned gpio18_pins[] = { 18 }; +static unsigned gpio19_pins[] = { 19 }; +static unsigned gpio20_pins[] = { 20 }; +static unsigned gpio21_pins[] = { 21 }; +static unsigned gpio22_pins[] = { 22 }; +static unsigned gpio23_pins[] = { 23 }; +static unsigned gpio24_pins[] = { 24 }; +static unsigned gpio25_pins[] = { 25 }; +static unsigned gpio26_pins[] = { 26 }; +static unsigned gpio27_pins[] = { 27 }; +static unsigned gpio28_pins[] = { 28 }; +static unsigned gpio29_pins[] = { 29 }; +static unsigned gpio30_pins[] = { 30 }; +static unsigned gpio31_pins[] = { 31 }; +static unsigned gpio32_pins[] = { 32 }; +static unsigned gpio33_pins[] = { 33 }; +static unsigned gpio34_pins[] = { 34 }; +static unsigned gpio35_pins[] = { 35 }; +static unsigned gpio36_pins[] = { 36 }; +static unsigned gpio37_pins[] = { 37 }; +static unsigned gpio38_pins[] = { 38 }; +static unsigned gpio39_pins[] = { 39 }; +static unsigned gpio40_pins[] = { 40 }; +static unsigned gpio41_pins[] = { 41 }; +static unsigned gpio42_pins[] = { 42 }; +static unsigned gpio43_pins[] = { 43 }; +static unsigned gpio44_pins[] = { 44 }; +static unsigned gpio45_pins[] = { 45 }; +static unsigned gpio46_pins[] = { 46 }; +static unsigned gpio47_pins[] = { 47 }; + +static unsigned nand_grp_pins[] = { + 8, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 27, +}; + +#define BCM6362_GROUP(n) \ + { \ + .name = #n, \ + .pins = n##_pins, \ + .num_pins = ARRAY_SIZE(n##_pins), \ + } + +static struct bcm6362_pingroup bcm6362_groups[] = { + BCM6362_GROUP(gpio0), + BCM6362_GROUP(gpio1), + BCM6362_GROUP(gpio2), + BCM6362_GROUP(gpio3), + BCM6362_GROUP(gpio4), + BCM6362_GROUP(gpio5), + BCM6362_GROUP(gpio6), + BCM6362_GROUP(gpio7), + BCM6362_GROUP(gpio8), + BCM6362_GROUP(gpio9), + BCM6362_GROUP(gpio10), + BCM6362_GROUP(gpio11), + BCM6362_GROUP(gpio12), + BCM6362_GROUP(gpio13), + BCM6362_GROUP(gpio14), + BCM6362_GROUP(gpio15), + BCM6362_GROUP(gpio16), + BCM6362_GROUP(gpio17), + BCM6362_GROUP(gpio18), + BCM6362_GROUP(gpio19), + BCM6362_GROUP(gpio20), + BCM6362_GROUP(gpio21), + BCM6362_GROUP(gpio22), + BCM6362_GROUP(gpio23), + BCM6362_GROUP(gpio24), + BCM6362_GROUP(gpio25), + BCM6362_GROUP(gpio26), + BCM6362_GROUP(gpio27), + BCM6362_GROUP(gpio28), + BCM6362_GROUP(gpio29), + BCM6362_GROUP(gpio30), + BCM6362_GROUP(gpio31), + BCM6362_GROUP(gpio32), + BCM6362_GROUP(gpio33), + BCM6362_GROUP(gpio34), + BCM6362_GROUP(gpio35), + BCM6362_GROUP(gpio36), + BCM6362_GROUP(gpio37), + BCM6362_GROUP(gpio38), + BCM6362_GROUP(gpio39), + BCM6362_GROUP(gpio40), + BCM6362_GROUP(gpio41), + BCM6362_GROUP(gpio42), + BCM6362_GROUP(gpio43), + BCM6362_GROUP(gpio44), + BCM6362_GROUP(gpio45), + BCM6362_GROUP(gpio46), + BCM6362_GROUP(gpio47), + BCM6362_GROUP(nand_grp), +}; + +static const char * const led_groups[] = { + "gpio0", + "gpio1", + "gpio2", + "gpio3", + "gpio4", + "gpio5", + "gpio6", + "gpio7", + "gpio8", + "gpio9", + "gpio10", + "gpio11", + "gpio12", + "gpio13", + "gpio14", + "gpio15", + "gpio16", + "gpio17", + "gpio18", + "gpio19", + "gpio20", + "gpio21", + "gpio22", + "gpio23", +}; + +static const char * const usb_device_led_groups[] = { + "gpio0", +}; + +static const char * const sys_irq_groups[] = { + "gpio1", +}; + +static const char * const serial_led_clk_groups[] = { + "gpio2", +}; + +static const char * const serial_led_data_groups[] = { + "gpio3", +}; + +static const char * const robosw_led_data_groups[] = { + "gpio4", +}; + +static const char * const robosw_led_clk_groups[] = { + "gpio5", +}; + +static const char * const robosw_led0_groups[] = { + "gpio6", +}; + +static const char * const robosw_led1_groups[] = { + "gpio7", +}; + +static const char * const inet_led_groups[] = { + "gpio8", +}; + +static const char * const spi_cs2_groups[] = { + "gpio9", +}; + +static const char * const spi_cs3_groups[] = { + "gpio10", +}; + +static const char * const ntr_pulse_groups[] = { + "gpio11", +}; + +static const char * const uart1_scts_groups[] = { + "gpio12", +}; + +static const char * const uart1_srts_groups[] = { + "gpio13", +}; + +static const char * const uart1_sdin_groups[] = { + "gpio14", +}; + +static const char * const uart1_sdout_groups[] = { + "gpio15", +}; + +static const char * const adsl_spi_miso_groups[] = { + "gpio16", +}; + +static const char * const adsl_spi_mosi_groups[] = { + "gpio17", +}; + +static const char * const adsl_spi_clk_groups[] = { + "gpio18", +}; + +static const char * const adsl_spi_cs_groups[] = { + "gpio19", +}; + +static const char * const ephy0_led_groups[] = { + "gpio20", +}; + +static const char * const ephy1_led_groups[] = { + "gpio21", +}; + +static const char * const ephy2_led_groups[] = { + "gpio22", +}; + +static const char * const ephy3_led_groups[] = { + "gpio23", +}; + +static const char * const ext_irq0_groups[] = { + "gpio24", +}; + +static const char * const ext_irq1_groups[] = { + "gpio25", +}; + +static const char * const ext_irq2_groups[] = { + "gpio26", +}; + +static const char * const ext_irq3_groups[] = { + "gpio27", +}; + +static const char * const wifi_groups[] = { + "gpio32", + "gpio33", + "gpio34", + "gpio35", + "gpio36", + "gpio37", + "gpio38", + "gpio39", + "gpio40", + "gpio41", + "gpio42", + "gpio43", + "gpio44", + "gpio45", + "gpio46", + "gpio47", +}; + +static const char * const nand_groups[] = { + "nand_grp", +}; + +#define BCM6362_LED_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .reg = BCM6362_LEDCTRL, \ + } + +#define BCM6362_MODE_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .reg = BCM6362_MODE, \ + } + +#define BCM6362_CTRL_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .reg = BCM6362_CTRL, \ + } + +#define BCM6362_BASEMODE_FUN(n, mask) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .reg = BCM6362_BASEMODE, \ + .basemode_mask = (mask), \ + } + +static const struct bcm6362_function bcm6362_funcs[] = { + BCM6362_LED_FUN(led), + BCM6362_MODE_FUN(usb_device_led), + BCM6362_MODE_FUN(sys_irq), + BCM6362_MODE_FUN(serial_led_clk), + BCM6362_MODE_FUN(serial_led_data), + BCM6362_MODE_FUN(robosw_led_data), + BCM6362_MODE_FUN(robosw_led_clk), + BCM6362_MODE_FUN(robosw_led0), + BCM6362_MODE_FUN(robosw_led1), + BCM6362_MODE_FUN(inet_led), + BCM6362_MODE_FUN(spi_cs2), + BCM6362_MODE_FUN(spi_cs3), + BCM6362_MODE_FUN(ntr_pulse), + BCM6362_MODE_FUN(uart1_scts), + BCM6362_MODE_FUN(uart1_srts), + BCM6362_MODE_FUN(uart1_sdin), + BCM6362_MODE_FUN(uart1_sdout), + BCM6362_MODE_FUN(adsl_spi_miso), + BCM6362_MODE_FUN(adsl_spi_mosi), + BCM6362_MODE_FUN(adsl_spi_clk), + BCM6362_MODE_FUN(adsl_spi_cs), + BCM6362_MODE_FUN(ephy0_led), + BCM6362_MODE_FUN(ephy1_led), + BCM6362_MODE_FUN(ephy2_led), + BCM6362_MODE_FUN(ephy3_led), + BCM6362_MODE_FUN(ext_irq0), + BCM6362_MODE_FUN(ext_irq1), + BCM6362_MODE_FUN(ext_irq2), + BCM6362_MODE_FUN(ext_irq3), + BCM6362_CTRL_FUN(wifi), + BCM6362_BASEMODE_FUN(nand, BASEMODE_NAND), +}; + +static int bcm6362_pinctrl_get_group_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6362_groups); +} + +static const char *bcm6362_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned group) +{ + return bcm6362_groups[group].name; +} + +static int bcm6362_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned group, const unsigned **pins, + unsigned *num_pins) +{ + *pins = bcm6362_groups[group].pins; + *num_pins = bcm6362_groups[group].num_pins; + + return 0; +} + +static int bcm6362_pinctrl_get_func_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6362_funcs); +} + +static const char *bcm6362_pinctrl_get_func_name(struct pinctrl_dev *pctldev, + unsigned selector) +{ + return bcm6362_funcs[selector].name; +} + +static int bcm6362_pinctrl_get_groups(struct pinctrl_dev *pctldev, + unsigned selector, + const char * const **groups, + unsigned * const num_groups) +{ + *groups = bcm6362_funcs[selector].groups; + *num_groups = bcm6362_funcs[selector].num_groups; + + return 0; +} + +static void bcm6362_set_gpio(struct bcm63xx_pinctrl *pc, unsigned pin) +{ + const struct pinctrl_pin_desc *desc = &bcm6362_pins[pin]; + unsigned int mask = bcm63xx_bank_pin(pin); + + if (desc->drv_data) + regmap_update_bits(pc->regs, BCM6362_BASEMODE_REG, + (uint32_t) desc->drv_data, 0); + + if (pin < BCM63XX_BANK_GPIOS) { + /* base mode 0 => gpio 1 => mux function */ + regmap_update_bits(pc->regs, BCM6362_MODE_REG, mask, 0); + + /* pins 0-23 might be muxed to led */ + if (pin < BCM6362_NUM_LEDS) + regmap_update_bits(pc->regs, BCM6362_LED_REG, mask, 0); + } else { + /* ctrl reg 0 => wifi function 1 => gpio */ + regmap_update_bits(pc->regs, BCM6362_CTRL_REG, mask, mask); + } +} + +static int bcm6362_pinctrl_set_mux(struct pinctrl_dev *pctldev, + unsigned selector, unsigned group) +{ + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + const struct bcm6362_pingroup *pg = &bcm6362_groups[group]; + const struct bcm6362_function *f = &bcm6362_funcs[selector]; + unsigned i; + unsigned int reg; + unsigned int val, mask; + + for (i = 0; i < pg->num_pins; i++) + bcm6362_set_gpio(pc, pg->pins[i]); + + switch (f->reg) { + case BCM6362_LEDCTRL: + reg = BCM6362_LED_REG; + mask = BIT(pg->pins[0]); + val = BIT(pg->pins[0]); + break; + case BCM6362_MODE: + reg = BCM6362_MODE_REG; + mask = BIT(pg->pins[0]); + val = BIT(pg->pins[0]); + break; + case BCM6362_CTRL: + reg = BCM6362_CTRL_REG; + mask = BIT(pg->pins[0]); + val = 0; + break; + case BCM6362_BASEMODE: + reg = BCM6362_BASEMODE_REG; + mask = f->basemode_mask; + val = f->basemode_mask; + break; + default: + WARN_ON(1); + return -EINVAL; + } + + regmap_update_bits(pc->regs, reg, mask, val); + + return 0; +} + +static int bcm6362_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) +{ + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + + /* disable all functions using this pin */ + bcm6362_set_gpio(pc, offset); + + return 0; +} + +static struct pinctrl_ops bcm6362_pctl_ops = { + .dt_free_map = pinctrl_utils_free_map, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .get_group_name = bcm6362_pinctrl_get_group_name, + .get_group_pins = bcm6362_pinctrl_get_group_pins, + .get_groups_count = bcm6362_pinctrl_get_group_count, +}; + +static struct pinmux_ops bcm6362_pmx_ops = { + .get_function_groups = bcm6362_pinctrl_get_groups, + .get_function_name = bcm6362_pinctrl_get_func_name, + .get_functions_count = bcm6362_pinctrl_get_func_count, + .gpio_request_enable = bcm6362_gpio_request_enable, + .set_mux = bcm6362_pinctrl_set_mux, + .strict = true, +}; + +static const struct bcm63xx_pinctrl_soc bcm6362_soc = { + .ngpios = BCM6362_NUM_GPIOS, + .npins = ARRAY_SIZE(bcm6362_pins), + .pctl_ops = &bcm6362_pctl_ops, + .pins = bcm6362_pins, + .pmx_ops = &bcm6362_pmx_ops, +}; + +static int bcm6362_pinctrl_probe(struct platform_device *pdev) +{ + return bcm63xx_pinctrl_probe(pdev, &bcm6362_soc, NULL); +} + +static const struct of_device_id bcm6362_pinctrl_match[] = { + { .compatible = "brcm,bcm6362-pinctrl", }, + { /* sentinel */ } +}; + +static struct platform_driver bcm6362_pinctrl_driver = { + .probe = bcm6362_pinctrl_probe, + .driver = { + .name = "bcm6362-pinctrl", + .of_match_table = bcm6362_pinctrl_match, + }, +}; + +builtin_platform_driver(bcm6362_pinctrl_driver); diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6368.c b/drivers/pinctrl/bcm/pinctrl-bcm6368.c new file mode 100644 index 000000000000..838095f9e890 --- /dev/null +++ b/drivers/pinctrl/bcm/pinctrl-bcm6368.c @@ -0,0 +1,523 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for BCM6368 GPIO unit (pinctrl + GPIO) + * + * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com> + * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com> + */ + +#include <linux/bits.h> +#include <linux/gpio/driver.h> +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/pinctrl/pinmux.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include "../pinctrl-utils.h" + +#include "pinctrl-bcm63xx.h" + +#define BCM6368_NUM_GPIOS 38 + +#define BCM6368_MODE_REG 0x18 +#define BCM6368_BASEMODE_REG 0x38 +#define BCM6368_BASEMODE_MASK 0x7 +#define BCM6368_BASEMODE_GPIO 0x0 +#define BCM6368_BASEMODE_UART1 0x1 + +struct bcm6368_pingroup { + const char *name; + const unsigned * const pins; + const unsigned num_pins; +}; + +struct bcm6368_function { + const char *name; + const char * const *groups; + const unsigned num_groups; + + unsigned dir_out:16; + unsigned basemode:3; +}; + +struct bcm6368_priv { + struct regmap_field *overlays; +}; + +#define BCM6368_BASEMODE_PIN(a, b) \ + { \ + .number = a, \ + .name = b, \ + .drv_data = (void *)true \ + } + +static const struct pinctrl_pin_desc bcm6368_pins[] = { + PINCTRL_PIN(0, "gpio0"), + PINCTRL_PIN(1, "gpio1"), + PINCTRL_PIN(2, "gpio2"), + PINCTRL_PIN(3, "gpio3"), + PINCTRL_PIN(4, "gpio4"), + PINCTRL_PIN(5, "gpio5"), + PINCTRL_PIN(6, "gpio6"), + PINCTRL_PIN(7, "gpio7"), + PINCTRL_PIN(8, "gpio8"), + PINCTRL_PIN(9, "gpio9"), + PINCTRL_PIN(10, "gpio10"), + PINCTRL_PIN(11, "gpio11"), + PINCTRL_PIN(12, "gpio12"), + PINCTRL_PIN(13, "gpio13"), + PINCTRL_PIN(14, "gpio14"), + PINCTRL_PIN(15, "gpio15"), + PINCTRL_PIN(16, "gpio16"), + PINCTRL_PIN(17, "gpio17"), + PINCTRL_PIN(18, "gpio18"), + PINCTRL_PIN(19, "gpio19"), + PINCTRL_PIN(20, "gpio20"), + PINCTRL_PIN(21, "gpio21"), + PINCTRL_PIN(22, "gpio22"), + PINCTRL_PIN(23, "gpio23"), + PINCTRL_PIN(24, "gpio24"), + PINCTRL_PIN(25, "gpio25"), + PINCTRL_PIN(26, "gpio26"), + PINCTRL_PIN(27, "gpio27"), + PINCTRL_PIN(28, "gpio28"), + PINCTRL_PIN(29, "gpio29"), + BCM6368_BASEMODE_PIN(30, "gpio30"), + BCM6368_BASEMODE_PIN(31, "gpio31"), + BCM6368_BASEMODE_PIN(32, "gpio32"), + BCM6368_BASEMODE_PIN(33, "gpio33"), + PINCTRL_PIN(34, "gpio34"), + PINCTRL_PIN(35, "gpio35"), + PINCTRL_PIN(36, "gpio36"), + PINCTRL_PIN(37, "gpio37"), +}; + +static unsigned gpio0_pins[] = { 0 }; +static unsigned gpio1_pins[] = { 1 }; +static unsigned gpio2_pins[] = { 2 }; +static unsigned gpio3_pins[] = { 3 }; +static unsigned gpio4_pins[] = { 4 }; +static unsigned gpio5_pins[] = { 5 }; +static unsigned gpio6_pins[] = { 6 }; +static unsigned gpio7_pins[] = { 7 }; +static unsigned gpio8_pins[] = { 8 }; +static unsigned gpio9_pins[] = { 9 }; +static unsigned gpio10_pins[] = { 10 }; +static unsigned gpio11_pins[] = { 11 }; +static unsigned gpio12_pins[] = { 12 }; +static unsigned gpio13_pins[] = { 13 }; +static unsigned gpio14_pins[] = { 14 }; +static unsigned gpio15_pins[] = { 15 }; +static unsigned gpio16_pins[] = { 16 }; +static unsigned gpio17_pins[] = { 17 }; +static unsigned gpio18_pins[] = { 18 }; +static unsigned gpio19_pins[] = { 19 }; +static unsigned gpio20_pins[] = { 20 }; +static unsigned gpio21_pins[] = { 21 }; +static unsigned gpio22_pins[] = { 22 }; +static unsigned gpio23_pins[] = { 23 }; +static unsigned gpio24_pins[] = { 24 }; +static unsigned gpio25_pins[] = { 25 }; +static unsigned gpio26_pins[] = { 26 }; +static unsigned gpio27_pins[] = { 27 }; +static unsigned gpio28_pins[] = { 28 }; +static unsigned gpio29_pins[] = { 29 }; +static unsigned gpio30_pins[] = { 30 }; +static unsigned gpio31_pins[] = { 31 }; +static unsigned uart1_grp_pins[] = { 30, 31, 32, 33 }; + +#define BCM6368_GROUP(n) \ + { \ + .name = #n, \ + .pins = n##_pins, \ + .num_pins = ARRAY_SIZE(n##_pins), \ + } + +static struct bcm6368_pingroup bcm6368_groups[] = { + BCM6368_GROUP(gpio0), + BCM6368_GROUP(gpio1), + BCM6368_GROUP(gpio2), + BCM6368_GROUP(gpio3), + BCM6368_GROUP(gpio4), + BCM6368_GROUP(gpio5), + BCM6368_GROUP(gpio6), + BCM6368_GROUP(gpio7), + BCM6368_GROUP(gpio8), + BCM6368_GROUP(gpio9), + BCM6368_GROUP(gpio10), + BCM6368_GROUP(gpio11), + BCM6368_GROUP(gpio12), + BCM6368_GROUP(gpio13), + BCM6368_GROUP(gpio14), + BCM6368_GROUP(gpio15), + BCM6368_GROUP(gpio16), + BCM6368_GROUP(gpio17), + BCM6368_GROUP(gpio18), + BCM6368_GROUP(gpio19), + BCM6368_GROUP(gpio20), + BCM6368_GROUP(gpio21), + BCM6368_GROUP(gpio22), + BCM6368_GROUP(gpio23), + BCM6368_GROUP(gpio24), + BCM6368_GROUP(gpio25), + BCM6368_GROUP(gpio26), + BCM6368_GROUP(gpio27), + BCM6368_GROUP(gpio28), + BCM6368_GROUP(gpio29), + BCM6368_GROUP(gpio30), + BCM6368_GROUP(gpio31), + BCM6368_GROUP(uart1_grp), +}; + +static const char * const analog_afe_0_groups[] = { + "gpio0", +}; + +static const char * const analog_afe_1_groups[] = { + "gpio1", +}; + +static const char * const sys_irq_groups[] = { + "gpio2", +}; + +static const char * const serial_led_data_groups[] = { + "gpio3", +}; + +static const char * const serial_led_clk_groups[] = { + "gpio4", +}; + +static const char * const inet_led_groups[] = { + "gpio5", +}; + +static const char * const ephy0_led_groups[] = { + "gpio6", +}; + +static const char * const ephy1_led_groups[] = { + "gpio7", +}; + +static const char * const ephy2_led_groups[] = { + "gpio8", +}; + +static const char * const ephy3_led_groups[] = { + "gpio9", +}; + +static const char * const robosw_led_data_groups[] = { + "gpio10", +}; + +static const char * const robosw_led_clk_groups[] = { + "gpio11", +}; + +static const char * const robosw_led0_groups[] = { + "gpio12", +}; + +static const char * const robosw_led1_groups[] = { + "gpio13", +}; + +static const char * const usb_device_led_groups[] = { + "gpio14", +}; + +static const char * const pci_req1_groups[] = { + "gpio16", +}; + +static const char * const pci_gnt1_groups[] = { + "gpio17", +}; + +static const char * const pci_intb_groups[] = { + "gpio18", +}; + +static const char * const pci_req0_groups[] = { + "gpio19", +}; + +static const char * const pci_gnt0_groups[] = { + "gpio20", +}; + +static const char * const pcmcia_cd1_groups[] = { + "gpio22", +}; + +static const char * const pcmcia_cd2_groups[] = { + "gpio23", +}; + +static const char * const pcmcia_vs1_groups[] = { + "gpio24", +}; + +static const char * const pcmcia_vs2_groups[] = { + "gpio25", +}; + +static const char * const ebi_cs2_groups[] = { + "gpio26", +}; + +static const char * const ebi_cs3_groups[] = { + "gpio27", +}; + +static const char * const spi_cs2_groups[] = { + "gpio28", +}; + +static const char * const spi_cs3_groups[] = { + "gpio29", +}; + +static const char * const spi_cs4_groups[] = { + "gpio30", +}; + +static const char * const spi_cs5_groups[] = { + "gpio31", +}; + +static const char * const uart1_groups[] = { + "uart1_grp", +}; + +#define BCM6368_FUN(n, out) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .dir_out = out, \ + } + +#define BCM6368_BASEMODE_FUN(n, val, out) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .basemode = BCM6368_BASEMODE_##val, \ + .dir_out = out, \ + } + +static const struct bcm6368_function bcm6368_funcs[] = { + BCM6368_FUN(analog_afe_0, 1), + BCM6368_FUN(analog_afe_1, 1), + BCM6368_FUN(sys_irq, 1), + BCM6368_FUN(serial_led_data, 1), + BCM6368_FUN(serial_led_clk, 1), + BCM6368_FUN(inet_led, 1), + BCM6368_FUN(ephy0_led, 1), + BCM6368_FUN(ephy1_led, 1), + BCM6368_FUN(ephy2_led, 1), + BCM6368_FUN(ephy3_led, 1), + BCM6368_FUN(robosw_led_data, 1), + BCM6368_FUN(robosw_led_clk, 1), + BCM6368_FUN(robosw_led0, 1), + BCM6368_FUN(robosw_led1, 1), + BCM6368_FUN(usb_device_led, 1), + BCM6368_FUN(pci_req1, 0), + BCM6368_FUN(pci_gnt1, 0), + BCM6368_FUN(pci_intb, 0), + BCM6368_FUN(pci_req0, 0), + BCM6368_FUN(pci_gnt0, 0), + BCM6368_FUN(pcmcia_cd1, 0), + BCM6368_FUN(pcmcia_cd2, 0), + BCM6368_FUN(pcmcia_vs1, 0), + BCM6368_FUN(pcmcia_vs2, 0), + BCM6368_FUN(ebi_cs2, 1), + BCM6368_FUN(ebi_cs3, 1), + BCM6368_FUN(spi_cs2, 1), + BCM6368_FUN(spi_cs3, 1), + BCM6368_FUN(spi_cs4, 1), + BCM6368_FUN(spi_cs5, 1), + BCM6368_BASEMODE_FUN(uart1, UART1, 0x6), +}; + +static int bcm6368_pinctrl_get_group_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6368_groups); +} + +static const char *bcm6368_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned group) +{ + return bcm6368_groups[group].name; +} + +static int bcm6368_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned group, const unsigned **pins, + unsigned *num_pins) +{ + *pins = bcm6368_groups[group].pins; + *num_pins = bcm6368_groups[group].num_pins; + + return 0; +} + +static int bcm6368_pinctrl_get_func_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6368_funcs); +} + +static const char *bcm6368_pinctrl_get_func_name(struct pinctrl_dev *pctldev, + unsigned selector) +{ + return bcm6368_funcs[selector].name; +} + +static int bcm6368_pinctrl_get_groups(struct pinctrl_dev *pctldev, + unsigned selector, + const char * const **groups, + unsigned * const num_groups) +{ + *groups = bcm6368_funcs[selector].groups; + *num_groups = bcm6368_funcs[selector].num_groups; + + return 0; +} + +static int bcm6368_pinctrl_set_mux(struct pinctrl_dev *pctldev, + unsigned selector, unsigned group) +{ + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + struct bcm6368_priv *priv = pc->driver_data; + const struct bcm6368_pingroup *pg = &bcm6368_groups[group]; + const struct bcm6368_function *fun = &bcm6368_funcs[selector]; + int i, pin; + + if (fun->basemode) { + unsigned int mask = 0; + + for (i = 0; i < pg->num_pins; i++) { + pin = pg->pins[i]; + if (pin < BCM63XX_BANK_GPIOS) + mask |= BIT(pin); + } + + regmap_update_bits(pc->regs, BCM6368_MODE_REG, mask, 0); + regmap_field_write(priv->overlays, fun->basemode); + } else { + pin = pg->pins[0]; + + if (bcm6368_pins[pin].drv_data) + regmap_field_write(priv->overlays, + BCM6368_BASEMODE_GPIO); + + regmap_update_bits(pc->regs, BCM6368_MODE_REG, BIT(pin), + BIT(pin)); + } + + for (pin = 0; pin < pg->num_pins; pin++) { + struct pinctrl_gpio_range *range; + int hw_gpio = bcm6368_pins[pin].number; + + range = pinctrl_find_gpio_range_from_pin(pctldev, hw_gpio); + if (range) { + struct gpio_chip *gc = range->gc; + + if (fun->dir_out & BIT(pin)) + gc->direction_output(gc, hw_gpio, 0); + else + gc->direction_input(gc, hw_gpio); + } + } + + return 0; +} + +static int bcm6368_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) +{ + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + struct bcm6368_priv *priv = pc->driver_data; + + if (offset >= BCM63XX_BANK_GPIOS && !bcm6368_pins[offset].drv_data) + return 0; + + /* disable all functions using this pin */ + if (offset < BCM63XX_BANK_GPIOS) + regmap_update_bits(pc->regs, BCM6368_MODE_REG, BIT(offset), 0); + + if (bcm6368_pins[offset].drv_data) + regmap_field_write(priv->overlays, BCM6368_BASEMODE_GPIO); + + return 0; +} + +static struct pinctrl_ops bcm6368_pctl_ops = { + .dt_free_map = pinctrl_utils_free_map, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .get_group_name = bcm6368_pinctrl_get_group_name, + .get_group_pins = bcm6368_pinctrl_get_group_pins, + .get_groups_count = bcm6368_pinctrl_get_group_count, +}; + +static struct pinmux_ops bcm6368_pmx_ops = { + .get_function_groups = bcm6368_pinctrl_get_groups, + .get_function_name = bcm6368_pinctrl_get_func_name, + .get_functions_count = bcm6368_pinctrl_get_func_count, + .gpio_request_enable = bcm6368_gpio_request_enable, + .set_mux = bcm6368_pinctrl_set_mux, + .strict = true, +}; + +static const struct bcm63xx_pinctrl_soc bcm6368_soc = { + .ngpios = BCM6368_NUM_GPIOS, + .npins = ARRAY_SIZE(bcm6368_pins), + .pctl_ops = &bcm6368_pctl_ops, + .pins = bcm6368_pins, + .pmx_ops = &bcm6368_pmx_ops, +}; + +static int bcm6368_pinctrl_probe(struct platform_device *pdev) +{ + struct reg_field overlays = REG_FIELD(BCM6368_BASEMODE_REG, 0, 15); + struct device *dev = &pdev->dev; + struct bcm63xx_pinctrl *pc; + struct bcm6368_priv *priv; + int err; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + err = bcm63xx_pinctrl_probe(pdev, &bcm6368_soc, (void *) priv); + if (err) + return err; + + pc = platform_get_drvdata(pdev); + + priv->overlays = devm_regmap_field_alloc(dev, pc->regs, overlays); + if (IS_ERR(priv->overlays)) + return PTR_ERR(priv->overlays); + + return 0; +} + +static const struct of_device_id bcm6368_pinctrl_match[] = { + { .compatible = "brcm,bcm6368-pinctrl", }, + { /* sentinel */ } +}; + +static struct platform_driver bcm6368_pinctrl_driver = { + .probe = bcm6368_pinctrl_probe, + .driver = { + .name = "bcm6368-pinctrl", + .of_match_table = bcm6368_pinctrl_match, + }, +}; + +builtin_platform_driver(bcm6368_pinctrl_driver); diff --git a/drivers/pinctrl/bcm/pinctrl-bcm63xx.c b/drivers/pinctrl/bcm/pinctrl-bcm63xx.c new file mode 100644 index 000000000000..e1285fe2fbc0 --- /dev/null +++ b/drivers/pinctrl/bcm/pinctrl-bcm63xx.c @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for BCM63xx GPIO unit (pinctrl + GPIO) + * + * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com> + * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com> + */ + +#include <linux/gpio/regmap.h> +#include <linux/mfd/syscon.h> +#include <linux/mod_devicetable.h> +#include <linux/of.h> +#include <linux/platform_device.h> + +#include "pinctrl-bcm63xx.h" + +#define BCM63XX_BANK_SIZE 4 + +#define BCM63XX_DIROUT_REG 0x04 +#define BCM63XX_DATA_REG 0x0c + +static int bcm63xx_reg_mask_xlate(struct gpio_regmap *gpio, + unsigned int base, unsigned int offset, + unsigned int *reg, unsigned int *mask) +{ + unsigned int line = offset % BCM63XX_BANK_GPIOS; + unsigned int stride = offset / BCM63XX_BANK_GPIOS; + + *reg = base - stride * BCM63XX_BANK_SIZE; + *mask = BIT(line); + + return 0; +} + +static const struct of_device_id bcm63xx_gpio_of_match[] = { + { .compatible = "brcm,bcm6318-gpio", }, + { .compatible = "brcm,bcm6328-gpio", }, + { .compatible = "brcm,bcm6358-gpio", }, + { .compatible = "brcm,bcm6362-gpio", }, + { .compatible = "brcm,bcm6368-gpio", }, + { .compatible = "brcm,bcm63268-gpio", }, + { /* sentinel */ } +}; + +static int bcm63xx_gpio_probe(struct device *dev, struct device_node *node, + const struct bcm63xx_pinctrl_soc *soc, + struct bcm63xx_pinctrl *pc) +{ + struct gpio_regmap_config grc = {0}; + + grc.parent = dev; + grc.fwnode = &node->fwnode; + grc.ngpio = soc->ngpios; + grc.ngpio_per_reg = BCM63XX_BANK_GPIOS; + grc.regmap = pc->regs; + grc.reg_dat_base = BCM63XX_DATA_REG; + grc.reg_dir_out_base = BCM63XX_DIROUT_REG; + grc.reg_set_base = BCM63XX_DATA_REG; + grc.reg_mask_xlate = bcm63xx_reg_mask_xlate; + + return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(dev, &grc)); +} + +int bcm63xx_pinctrl_probe(struct platform_device *pdev, + const struct bcm63xx_pinctrl_soc *soc, + void *driver_data) +{ + struct device *dev = &pdev->dev; + struct bcm63xx_pinctrl *pc; + struct device_node *node; + int err; + + pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); + if (!pc) + return -ENOMEM; + + platform_set_drvdata(pdev, pc); + + pc->dev = dev; + pc->driver_data = driver_data; + + pc->regs = syscon_node_to_regmap(dev->parent->of_node); + if (IS_ERR(pc->regs)) + return PTR_ERR(pc->regs); + + pc->pctl_desc.name = dev_name(dev); + pc->pctl_desc.pins = soc->pins; + pc->pctl_desc.npins = soc->npins; + pc->pctl_desc.pctlops = soc->pctl_ops; + pc->pctl_desc.pmxops = soc->pmx_ops; + pc->pctl_desc.owner = THIS_MODULE; + + pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc); + if (IS_ERR(pc->pctl_dev)) + return PTR_ERR(pc->pctl_dev); + + for_each_child_of_node(dev->parent->of_node, node) { + if (of_match_node(bcm63xx_gpio_of_match, node)) { + err = bcm63xx_gpio_probe(dev, node, soc, pc); + if (err) { + dev_err(dev, "could not add GPIO chip\n"); + of_node_put(node); + return err; + } + } + } + + return 0; +} diff --git a/drivers/pinctrl/bcm/pinctrl-bcm63xx.h b/drivers/pinctrl/bcm/pinctrl-bcm63xx.h new file mode 100644 index 000000000000..3bdb50021f1b --- /dev/null +++ b/drivers/pinctrl/bcm/pinctrl-bcm63xx.h @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com> + * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com> + */ + +#ifndef __PINCTRL_BCM63XX_H__ +#define __PINCTRL_BCM63XX_H__ + +#include <linux/pinctrl/pinctrl.h> + +#define BCM63XX_BANK_GPIOS 32 + +struct bcm63xx_pinctrl_soc { + struct pinctrl_ops *pctl_ops; + struct pinmux_ops *pmx_ops; + + const struct pinctrl_pin_desc *pins; + unsigned npins; + + unsigned int ngpios; +}; + +struct bcm63xx_pinctrl { + struct device *dev; + struct regmap *regs; + + struct pinctrl_desc pctl_desc; + struct pinctrl_dev *pctl_dev; + + void *driver_data; +}; + +static inline unsigned int bcm63xx_bank_pin(unsigned int pin) +{ + return pin % BCM63XX_BANK_GPIOS; +} + +int bcm63xx_pinctrl_probe(struct platform_device *pdev, + const struct bcm63xx_pinctrl_soc *soc, + void *driver_data); + +#endif /* __PINCTRL_BCM63XX_H__ */ diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 286de0520574..ecf0032a0995 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -624,8 +624,17 @@ void gpiochip_irq_domain_deactivate(struct irq_domain *domain, bool gpiochip_irqchip_irq_valid(const struct gpio_chip *gc, unsigned int offset); +#ifdef CONFIG_GPIOLIB_IRQCHIP int gpiochip_irqchip_add_domain(struct gpio_chip *gc, struct irq_domain *domain); +#else +static inline int gpiochip_irqchip_add_domain(struct gpio_chip *gc, + struct irq_domain *domain) +{ + WARN_ON(1); + return -EINVAL; +} +#endif int gpiochip_generic_request(struct gpio_chip *gc, unsigned int offset); void gpiochip_generic_free(struct gpio_chip *gc, unsigned int offset); diff --git a/include/linux/gpio/regmap.h b/include/linux/gpio/regmap.h index ad76f3d0a6ba..334dd928042b 100644 --- a/include/linux/gpio/regmap.h +++ b/include/linux/gpio/regmap.h @@ -4,6 +4,7 @@ #define _LINUX_GPIO_REGMAP_H struct device; +struct fwnode_handle; struct gpio_regmap; struct irq_domain; struct regmap; @@ -16,6 +17,8 @@ struct regmap; * @parent: The parent device * @regmap: The regmap used to access the registers * given, the name of the device is used + * @fwnode: (Optional) The firmware node. + * If not given, the fwnode of the parent is used. * @label: (Optional) Descriptive name for GPIO controller. * If not given, the name of the device is used. * @ngpio: Number of GPIOs @@ -57,6 +60,7 @@ struct regmap; struct gpio_regmap_config { struct device *parent; struct regmap *regmap; + struct fwnode_handle *fwnode; const char *label; int ngpio; |