From: Álvaro Fernández Rojas Date: Wed, 24 Feb 2021 20:28:08 +0000 (+0100) Subject: bmips: rewrite pin controllers X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=e2448e5e03ef2df8194f5705627c2bb6b867d989;p=openwrt%2Fstaging%2Fnoltari.git bmips: rewrite pin controllers This is needed in order to upstream them. Signed-off-by: Álvaro Fernández Rojas --- diff --git a/target/linux/bmips/config-5.10 b/target/linux/bmips/config-5.10 index 86c71aaeef..cfe8888f80 100644 --- a/target/linux/bmips/config-5.10 +++ b/target/linux/bmips/config-5.10 @@ -190,7 +190,6 @@ CONFIG_PINCTRL_BCM6328=y CONFIG_PINCTRL_BCM6358=y CONFIG_PINCTRL_BCM6362=y CONFIG_PINCTRL_BCM6368=y -CONFIG_PINCTRL_BCM63XX=y CONFIG_PM=y CONFIG_PM_CLK=y CONFIG_PM_GENERIC_DOMAINS=y diff --git a/target/linux/bmips/dts/bcm6318.dtsi b/target/linux/bmips/dts/bcm6318.dtsi index ba12390814..d19f8ec964 100644 --- a/target/linux/bmips/dts/bcm6318.dtsi +++ b/target/linux/bmips/dts/bcm6318.dtsi @@ -143,112 +143,113 @@ mask = <0x1>; }; - pinctrl: pin-controller@10000080 { - compatible = "brcm,bcm6318-pinctrl"; - reg = <0x10000080 0x08>, - <0x10000088 0x08>, - <0x10000098 0x04>, - <0x1000009c 0x0c>, - <0x100000d4 0x18>; - reg-names = "dirout", "dat", "mode", "mux", "pad"; - - gpio-controller; - #gpio-cells = <2>; - - interrupt-parent = <&ext_intc>; - interrupts = <0 0>, <1 0>; - interrupt-names = "gpio33", "gpio34"; - - pinctrl_ephy0_spd_led: ephy0_spd_led { - function = "ephy0_spd_led"; - pins = "gpio0"; - }; + gpio: syscon@10000080 { + compatible = "syscon", "simple-mfd"; + reg = <0x10000080 0x80>; + native-endian; - pinctrl_ephy1_spd_led: ephy1_spd_led { - function = "ephy1_spd_led"; - pins = "gpio1"; - }; + pinctrl: pin-controller { + compatible = "brcm,bcm6318-pinctrl"; - pinctrl_ephy2_spd_led: ephy2_spd_led { - function = "ephy2_spd_led"; - pins = "gpio2"; - }; + gpio-controller; + #gpio-cells = <2>; - pinctrl_ephy3_spd_led: ephy3_spd_led { - function = "ephy3_spd_led"; - pins = "gpio3"; - }; + interrupts-extended = <&ext_intc 0 0>, + <&ext_intc 1 0>; + interrupt-names = "gpio33", + "gpio34"; - pinctrl_ephy0_act_led: ephy0_act_led { - function = "ephy0_act_led"; - pins = "gpio4"; - }; + pinctrl_ephy0_spd_led: ephy0_spd_led { + function = "ephy0_spd_led"; + pins = "gpio0"; + }; - pinctrl_ephy1_act_led: ephy1_act_led { - function = "ephy1_act_led"; - pins = "gpio5"; - }; + pinctrl_ephy1_spd_led: ephy1_spd_led { + function = "ephy1_spd_led"; + pins = "gpio1"; + }; - pinctrl_ephy2_act_led: ephy2_act_led { - function = "ephy2_act_led"; - pins = "gpio6"; - }; + pinctrl_ephy2_spd_led: ephy2_spd_led { + function = "ephy2_spd_led"; + pins = "gpio2"; + }; - pinctrl_ephy3_act_led: ephy3_act_led { - function = "ephy3_act_led"; - pins = "gpio7"; - }; + pinctrl_ephy3_spd_led: ephy3_spd_led { + function = "ephy3_spd_led"; + pins = "gpio3"; + }; - pinctrl_serial_led: serial_led { - pinctrl_serial_led_data: serial_led_data { - function = "serial_led_data"; + pinctrl_ephy0_act_led: ephy0_act_led { + function = "ephy0_act_led"; + pins = "gpio4"; + }; + + pinctrl_ephy1_act_led: ephy1_act_led { + function = "ephy1_act_led"; + pins = "gpio5"; + }; + + pinctrl_ephy2_act_led: ephy2_act_led { + function = "ephy2_act_led"; pins = "gpio6"; }; - pinctrl_serial_led_clk: serial_led_clk { - function = "serial_led_clk"; + pinctrl_ephy3_act_led: ephy3_act_led { + function = "ephy3_act_led"; pins = "gpio7"; }; - }; - pinctrl_inet_act_led: inet_act_led { - function = "inet_act_led"; - pins = "gpio8"; - }; + pinctrl_serial_led: serial_led { + pinctrl_serial_led_data: serial_led_data { + function = "serial_led_data"; + pins = "gpio6"; + }; - pinctrl_inet_fail_led: inet_fail_led { - function = "inet_fail_led"; - pins = "gpio9"; - }; + pinctrl_serial_led_clk: serial_led_clk { + function = "serial_led_clk"; + pins = "gpio7"; + }; + }; - pinctrl_dsl_led: dsl_led { - function = "dsl_led"; - pins = "gpio10"; - }; + pinctrl_inet_act_led: inet_act_led { + function = "inet_act_led"; + pins = "gpio8"; + }; - pinctrl_post_fail_led: post_fail_led { - function = "post_fail_led"; - pins = "gpio11"; - }; + pinctrl_inet_fail_led: inet_fail_led { + function = "inet_fail_led"; + pins = "gpio9"; + }; - pinctrl_wlan_wps_led: wlan_wps_led { - function = "wlan_wps_led"; - pins = "gpio12"; - }; + pinctrl_dsl_led: dsl_led { + function = "dsl_led"; + pins = "gpio10"; + }; - pinctrl_usb_pwron: usb_pwron { - function = "usb_pwron"; - pins = "gpio13"; - }; + pinctrl_post_fail_led: post_fail_led { + function = "post_fail_led"; + pins = "gpio11"; + }; - pinctrl_usb_device_led: usb_device_led { - function = "usb_device_led"; - pins = "gpio13"; - }; + pinctrl_wlan_wps_led: wlan_wps_led { + function = "wlan_wps_led"; + pins = "gpio12"; + }; - pinctrl_usb_active: usb_active { - function = "usb_active"; - pins = "gpio40"; + pinctrl_usb_pwron: usb_pwron { + function = "usb_pwron"; + pins = "gpio13"; + }; + + pinctrl_usb_device_led: usb_device_led { + function = "usb_device_led"; + pins = "gpio13"; + }; + + pinctrl_usb_active: usb_active { + function = "usb_active"; + pins = "gpio40"; + }; }; }; diff --git a/target/linux/bmips/dts/bcm63268.dtsi b/target/linux/bmips/dts/bcm63268.dtsi index be98bf181e..538b43754b 100644 --- a/target/linux/bmips/dts/bcm63268.dtsi +++ b/target/linux/bmips/dts/bcm63268.dtsi @@ -147,131 +147,134 @@ timeout-sec = <30>; }; - pinctrl: pin-controller@100000c0 { - compatible = "brcm,bcm63268-pinctrl"; - reg = <0x100000c0 0x8>, - <0x100000c8 0x8>, - <0x100000d0 0x4>, - <0x100000d8 0x4>, - <0x100000dc 0x4>, - <0x100000f8 0x4>; - reg-names = "dirout", "dat", "led", "mode", - "ctrl", "basemode"; - - gpio-controller; - #gpio-cells = <2>; - - interrupt-parent = <&ext_intc>; - interrupts = <0 0>, <1 0>, <2 0>, <3 0>; - interrupt-names = "gpio32", "gpio33", "gpio34", "gpio35"; - - pinctrl_serial_led: serial_led { - pinctrl_serial_led_clk: serial_led_clk { - function = "serial_led_clk"; - pins = "gpio0"; + gpio: syscon@100000c0 { + compatible = "syscon", "simple-mfd"; + reg = <0x100000c0 0x80>; + native-endian; + + pinctrl: pin-controller { + compatible = "brcm,bcm63268-pinctrl"; + + gpio-controller; + #gpio-cells = <2>; + + interrupts-extended = <&ext_intc 0 0>, + <&ext_intc 1 0>, + <&ext_intc 2 0>, + <&ext_intc 3 0>; + interrupt-names = "gpio32", + "gpio33", + "gpio34", + "gpio35"; + + pinctrl_serial_led: serial_led { + pinctrl_serial_led_clk: serial_led_clk { + function = "serial_led_clk"; + pins = "gpio0"; + }; + + pinctrl_serial_led_data: serial_led_data { + function = "serial_led_data"; + pins = "gpio1"; + }; }; - pinctrl_serial_led_data: serial_led_data { - function = "serial_led_data"; - pins = "gpio1"; + pinctrl_hsspi_cs4: hsspi_cs4 { + function = "hsspi_cs4"; + pins = "gpio16"; }; - }; - pinctrl_hsspi_cs4: hsspi_cs4 { - function = "hsspi_cs4"; - pins = "gpio16"; - }; + pinctrl_hsspi_cs5: hsspi_cs5 { + function = "hsspi_cs5"; + pins = "gpio17"; + }; - pinctrl_hsspi_cs5: hsspi_cs5 { - function = "hsspi_cs5"; - pins = "gpio17"; - }; + pinctrl_hsspi_cs6: hsspi_cs6 { + function = "hsspi_cs6"; + pins = "gpio8"; + }; - pinctrl_hsspi_cs6: hsspi_cs6 { - function = "hsspi_cs6"; - pins = "gpio8"; - }; + pinctrl_hsspi_cs7: hsspi_cs7 { + function = "hsspi_cs7"; + pins = "gpio9"; + }; - pinctrl_hsspi_cs7: hsspi_cs7 { - function = "hsspi_cs7"; - pins = "gpio9"; - }; + pinctrl_adsl_spi: adsl_spi { + pinctrl_adsl_spi_miso: adsl_spi_miso { + function = "adsl_spi_miso"; + pins = "gpio18"; + }; - pinctrl_adsl_spi: adsl_spi { - pinctrl_adsl_spi_miso: adsl_spi_miso { - function = "adsl_spi_miso"; - pins = "gpio18"; + pinctrl_adsl_spi_mosi: adsl_spi_mosi { + function = "adsl_spi_mosi"; + pins = "gpio19"; + }; }; - pinctrl_adsl_spi_mosi: adsl_spi_mosi { - function = "adsl_spi_mosi"; - pins = "gpio19"; + pinctrl_vreq_clk: vreq_clk { + function = "vreq_clk"; + pins = "gpio22"; }; - }; - pinctrl_vreq_clk: vreq_clk { - function = "vreq_clk"; - pins = "gpio22"; - }; - - pinctrl_pcie_clkreq_b: pcie_clkreq_b { - function = "pcie_clkreq_b"; - pins = "gpio23"; - }; + pinctrl_pcie_clkreq_b: pcie_clkreq_b { + function = "pcie_clkreq_b"; + pins = "gpio23"; + }; - pinctrl_robosw_led_clk: robosw_led_clk { - function = "robosw_led_clk"; - pins = "gpio30"; - }; + pinctrl_robosw_led_clk: robosw_led_clk { + function = "robosw_led_clk"; + pins = "gpio30"; + }; - pinctrl_robosw_led_data: robosw_led_data { - function = "robosw_led_data"; - pins = "gpio31"; - }; + pinctrl_robosw_led_data: robosw_led_data { + function = "robosw_led_data"; + pins = "gpio31"; + }; - pinctrl_nand: nand { - function = "nand"; - group = "nand_grp"; - }; + pinctrl_nand: nand { + function = "nand"; + group = "nand_grp"; + }; - pinctrl_gpio35_alt: gpio35_alt { - function = "gpio35_alt"; - pin = "gpio35"; - }; + pinctrl_gpio35_alt: gpio35_alt { + function = "gpio35_alt"; + pin = "gpio35"; + }; - pinctrl_dectpd: dectpd { - function = "dectpd"; - group = "dectpd_grp"; - }; + pinctrl_dectpd: dectpd { + function = "dectpd"; + group = "dectpd_grp"; + }; - pinctrl_vdsl_phy_override_0: vdsl_phy_override_0 { - function = "vdsl_phy_override_0"; - group = "vdsl_phy_override_0_grp"; - }; + pinctrl_vdsl_phy_override_0: vdsl_phy_override_0 { + function = "vdsl_phy_override_0"; + group = "vdsl_phy_override_0_grp"; + }; - pinctrl_vdsl_phy_override_1: vdsl_phy_override_1 { - function = "vdsl_phy_override_1"; - group = "vdsl_phy_override_1_grp"; - }; + pinctrl_vdsl_phy_override_1: vdsl_phy_override_1 { + function = "vdsl_phy_override_1"; + group = "vdsl_phy_override_1_grp"; + }; - pinctrl_vdsl_phy_override_2: vdsl_phy_override_2 { - function = "vdsl_phy_override_2"; - group = "vdsl_phy_override_2_grp"; - }; + pinctrl_vdsl_phy_override_2: vdsl_phy_override_2 { + function = "vdsl_phy_override_2"; + group = "vdsl_phy_override_2_grp"; + }; - pinctrl_vdsl_phy_override_3: vdsl_phy_override_3 { - function = "vdsl_phy_override_3"; - group = "vdsl_phy_override_3_grp"; - }; + pinctrl_vdsl_phy_override_3: vdsl_phy_override_3 { + function = "vdsl_phy_override_3"; + group = "vdsl_phy_override_3_grp"; + }; - pinctrl_dsl_gpio8: dsl_gpio8 { - function = "dsl_gpio8"; - group = "dsl_gpio8"; - }; + pinctrl_dsl_gpio8: dsl_gpio8 { + function = "dsl_gpio8"; + group = "dsl_gpio8"; + }; - pinctrl_dsl_gpio9: dsl_gpio9 { - function = "dsl_gpio9"; - group = "dsl_gpio9"; + pinctrl_dsl_gpio9: dsl_gpio9 { + function = "dsl_gpio9"; + group = "dsl_gpio9"; + }; }; }; diff --git a/target/linux/bmips/dts/bcm6328.dtsi b/target/linux/bmips/dts/bcm6328.dtsi index 07ae773fe4..f4f86c381e 100644 --- a/target/linux/bmips/dts/bcm6328.dtsi +++ b/target/linux/bmips/dts/bcm6328.dtsi @@ -146,97 +146,102 @@ mask = <0x1>; }; - pinctrl: pin-controller@10000080 { - compatible = "brcm,bcm6328-pinctrl"; - reg = <0x10000080 0x8>, - <0x10000088 0x8>, - <0x10000098 0x4>, - <0x1000009c 0xc>; - reg-names = "dirout", "dat", "mode", "mux"; - - gpio-controller; - #gpio-cells = <2>; - - interrupt-parent = <&ext_intc>; - interrupts = <3 0>, <2 0>, <0 0>, <1 0>; - interrupt-names = "gpio12", "gpio15", - "gpio23", "gpio24"; - - pinctrl_serial_led: serial_led { - pinctrl_serial_led_data: serial_led_data { - function = "serial_led_data"; - pins = "gpio6"; - }; + gpio: syscon@10000080 { + compatible = "syscon", "simple-mfd"; + reg = <0x10000080 0x80>; + native-endian; - pinctrl_serial_led_clk: serial_led_clk { - function = "serial_led_clk"; - pins = "gpio7"; + pinctrl: pin-controller { + compatible = "brcm,bcm6328-pinctrl"; + + gpio-controller; + #gpio-cells = <2>; + + interrupts-extended = <&ext_intc 3 0>, + <&ext_intc 2 0>, + <&ext_intc 1 0>, + <&ext_intc 0 0>; + interrupt-names = "gpio12", + "gpio15", + "gpio23", + "gpio24"; + + pinctrl_serial_led: serial_led { + pinctrl_serial_led_data: serial_led_data { + function = "serial_led_data"; + pins = "gpio6"; + }; + + pinctrl_serial_led_clk: serial_led_clk { + function = "serial_led_clk"; + pins = "gpio7"; + }; }; - }; - pinctrl_inet_act_led: inet_act_led { - function = "inet_act_led"; - pins = "gpio11"; - }; + pinctrl_inet_act_led: inet_act_led { + function = "inet_act_led"; + pins = "gpio11"; + }; - pinctrl_pcie_clkreq: pcie_clkreq { - function = "pcie_clkreq"; - pins = "gpio16"; - }; + pinctrl_pcie_clkreq: pcie_clkreq { + function = "pcie_clkreq"; + pins = "gpio16"; + }; - pinctrl_ephy0_spd_led: ephy0_spd_led { - function = "led"; - pins = "gpio17"; - }; + pinctrl_ephy0_spd_led: ephy0_spd_led { + function = "led"; + pins = "gpio17"; + }; - pinctrl_ephy1_spd_led: ephy1_spd_led { - function = "led"; - pins = "gpio18"; - }; + pinctrl_ephy1_spd_led: ephy1_spd_led { + function = "led"; + pins = "gpio18"; + }; - pinctrl_ephy2_spd_led: ephy2_spd_led { - function = "led"; - pins = "gpio19"; - }; + pinctrl_ephy2_spd_led: ephy2_spd_led { + function = "led"; + pins = "gpio19"; + }; - pinctrl_ephy3_spd_led: ephy3_spd_led { - function = "led"; - pins = "gpio20"; - }; + pinctrl_ephy3_spd_led: ephy3_spd_led { + function = "led"; + pins = "gpio20"; + }; - pinctrl_ephy0_act_led: ephy0_act_led { - function = "ephy0_act_led"; - pins = "gpio25"; - }; + pinctrl_ephy0_act_led: ephy0_act_led { + function = "ephy0_act_led"; + pins = "gpio25"; + }; - pinctrl_ephy1_act_led: ephy1_act_led { - function = "ephy1_act_led"; - pins = "gpio26"; - }; + pinctrl_ephy1_act_led: ephy1_act_led { + function = "ephy1_act_led"; + pins = "gpio26"; + }; - pinctrl_ephy2_act_led: ephy2_act_led { - function = "ephy2_act_led"; - pins = "gpio27"; - }; + pinctrl_ephy2_act_led: ephy2_act_led { + function = "ephy2_act_led"; + pins = "gpio27"; + }; - pinctrl_ephy3_act_led: ephy3_act_led { - function = "ephy3_act_led"; - pins = "gpio28"; - }; + pinctrl_ephy3_act_led: ephy3_act_led { + function = "ephy3_act_led"; + pins = "gpio28"; + }; - pinctrl_hsspi_cs1: hsspi_cs1 { - function = "hsspi_cs1"; - pins = "hsspi_cs1"; - }; + pinctrl_hsspi_cs1: hsspi_cs1 { + function = "hsspi_cs1"; + pins = "hsspi_cs1"; + }; - pinctrl_usb_port1_device: usb_port1_device { - function = "usb_device_port"; - pins = "usb_port1"; - }; + pinctrl_usb_port1_device: usb_port1_device { + function = "usb_device_port"; + pins = "usb_port1"; + }; - pinctrl_usb_port1_host: usb_port1_host { - function = "usb_host_port"; - pins = "usb_port1"; + pinctrl_usb_port1_host: usb_port1_host { + function = "usb_host_port"; + pins = "usb_port1"; + }; }; }; diff --git a/target/linux/bmips/dts/bcm6358.dtsi b/target/linux/bmips/dts/bcm6358.dtsi index 83cfb0ad90..8e2c9fa0ee 100644 --- a/target/linux/bmips/dts/bcm6358.dtsi +++ b/target/linux/bmips/dts/bcm6358.dtsi @@ -158,76 +158,77 @@ timeout-sec = <30>; }; - pinctrl: pin-controller@fffe0080 { - compatible = "brcm,bcm6358-pinctrl"; - reg = <0xfffe0080 0x8>, - <0xfffe0088 0x8>; - reg-names = "dirout", "dat", "mode"; - brcm,gpiomode = <&gpiomode>; - - gpio-controller; - #gpio-cells = <2>; - - interrupts-extended = <&ext_intc1 0 0>, - <&ext_intc1 1 0>, - <&ext_intc0 0 0>, - <&ext_intc0 1 0>, - <&ext_intc0 2 0>, - <&ext_intc0 3 0>; - interrupt-names = "gpio32", "gpio33", "gpio34", "gpio35", - "gpio36", "gpio37"; - - pinctrl_ebi_cs: ebi_cs { - function = "ebi_cs"; - groups = "ebi_cs_grp"; - }; - - pinctrl_uart1: uart1 { - function = "uart1"; - groups = "uart1_grp"; - }; - - pinctrl_serial_led: serial_led { - function = "serial_led"; - groups = "serial_led_grp"; - }; - - pinctrl_legacy_led: legacy_led { - function = "legacy_led"; - groups = "legacy_led_grp"; - }; - - pinctrl_led: led { - function = "led"; - groups = "led_grp"; - }; - - pinctrl_spi_cs_23: spi_cs { - function = "spi_cs"; - groups = "spi_cs_grp"; - }; - - pinctrl_utopia: utopia { - function = "utopia"; - groups = "utopia_grp"; - }; - - pinctrl_pwm_syn_clk: pwm_syn_clk { - function = "pwm_syn_clk"; - groups = "pwm_syn_clk_grp"; - }; + gpio: syscon@fffe0080 { + compatible = "syscon", "simple-mfd"; + reg = <0xfffe0080 0x50>; + native-endian; - pinctrl_sys_irq: sys_irq { - function = "sys_irq"; - groups = "sys_irq_grp"; + pinctrl: pin-controller { + compatible = "brcm,bcm6358-pinctrl"; + + gpio-controller; + #gpio-cells = <2>; + + interrupts-extended = <&ext_intc1 0 0>, + <&ext_intc1 1 0>, + <&ext_intc0 0 0>, + <&ext_intc0 1 0>, + <&ext_intc0 2 0>, + <&ext_intc0 3 0>; + interrupt-names = "gpio32", + "gpio33", + "gpio34", + "gpio35", + "gpio36", + "gpio37"; + + pinctrl_ebi_cs: ebi_cs { + function = "ebi_cs"; + groups = "ebi_cs_grp"; + }; + + pinctrl_uart1: uart1 { + function = "uart1"; + groups = "uart1_grp"; + }; + + pinctrl_serial_led: serial_led { + function = "serial_led"; + groups = "serial_led_grp"; + }; + + pinctrl_legacy_led: legacy_led { + function = "legacy_led"; + groups = "legacy_led_grp"; + }; + + pinctrl_led: led { + function = "led"; + groups = "led_grp"; + }; + + pinctrl_spi_cs_23: spi_cs { + function = "spi_cs"; + groups = "spi_cs_grp"; + }; + + pinctrl_utopia: utopia { + function = "utopia"; + groups = "utopia_grp"; + }; + + pinctrl_pwm_syn_clk: pwm_syn_clk { + function = "pwm_syn_clk"; + groups = "pwm_syn_clk_grp"; + }; + + pinctrl_sys_irq: sys_irq { + function = "sys_irq"; + groups = "sys_irq_grp"; + }; }; }; - gpiomode: gpiomode@fffe0098 { - compatible = "brcm,bcm6358-gpiomode", "syscon"; - reg = <0xfffe0098 0x4>; - }; - leds: led-controller@fffe00d0 { #address-cells = <1>; #size-cells = <0>; diff --git a/target/linux/bmips/dts/bcm6362.dtsi b/target/linux/bmips/dts/bcm6362.dtsi index 724ce5a2f8..d531ed4fe5 100644 --- a/target/linux/bmips/dts/bcm6362.dtsi +++ b/target/linux/bmips/dts/bcm6362.dtsi @@ -147,174 +147,176 @@ timeout-sec = <30>; }; - pinctrl: pin-controller@10000080 { - compatible = "brcm,bcm6362-pinctrl"; - reg = <0x10000080 0x8>, - <0x10000088 0x8>, - <0x10000090 0x4>, - <0x10000098 0x4>, - <0x1000009c 0x4>, - <0x100000b8 0x4>; - reg-names = "dirout", "dat", "led", - "mode", "ctrl", "basemode"; - - gpio-controller; - #gpio-cells = <2>; - - interrupt-parent = <&ext_intc>; - interrupts = <0 0>, <1 0>, <2 0>, <3 0>; - interrupt-names = "gpio24", "gpio25", - "gpio26", "gpio27"; - - pinctrl_usb_device_led: usb_device_led { - function = "usb_device_led"; - pins = "gpio0"; - }; + gpio: syscon@10000080 { + compatible = "syscon", "simple-mfd"; + reg = <0x10000080 0x80>; + native-endian; - pinctrl_sys_irq: sys_irq { - function = "sys_irq"; - pins = "gpio1"; - }; + pinctrl: pin-controller { + compatible = "brcm,bcm6362-pinctrl"; - pinctrl_serial_led: serial_led { - pinctrl_serial_led_clk: serial_led_clk { - function = "serial_led_clk"; - pins = "gpio2"; - }; + gpio-controller; + #gpio-cells = <2>; - pinctrl_serial_led_data: serial_led_data { - function = "serial_led_data"; - pins = "gpio3"; - }; - }; + interrupts-extended = <&ext_intc 0 0>, + <&ext_intc 1 0>, + <&ext_intc 2 0>, + <&ext_intc 3 0>; + interrupt-names = "gpio24", + "gpio25", + "gpio26", + "gpio27"; - pinctrl_robosw_led_data: robosw_led_data { - function = "robosw_led_data"; - pins = "gpio4"; - }; + pinctrl_usb_device_led: usb_device_led { + function = "usb_device_led"; + pins = "gpio0"; + }; - pinctrl_robosw_led_clk: robosw_led_clk { - function = "robosw_led_clk"; - pins = "gpio5"; - }; + pinctrl_sys_irq: sys_irq { + function = "sys_irq"; + pins = "gpio1"; + }; - pinctrl_robosw_led0: robosw_led0 { - function = "robosw_led0"; - pins = "gpio6"; - }; + pinctrl_serial_led: serial_led { + pinctrl_serial_led_clk: serial_led_clk { + function = "serial_led_clk"; + pins = "gpio2"; + }; - pinctrl_robosw_led1: robosw_led1 { - function = "robosw_led1"; - pins = "gpio7"; - }; + pinctrl_serial_led_data: serial_led_data { + function = "serial_led_data"; + pins = "gpio3"; + }; + }; - pinctrl_inet_led: inet_led { - function = "inet_led"; - pins = "gpio8"; - }; + pinctrl_robosw_led_data: robosw_led_data { + function = "robosw_led_data"; + pins = "gpio4"; + }; - pinctrl_spi_cs2: spi_cs2 { - function = "spi_cs2"; - pins = "gpio9"; - }; + pinctrl_robosw_led_clk: robosw_led_clk { + function = "robosw_led_clk"; + pins = "gpio5"; + }; - pinctrl_spi_cs3: spi_cs3 { - function = "spi_cs3"; - pins = "gpio10"; - }; + pinctrl_robosw_led0: robosw_led0 { + function = "robosw_led0"; + pins = "gpio6"; + }; - pinctrl_ntr_pulse: ntr_pulse { - function = "ntr_pulse"; - pins = "gpio11"; - }; + pinctrl_robosw_led1: robosw_led1 { + function = "robosw_led1"; + pins = "gpio7"; + }; - pinctrl_uart1_scts: uart1_scts { - function = "uart1_scts"; - pins = "gpio12"; - }; + pinctrl_inet_led: inet_led { + function = "inet_led"; + pins = "gpio8"; + }; - pinctrl_uart1_srts: uart1_srts { - function = "uart1_srts"; - pins = "gpio13"; - }; + pinctrl_spi_cs2: spi_cs2 { + function = "spi_cs2"; + pins = "gpio9"; + }; - pinctrl_uart1: uart1 { - pinctrl_uart1_sdin: uart1_sdin { - function = "uart1_sdin"; - pins = "gpio14"; + pinctrl_spi_cs3: spi_cs3 { + function = "spi_cs3"; + pins = "gpio10"; }; - pinctrl_uart1_sdout: uart1_sdout { - function = "uart1_sdout"; - pins = "gpio15"; + pinctrl_ntr_pulse: ntr_pulse { + function = "ntr_pulse"; + pins = "gpio11"; }; - }; - pinctrl_adsl_spi: adsl_spi { - pinctrl_adsl_spi_miso: adsl_spi_miso { - function = "adsl_spi_miso"; - pins = "gpio16"; + pinctrl_uart1_scts: uart1_scts { + function = "uart1_scts"; + pins = "gpio12"; }; - pinctrl_adsl_spi_mosi: adsl_spi_mosi { - function = "adsl_spi_mosi"; - pins = "gpio17"; + pinctrl_uart1_srts: uart1_srts { + function = "uart1_srts"; + pins = "gpio13"; }; - pinctrl_adsl_spi_clk: adsl_spi_clk { - function = "adsl_spi_clk"; - pins = "gpio18"; + pinctrl_uart1: uart1 { + pinctrl_uart1_sdin: uart1_sdin { + function = "uart1_sdin"; + pins = "gpio14"; + }; + + pinctrl_uart1_sdout: uart1_sdout { + function = "uart1_sdout"; + pins = "gpio15"; + }; }; - pinctrl_adsl_spi_cs: adsl_spi_cs { - function = "adsl_spi_cs"; - pins = "gpio19"; + pinctrl_adsl_spi: adsl_spi { + pinctrl_adsl_spi_miso: adsl_spi_miso { + function = "adsl_spi_miso"; + pins = "gpio16"; + }; + + pinctrl_adsl_spi_mosi: adsl_spi_mosi { + function = "adsl_spi_mosi"; + pins = "gpio17"; + }; + + pinctrl_adsl_spi_clk: adsl_spi_clk { + function = "adsl_spi_clk"; + pins = "gpio18"; + }; + + pinctrl_adsl_spi_cs: adsl_spi_cs { + function = "adsl_spi_cs"; + pins = "gpio19"; + }; }; - }; - pinctrl_ephy0_led: ephy0_led { - function = "ephy0_led"; - pins = "gpio20"; - }; + pinctrl_ephy0_led: ephy0_led { + function = "ephy0_led"; + pins = "gpio20"; + }; - pinctrl_ephy1_led: ephy1_led { - function = "ephy1_led"; - pins = "gpio21"; - }; + pinctrl_ephy1_led: ephy1_led { + function = "ephy1_led"; + pins = "gpio21"; + }; - pinctrl_ephy2_led: ephy2_led { - function = "ephy2_led"; - pins = "gpio22"; - }; + pinctrl_ephy2_led: ephy2_led { + function = "ephy2_led"; + pins = "gpio22"; + }; - pinctrl_ephy3_led: ephy3_led { - function = "ephy3_led"; - pins = "gpio23"; - }; + pinctrl_ephy3_led: ephy3_led { + function = "ephy3_led"; + pins = "gpio23"; + }; - pinctrl_ext_irq0: ext_irq0 { - function = "ext_irq0"; - pins = "gpio24"; - }; + pinctrl_ext_irq0: ext_irq0 { + function = "ext_irq0"; + pins = "gpio24"; + }; - pinctrl_ext_irq1: ext_irq1 { - function = "ext_irq1"; - pins = "gpio25"; - }; + pinctrl_ext_irq1: ext_irq1 { + function = "ext_irq1"; + pins = "gpio25"; + }; - pinctrl_ext_irq2: ext_irq2 { - function = "ext_irq2"; - pins = "gpio26"; - }; + pinctrl_ext_irq2: ext_irq2 { + function = "ext_irq2"; + pins = "gpio26"; + }; - pinctrl_ext_irq3: ext_irq3 { - function = "ext_irq3"; - pins = "gpio27"; - }; + pinctrl_ext_irq3: ext_irq3 { + function = "ext_irq3"; + pins = "gpio27"; + }; - pinctrl_nand: nand { - function = "nand"; - group = "nand_grp"; + pinctrl_nand: nand { + function = "nand"; + group = "nand_grp"; + }; }; }; diff --git a/target/linux/bmips/dts/bcm6368.dtsi b/target/linux/bmips/dts/bcm6368.dtsi index babd8c7385..0b434c5c01 100644 --- a/target/linux/bmips/dts/bcm6368.dtsi +++ b/target/linux/bmips/dts/bcm6368.dtsi @@ -149,185 +149,190 @@ timeout-sec = <30>; }; - pinctrl: pin-controller@10000080 { - compatible = "brcm,bcm6368-pinctrl"; - reg = <0x10000080 0x8>, - <0x10000088 0x8>, - <0x10000098 0x4>; - reg-names = "dirout", "dat", "mode"; - brcm,gpiobasemode = <&gpiobasemode>; - - gpio-controller; - #gpio-cells = <2>; - - interrupts-extended = <&ext_intc1 0 0>, - <&ext_intc1 1 0>, - <&ext_intc0 0 0>, - <&ext_intc0 1 0>, - <&ext_intc0 2 0>, - <&ext_intc0 3 0>; - interrupt-names = "gpio32", "gpio33", "gpio34", "gpio35", - "gpio36", "gpio37"; - - pinctrl_analog_afe_0: analog_afe_0 { - function = "analog_afe_0"; - pins = "gpio0"; - }; - - pinctrl_analog_afe_1: analog_afe_1 { - function = "analog_afe_1"; - pins = "gpio1"; - }; - - pinctrl_sys_irq: sys_irq { - function = "sys_irq"; - pins = "gpio2"; - }; + gpio: syscon@10000080 { + compatible = "syscon", "simple-mfd"; + reg = <0x10000080 0x80>; + native-endian; - pinctrl_serial_led: serial_led { - pinctrl_serial_led_data: serial_led_data { - function = "serial_led_data"; - pins = "gpio3"; + pinctrl: pin-controller { + compatible = "brcm,bcm6368-pinctrl"; + + gpio-controller; + #gpio-cells = <2>; + + interrupts-extended = <&ext_intc1 0 0>, + <&ext_intc1 1 0>, + <&ext_intc0 0 0>, + <&ext_intc0 1 0>, + <&ext_intc0 2 0>, + <&ext_intc0 3 0>; + interrupt-names = "gpio32", + "gpio33", + "gpio34", + "gpio35", + "gpio36", + "gpio37"; + + pinctrl_analog_afe_0: analog_afe_0 { + function = "analog_afe_0"; + pins = "gpio0"; }; - pinctrl_serial_led_clk: serial_led_clk { - function = "serial_led_clk"; - pins = "gpio4"; + pinctrl_analog_afe_1: analog_afe_1 { + function = "analog_afe_1"; + pins = "gpio1"; }; - }; - - pinctrl_inet_led: inet_led { - function = "inet_led"; - pins = "gpio5"; - }; - - pinctrl_ephy0_led: ephy0_led { - function = "ephy0_led"; - pins = "gpio6"; - }; - pinctrl_ephy1_led: ephy1_led { - function = "ephy1_led"; - pins = "gpio7"; - }; - - pinctrl_ephy2_led: ephy2_led { - function = "ephy2_led"; - pins = "gpio8"; - }; - - pinctrl_ephy3_led: ephy3_led { - function = "ephy3_led"; - pins = "gpio9"; - }; + pinctrl_sys_irq: sys_irq { + function = "sys_irq"; + pins = "gpio2"; + }; - pinctrl_robosw_led_data: robosw_led_data { - function = "robosw_led_data"; - pins = "gpio10"; - }; + pinctrl_serial_led: serial_led { + pinctrl_serial_led_data: serial_led_data { + function = "serial_led_data"; + pins = "gpio3"; + }; - pinctrl_robosw_led_clk: robosw_led_clk { - function = "robosw_led_clk"; - pins = "gpio11"; - }; + pinctrl_serial_led_clk: serial_led_clk { + function = "serial_led_clk"; + pins = "gpio4"; + }; + }; - pinctrl_robosw_led0: robosw_led0 { - function = "robosw_led0"; - pins = "gpio12"; - }; + pinctrl_inet_led: inet_led { + function = "inet_led"; + pins = "gpio5"; + }; - pinctrl_robosw_led1: robosw_led1 { - function = "robosw_led1"; - pins = "gpio13"; - }; + pinctrl_ephy0_led: ephy0_led { + function = "ephy0_led"; + pins = "gpio6"; + }; - pinctrl_usb_device_led: usb_device_led { - function = "usb_device_led"; - pins = "gpio14"; - }; + pinctrl_ephy1_led: ephy1_led { + function = "ephy1_led"; + pins = "gpio7"; + }; - pinctrl_pci: pci { - pinctrl_pci_req1: pci_req1 { - function = "pci_req1"; - pins = "gpio16"; + pinctrl_ephy2_led: ephy2_led { + function = "ephy2_led"; + pins = "gpio8"; }; - pinctrl_pci_gnt1: pci_gnt1 { - function = "pci_gnt1"; - pins = "gpio17"; + pinctrl_ephy3_led: ephy3_led { + function = "ephy3_led"; + pins = "gpio9"; }; - pinctrl_pci_intb: pci_intb { - function = "pci_intb"; - pins = "gpio18"; + pinctrl_robosw_led_data: robosw_led_data { + function = "robosw_led_data"; + pins = "gpio10"; }; - pinctrl_pci_req0: pci_req0 { - function = "pci_req0"; - pins = "gpio19"; + pinctrl_robosw_led_clk: robosw_led_clk { + function = "robosw_led_clk"; + pins = "gpio11"; }; - pinctrl_pci_gnt0: pci_gnt0 { - function = "pci_gnt0"; - pins = "gpio20"; + pinctrl_robosw_led0: robosw_led0 { + function = "robosw_led0"; + pins = "gpio12"; }; - }; - pinctrl_pcmcia: pcmcia { - pinctrl_pcmcia_cd1: pcmcia_cd1 { - function = "pcmcia_cd1"; - pins = "gpio22"; + pinctrl_robosw_led1: robosw_led1 { + function = "robosw_led1"; + pins = "gpio13"; }; - pinctrl_pcmcia_cd2: pcmcia_cd2 { - function = "pcmcia_cd2"; - pins = "gpio23"; + pinctrl_usb_device_led: usb_device_led { + function = "usb_device_led"; + pins = "gpio14"; }; - pinctrl_pcmcia_vs1: pcmcia_vs1 { - function = "pcmcia_vs1"; - pins = "gpio24"; + pinctrl_pci: pci { + pinctrl_pci_req1: pci_req1 { + function = "pci_req1"; + pins = "gpio16"; + }; + + pinctrl_pci_gnt1: pci_gnt1 { + function = "pci_gnt1"; + pins = "gpio17"; + }; + + pinctrl_pci_intb: pci_intb { + function = "pci_intb"; + pins = "gpio18"; + }; + + pinctrl_pci_req0: pci_req0 { + function = "pci_req0"; + pins = "gpio19"; + }; + + pinctrl_pci_gnt0: pci_gnt0 { + function = "pci_gnt0"; + pins = "gpio20"; + }; }; - pinctrl_pcmcia_vs2: pcmcia_vs2 { - function = "pcmcia_vs2"; - pins = "gpio25"; + pinctrl_pcmcia: pcmcia { + pinctrl_pcmcia_cd1: pcmcia_cd1 { + function = "pcmcia_cd1"; + pins = "gpio22"; + }; + + pinctrl_pcmcia_cd2: pcmcia_cd2 { + function = "pcmcia_cd2"; + pins = "gpio23"; + }; + + pinctrl_pcmcia_vs1: pcmcia_vs1 { + function = "pcmcia_vs1"; + pins = "gpio24"; + }; + + pinctrl_pcmcia_vs2: pcmcia_vs2 { + function = "pcmcia_vs2"; + pins = "gpio25"; + }; }; - }; - pinctrl_ebi_cs2: ebi_cs2 { - function = "ebi_cs2"; - pins = "gpio26"; - }; + pinctrl_ebi_cs2: ebi_cs2 { + function = "ebi_cs2"; + pins = "gpio26"; + }; - pinctrl_ebi_cs3: ebi_cs3 { - function = "ebi_cs2"; - pins = "gpio27"; - }; + pinctrl_ebi_cs3: ebi_cs3 { + function = "ebi_cs3"; + pins = "gpio27"; + }; - pinctrl_spi_cs2: spi_cs2 { - function = "spi_cs2"; - pins = "gpio28"; - }; + pinctrl_spi_cs2: spi_cs2 { + function = "spi_cs2"; + pins = "gpio28"; + }; - pinctrl_spi_cs3: spi_cs3 { - function = "spi_cs3"; - pins = "gpio29"; - }; + pinctrl_spi_cs3: spi_cs3 { + function = "spi_cs3"; + pins = "gpio29"; + }; - pinctrl_spi_cs4: spi_cs4 { - function = "spi_cs4"; - pins = "gpio30"; - }; + pinctrl_spi_cs4: spi_cs4 { + function = "spi_cs4"; + pins = "gpio30"; + }; - pinctrl_spi_cs5: spi_cs5 { - function = "spi_cs5"; - pins = "gpio31"; - }; + pinctrl_spi_cs5: spi_cs5 { + function = "spi_cs5"; + pins = "gpio31"; + }; - pinctrl_uart1: uart1 { - function = "uart1"; - group = "uart1_grp"; + pinctrl_uart1: uart1 { + function = "uart1"; + group = "uart1_grp"; + }; }; }; diff --git a/target/linux/bmips/patches-5.10/400-Documentation-add-BCM6328-pincontroller-binding-docu.patch b/target/linux/bmips/patches-5.10/400-Documentation-add-BCM6328-pincontroller-binding-docu.patch new file mode 100644 index 0000000000..4ad97ad1e0 --- /dev/null +++ b/target/linux/bmips/patches-5.10/400-Documentation-add-BCM6328-pincontroller-binding-docu.patch @@ -0,0 +1,182 @@ +From 3b6d70e7bae0dbba02435c53f878a042d6d4bd4d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= +Date: Wed, 27 Jul 2016 11:33:56 +0200 +Subject: [PATCH 01/12] Documentation: add BCM6328 pincontroller binding + documentation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add binding documentation for the pincontrol core found in BCM6328 SoCs. + +Signed-off-by: Álvaro Fernández Rojas +Signed-off-by: Jonas Gorski +--- + .../pinctrl/brcm,bcm6328-pinctrl.yaml | 161 ++++++++++++++++++ + 1 file changed, 161 insertions(+) + create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml + +--- /dev/null ++++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml +@@ -0,0 +1,161 @@ ++# 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 ++ - Jonas Gorski ++ ++description: |+ ++ The pin controller node should be the child of a syscon node. ++ ++ Refer to the the bindings described in ++ Documentation/devicetree/bindings/mfd/syscon.yaml ++ ++properties: ++ compatible: ++ const: brcm,bcm6328-pinctrl ++ ++ gpio-controller: true ++ ++ '#gpio-cells': ++ description: ++ Specifies the pin number and flags, as defined in ++ include/dt-bindings/gpio/gpio.h ++ const: 2 ++ ++ interrupts-extended: ++ description: ++ One interrupt per each of the 4 GPIO ports supported by the controller, ++ sorted by port number ascending order. ++ minItems: 4 ++ maxItems: 4 ++ ++patternProperties: ++ '^.*$': ++ if: ++ type: object ++ then: ++ properties: ++ function: ++ $ref: "/schemas/types.yaml#/definitions/string" ++ 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: ++ $ref: "/schemas/types.yaml#/definitions/string" ++ enum: [ gpio6, gpio7, gpio11, gpio16, gpio17, gpio18, gpio19, ++ gpio20, gpio25, gpio26, gpio27, gpio28, hsspi_cs1, ++ usb_port1 ] ++ ++required: ++ - compatible ++ - gpio-controller ++ - '#gpio-cells' ++ ++additionalProperties: false ++ ++examples: ++ - | ++ gpio@10000080 { ++ compatible = "syscon", "simple-mfd"; ++ reg = <0x10000080 0x80>; ++ ++ pinctrl: pinctrl { ++ compatible = "brcm,bcm6328-pinctrl"; ++ ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ interrupts-extended = <&ext_intc 3 0>, ++ <&ext_intc 2 0>, ++ <&ext_intc 1 0>, ++ <&ext_intc 0 0>; ++ interrupt-names = "gpio12", ++ "gpio15", ++ "gpio23", ++ "gpio24"; ++ ++ pinctrl_serial_led: serial_led { ++ pinctrl_serial_led_data: serial_led_data { ++ function = "serial_led_data"; ++ pins = "gpio6"; ++ }; ++ ++ pinctrl_serial_led_clk: serial_led_clk { ++ function = "serial_led_clk"; ++ pins = "gpio7"; ++ }; ++ }; ++ ++ pinctrl_inet_act_led: inet_act_led { ++ function = "inet_act_led"; ++ pins = "gpio11"; ++ }; ++ ++ pinctrl_pcie_clkreq: pcie_clkreq { ++ function = "pcie_clkreq"; ++ pins = "gpio16"; ++ }; ++ ++ pinctrl_ephy0_spd_led: ephy0_spd_led { ++ function = "led"; ++ pins = "gpio17"; ++ }; ++ ++ pinctrl_ephy1_spd_led: ephy1_spd_led { ++ function = "led"; ++ pins = "gpio18"; ++ }; ++ ++ pinctrl_ephy2_spd_led: ephy2_spd_led { ++ function = "led"; ++ pins = "gpio19"; ++ }; ++ ++ pinctrl_ephy3_spd_led: ephy3_spd_led { ++ function = "led"; ++ pins = "gpio20"; ++ }; ++ ++ pinctrl_ephy0_act_led: ephy0_act_led { ++ function = "ephy0_act_led"; ++ pins = "gpio25"; ++ }; ++ ++ pinctrl_ephy1_act_led: ephy1_act_led { ++ function = "ephy1_act_led"; ++ pins = "gpio26"; ++ }; ++ ++ pinctrl_ephy2_act_led: ephy2_act_led { ++ function = "ephy2_act_led"; ++ pins = "gpio27"; ++ }; ++ ++ pinctrl_ephy3_act_led: ephy3_act_led { ++ function = "ephy3_act_led"; ++ pins = "gpio28"; ++ }; ++ ++ pinctrl_hsspi_cs1: hsspi_cs1 { ++ function = "hsspi_cs1"; ++ pins = "hsspi_cs1"; ++ }; ++ ++ pinctrl_usb_port1_device: usb_port1_device { ++ function = "usb_device_port"; ++ pins = "usb_port1"; ++ }; ++ ++ pinctrl_usb_port1_host: usb_port1_host { ++ function = "usb_host_port"; ++ pins = "usb_port1"; ++ }; ++ }; ++ }; diff --git a/target/linux/bmips/patches-5.10/400-pinctrl-add-bcm63xx-base-code.patch b/target/linux/bmips/patches-5.10/400-pinctrl-add-bcm63xx-base-code.patch deleted file mode 100644 index 0f42bd2f83..0000000000 --- a/target/linux/bmips/patches-5.10/400-pinctrl-add-bcm63xx-base-code.patch +++ /dev/null @@ -1,226 +0,0 @@ -From ab2f33e35e35905a76204138143875251f3e1088 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Fri, 24 Jun 2016 22:07:42 +0200 -Subject: [PATCH 01/13] pinctrl: add bcm63xx base code - -Setup directory and add a helper for bcm63xx pinctrl support. - -Signed-off-by: Jonas Gorski ---- - drivers/pinctrl/Kconfig | 1 + - drivers/pinctrl/Makefile | 1 + - drivers/pinctrl/bcm63xx/Kconfig | 3 + - drivers/pinctrl/bcm63xx/Makefile | 1 + - drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.c | 142 ++++++++++++++++++++++++++++++ - drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.h | 14 +++ - 7 files changed, 163 insertions(+) - create mode 100644 drivers/pinctrl/bcm63xx/Kconfig - create mode 100644 drivers/pinctrl/bcm63xx/Makefile - create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.c - create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.h - ---- a/drivers/pinctrl/Kconfig -+++ b/drivers/pinctrl/Kconfig -@@ -377,6 +377,7 @@ config PINCTRL_OCELOT - source "drivers/pinctrl/actions/Kconfig" - source "drivers/pinctrl/aspeed/Kconfig" - source "drivers/pinctrl/bcm/Kconfig" -+source "drivers/pinctrl/bcm63xx/Kconfig" - source "drivers/pinctrl/berlin/Kconfig" - source "drivers/pinctrl/freescale/Kconfig" - source "drivers/pinctrl/intel/Kconfig" ---- a/drivers/pinctrl/Makefile -+++ b/drivers/pinctrl/Makefile -@@ -51,6 +51,7 @@ obj-$(CONFIG_PINCTRL_EQUILIBRIUM) += p - obj-y += actions/ - obj-$(CONFIG_ARCH_ASPEED) += aspeed/ - obj-y += bcm/ -+obj-y += bcm63xx/ - obj-$(CONFIG_PINCTRL_BERLIN) += berlin/ - obj-y += freescale/ - obj-$(CONFIG_X86) += intel/ ---- /dev/null -+++ b/drivers/pinctrl/bcm63xx/Kconfig -@@ -0,0 +1,3 @@ -+config PINCTRL_BCM63XX -+ bool -+ select GPIO_GENERIC ---- /dev/null -+++ b/drivers/pinctrl/bcm63xx/Makefile -@@ -0,0 +1 @@ -+obj-$(CONFIG_PINCTRL_BCM63XX) += pinctrl-bcm63xx.o ---- /dev/null -+++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.c -@@ -0,0 +1,155 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2016 Jonas Gorski -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "pinctrl-bcm63xx.h" -+#include "../core.h" -+ -+#define BANK_SIZE sizeof(u32) -+#define PINS_PER_BANK (BANK_SIZE * BITS_PER_BYTE) -+ -+#ifdef CONFIG_OF -+static int bcm63xx_gpio_of_xlate(struct gpio_chip *gc, -+ const struct of_phandle_args *gpiospec, -+ u32 *flags) -+{ -+ struct gpio_chip *base = gpiochip_get_data(gc); -+ int pin = gpiospec->args[0]; -+ -+ if (gc != &base[pin / PINS_PER_BANK]) -+ return -EINVAL; -+ -+ pin = pin % PINS_PER_BANK; -+ -+ if (pin >= gc->ngpio) -+ return -EINVAL; -+ -+ if (flags) -+ *flags = gpiospec->args[1]; -+ -+ return pin; -+} -+#endif -+ -+static int bcm63xx_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) -+{ -+ struct gpio_chip *base = gpiochip_get_data(chip); -+ char irq_name[7]; /* "gpioXX" */ -+ -+ /* FIXME: this is ugly */ -+ sprintf(irq_name, "gpio%d", gpio + PINS_PER_BANK * (chip - base)); -+ return of_irq_get_byname(chip->of_node, irq_name); -+} -+ -+static int bcm63xx_setup_gpio(struct device *dev, struct gpio_chip *gc, -+ void __iomem *dirout, void __iomem *data, -+ size_t sz, int ngpio) -+ -+{ -+ int banks, chips, i, ret = -EINVAL; -+ -+ chips = DIV_ROUND_UP(ngpio, PINS_PER_BANK); -+ banks = sz / BANK_SIZE; -+ -+ for (i = 0; i < chips; i++) { -+ int offset, pins; -+ int reg_offset; -+ char *label; -+ -+ label = devm_kasprintf(dev, GFP_KERNEL, "bcm63xx-gpio.%i", i); -+ if (!label) -+ return -ENOMEM; -+ -+ offset = i * PINS_PER_BANK; -+ pins = min_t(int, ngpio - offset, PINS_PER_BANK); -+ -+ /* the registers are treated like a huge big endian register */ -+ reg_offset = (banks - i - 1) * BANK_SIZE; -+ -+ ret = bgpio_init(&gc[i], dev, BANK_SIZE, data + reg_offset, -+ NULL, NULL, dirout + reg_offset, NULL, -+ BGPIOF_BIG_ENDIAN_BYTE_ORDER); -+ if (ret) -+ return ret; -+ -+ gc[i].request = gpiochip_generic_request; -+ gc[i].free = gpiochip_generic_free; -+ -+ if (of_get_property(dev->of_node, "interrupt-names", NULL)) -+ gc[i].to_irq = bcm63xx_gpio_to_irq; -+ -+#ifdef CONFIG_OF -+ gc[i].of_gpio_n_cells = 2; -+ gc[i].of_xlate = bcm63xx_gpio_of_xlate; -+#endif -+ -+ gc[i].label = label; -+ gc[i].ngpio = pins; -+ -+ devm_gpiochip_add_data(dev, &gc[i], gc); -+ } -+ -+ return 0; -+} -+ -+static void bcm63xx_setup_pinranges(struct gpio_chip *gc, const char *name, -+ int ngpio) -+{ -+ int i, chips = DIV_ROUND_UP(ngpio, PINS_PER_BANK); -+ -+ for (i = 0; i < chips; i++) { -+ int offset, pins; -+ -+ offset = i * PINS_PER_BANK; -+ pins = min_t(int, ngpio - offset, PINS_PER_BANK); -+ -+ gpiochip_add_pin_range(&gc[i], name, 0, offset, pins); -+ } -+} -+ -+struct pinctrl_dev *bcm63xx_pinctrl_register(struct platform_device *pdev, -+ struct pinctrl_desc *desc, -+ void *priv, struct gpio_chip *gc, -+ int ngpio) -+{ -+ struct pinctrl_dev *pctldev; -+ struct resource *res; -+ void __iomem *dirout, *data; -+ size_t sz; -+ int ret; -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dirout"); -+ dirout = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(dirout)) -+ return ERR_CAST(dirout); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat"); -+ data = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(data)) -+ return ERR_CAST(data); -+ -+ sz = resource_size(res); -+ -+ ret = bcm63xx_setup_gpio(&pdev->dev, gc, dirout, data, sz, ngpio); -+ if (ret) -+ return ERR_PTR(ret); -+ -+ pctldev = devm_pinctrl_register(&pdev->dev, desc, priv); -+ if (IS_ERR(pctldev)) -+ return pctldev; -+ -+ bcm63xx_setup_pinranges(gc, pinctrl_dev_get_devname(pctldev), ngpio); -+ -+ dev_info(&pdev->dev, "registered at mmio %p\n", dirout); -+ -+ return pctldev; -+} ---- /dev/null -+++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.h -@@ -0,0 +1,14 @@ -+#ifndef __PINCTRL_BCM63XX -+#define __PINCTRL_BCM63XX -+ -+#include -+#include -+#include -+#include -+ -+struct pinctrl_dev *bcm63xx_pinctrl_register(struct platform_device *pdev, -+ struct pinctrl_desc *desc, -+ void *priv, struct gpio_chip *gc, -+ int ngpio); -+ -+#endif diff --git a/target/linux/bmips/patches-5.10/401-Documentation-add-BCM6328-pincontroller-binding-docu.patch b/target/linux/bmips/patches-5.10/401-Documentation-add-BCM6328-pincontroller-binding-docu.patch deleted file mode 100644 index 3a2a7811db..0000000000 --- a/target/linux/bmips/patches-5.10/401-Documentation-add-BCM6328-pincontroller-binding-docu.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 4bdd40849632608d5cb7d3a64380cd76e7eea07b Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Wed, 27 Jul 2016 11:33:56 +0200 -Subject: [PATCH 02/16] Documentation: add BCM6328 pincontroller binding - documentation - -Add binding documentation for the pincontrol core found in BCM6328 SoCs. - -Signed-off-by: Jonas Gorski ---- - .../bindings/pinctrl/brcm,bcm6328-pinctrl.txt | 61 ++++++++++++++++++++++ - 1 file changed, 61 insertions(+) - create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.txt - ---- /dev/null -+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.txt -@@ -0,0 +1,61 @@ -+* Broadcom BCM6328 pin controller -+ -+Required properties: -+- compatible: Must be "brcm,bcm6328-pinctrl". -+- reg: Register specifies of dirout, dat, mode, mux registers. -+- reg-names: Must be "dirout", "dat", "mode", "mux". -+- gpio-controller: Identifies this node as a GPIO controller. -+- #gpio-cells: Must be <2> -+ -+Example: -+ -+pinctrl: pin-controller@10000080 { -+ compatible = "brcm,bcm6328-pinctrl"; -+ reg = <0x10000080 0x8>, -+ <0x10000088 0x8>, -+ <0x10000098 0x4>, -+ <0x1000009c 0xc>; -+ reg-names = "dirout", "dat", "mode", "mux"; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+}; -+ -+Available pins/groups and functions: -+ -+name pins functions -+----------------------------------------------------------- -+gpio0 0 led -+gpio1 1 led -+gpio2 2 led -+gpio3 3 led -+gpio4 4 led -+gpio5 5 led -+gpio6 6 led, serial_led_data -+gpio7 7 led, serial_led_clk -+gpio8 8 led -+gpio9 9 led -+gpio10 10 led -+gpio11 11 led -+gpio12 12 led -+gpio13 13 led -+gpio14 14 led -+gpio15 15 led -+gpio16 16 led, pcie_clkreq -+gpio17 17 led -+gpio18 18 led -+gpio19 19 led -+gpio20 20 led -+gpio21 21 led -+gpio22 22 led -+gpio23 23 led -+gpio24 24 - -+gpio25 25 ephy0_act_led -+gpio26 26 ephy1_act_led -+gpio27 27 ephy2_act_led -+gpio28 28 ephy3_act_led -+gpio29 29 - -+gpio30 30 - -+gpio31 31 - -+hsspi_cs1 - hsspi_cs1 -+usb_port1 - usb_host_port, usb_device_port diff --git a/target/linux/bmips/patches-5.10/401-pinctrl-add-a-pincontrol-driver-for-BCM6328.patch b/target/linux/bmips/patches-5.10/401-pinctrl-add-a-pincontrol-driver-for-BCM6328.patch new file mode 100644 index 0000000000..0e223f2fca --- /dev/null +++ b/target/linux/bmips/patches-5.10/401-pinctrl-add-a-pincontrol-driver-for-BCM6328.patch @@ -0,0 +1,636 @@ +From 3373a507212e6394921781766e9cd0dc155c62ba Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= +Date: Fri, 24 Jun 2016 22:12:50 +0200 +Subject: [PATCH 02/12] pinctrl: add a pincontrol driver for BCM6328 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add a pincontrol driver for BCM6328. BCM628 supports muxing 32 pins as +GPIOs, as LEDs for the integrated LED controller, or various other +functions. Its pincontrol mux registers also control other aspects, like +switching the second USB port between host and device mode. + +Signed-off-by: Álvaro Fernández Rojas +Signed-off-by: Jonas Gorski +--- + drivers/pinctrl/bcm/Kconfig | 11 + + drivers/pinctrl/bcm/Makefile | 1 + + drivers/pinctrl/bcm/pinctrl-bcm6328.c | 581 ++++++++++++++++++++++++++ + 3 files changed, 593 insertions(+) + create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6328.c + +--- a/drivers/pinctrl/bcm/Kconfig ++++ b/drivers/pinctrl/bcm/Kconfig +@@ -29,6 +29,17 @@ config PINCTRL_BCM2835 + help + Say Y here to enable the Broadcom BCM2835 GPIO driver. + ++config PINCTRL_BCM6328 ++ bool "Broadcom BCM6328 GPIO driver" ++ depends on OF_GPIO && (BMIPS_GENERIC || COMPILE_TEST) ++ select PINMUX ++ select PINCONF ++ select GENERIC_PINCONF ++ select MFD_SYSCON ++ default BMIPS_GENERIC ++ help ++ Say Y here to enable the Broadcom BCM6328 GPIO driver. ++ + config PINCTRL_IPROC_GPIO + bool "Broadcom iProc GPIO (with PINCONF) driver" + depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST) +--- a/drivers/pinctrl/bcm/Makefile ++++ b/drivers/pinctrl/bcm/Makefile +@@ -3,6 +3,7 @@ + + obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o + obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o ++obj-$(CONFIG_PINCTRL_BCM6328) += pinctrl-bcm6328.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 +--- /dev/null ++++ b/drivers/pinctrl/bcm/pinctrl-bcm6328.c +@@ -0,0 +1,581 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Driver for BCM6328 GPIO unit (pinctrl + GPIO) ++ * ++ * Copyright (C) 2021 Álvaro Fernández Rojas ++ * Copyright (C) 2016 Jonas Gorski ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include "../core.h" ++#include "../pinctrl-utils.h" ++ ++#define MODULE_NAME "bcm6328-pinctrl" ++#define BCM6328_NUM_GPIOS 32 ++ ++#define BANK_SIZE sizeof(uint32_t) ++#define PINS_PER_BANK (BANK_SIZE * BITS_PER_BYTE) ++ ++#define BCM6328_DIROUT_REG 0x04 ++#define BCM6328_DATA_REG 0x0c ++#define BCM6328_MODE_REG 0x18 ++#define BCM6328_MUX_HI_REG 0x1c ++#define BCM6328_MUX_LO_REG 0x20 ++#define BCM6328_MUX_OTHER_REG 0x24 ++ ++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; ++}; ++ ++struct bcm6328_pinctrl { ++ struct device *dev; ++ struct regmap *regs; ++ ++ struct pinctrl_dev *pctl_dev; ++ struct gpio_chip gpio_chip; ++ struct pinctrl_desc pctl_desc; ++ struct pinctrl_gpio_range gpio_range; ++}; ++ ++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_bank_pin(unsigned int pin) ++{ ++ return pin % PINS_PER_BANK; ++} ++ ++static inline unsigned int bcm6318_mux_off(unsigned int pin) ++{ ++ static const unsigned int bcm6328_mux[] = { ++ BCM6328_MUX_LO_REG, ++ BCM6328_MUX_HI_REG, ++ BCM6328_MUX_OTHER_REG ++ }; ++ ++ return bcm6328_mux[pin / 16]; ++} ++ ++static inline unsigned int bcm6328_reg_off(unsigned int reg, unsigned int pin) ++{ ++ return reg - (pin / PINS_PER_BANK) * BANK_SIZE; ++} ++ ++static int bcm6328_gpio_direction_input(struct gpio_chip *chip, ++ unsigned int pin) ++{ ++ struct bcm6328_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int dirout = bcm6328_reg_off(BCM6328_DIROUT_REG, pin); ++ unsigned int bank_pin = bcm6328_bank_pin(pin); ++ int ret; ++ ++ /* ++ * Check with the pinctrl driver whether this pin is usable as ++ * an input GPIO ++ */ ++ ret = pinctrl_gpio_direction_input(chip->base + pin); ++ if (ret) ++ return ret; ++ ++ regmap_update_bits(pc->regs, dirout, BIT(bank_pin), 0); ++ ++ return 0; ++} ++ ++static int bcm6328_gpio_direction_output(struct gpio_chip *chip, ++ unsigned int pin, int value) ++{ ++ struct bcm6328_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int data = bcm6328_reg_off(BCM6328_DATA_REG, pin); ++ unsigned int dirout = bcm6328_reg_off(BCM6328_DIROUT_REG, pin); ++ unsigned int bank_pin = bcm6328_bank_pin(pin); ++ unsigned int val = value ? BIT(bank_pin) : 0; ++ int ret; ++ ++ /* ++ * Check with the pinctrl driver whether this pin is usable as ++ * an output GPIO ++ */ ++ ret = pinctrl_gpio_direction_output(chip->base + pin); ++ if (ret) ++ return ret; ++ ++ regmap_update_bits(pc->regs, dirout, BIT(bank_pin), BIT(bank_pin)); ++ regmap_update_bits(pc->regs, data, BIT(bank_pin), val); ++ ++ return 0; ++} ++ ++static int bcm6328_gpio_get(struct gpio_chip *chip, unsigned int pin) ++{ ++ struct bcm6328_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int data = bcm6328_reg_off(BCM6328_DATA_REG, pin); ++ unsigned int bank_pin = bcm6328_bank_pin(pin); ++ unsigned int val; ++ ++ regmap_read(pc->regs, data, &val); ++ ++ return !!(val & BIT(bank_pin)); ++} ++ ++static int bcm6328_gpio_get_direction(struct gpio_chip *chip, unsigned int pin) ++{ ++ struct bcm6328_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int dirout = bcm6328_reg_off(BCM6328_DIROUT_REG, pin); ++ unsigned int bank_pin = bcm6328_bank_pin(pin); ++ unsigned int val; ++ ++ regmap_read(pc->regs, dirout, &val); ++ ++ if (val & BIT(bank_pin)) ++ return GPIO_LINE_DIRECTION_OUT; ++ ++ return GPIO_LINE_DIRECTION_IN; ++} ++ ++static void bcm6328_gpio_set(struct gpio_chip *chip, unsigned int pin, ++ int value) ++{ ++ struct bcm6328_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int data = bcm6328_reg_off(BCM6328_DATA_REG, pin); ++ unsigned int bank_pin = bcm6328_bank_pin(pin); ++ unsigned int val = value ? BIT(bank_pin) : 0; ++ ++ regmap_update_bits(pc->regs, data, BIT(bank_pin), val); ++} ++ ++static int bcm6328_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) ++{ ++ char irq_name[7]; ++ ++ sprintf(irq_name, "gpio%d", gpio); ++ ++ return of_irq_get_byname(chip->of_node, irq_name); ++} ++ ++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 bcm6328_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, bcm6318_mux_off(pin), ++ 3UL << ((pin % 16) * 2), ++ mux << ((pin % 16) * 2)); ++} ++ ++static int bcm6328_pinctrl_set_mux(struct pinctrl_dev *pctldev, ++ unsigned selector, unsigned group) ++{ ++ struct bcm6328_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 bcm6328_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 = { ++ .get_groups_count = bcm6328_pinctrl_get_group_count, ++ .get_group_name = bcm6328_pinctrl_get_group_name, ++ .get_group_pins = bcm6328_pinctrl_get_group_pins, ++ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, ++ .dt_free_map = pinctrl_utils_free_map, ++}; ++ ++static struct pinmux_ops bcm6328_pmx_ops = { ++ .get_functions_count = bcm6328_pinctrl_get_func_count, ++ .get_function_name = bcm6328_pinctrl_get_func_name, ++ .get_function_groups = bcm6328_pinctrl_get_groups, ++ .set_mux = bcm6328_pinctrl_set_mux, ++ .gpio_request_enable = bcm6328_gpio_request_enable, ++ .strict = true, ++}; ++ ++static int bcm6328_pinctrl_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *np = dev->of_node; ++ struct bcm6328_pinctrl *pc; ++ int err; ++ ++ pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); ++ if (!pc) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, pc); ++ pc->dev = dev; ++ ++ pc->regs = syscon_node_to_regmap(dev->parent->of_node); ++ if (IS_ERR(pc->regs)) ++ return PTR_ERR(pc->regs); ++ ++ pc->gpio_chip.label = MODULE_NAME; ++ pc->gpio_chip.owner = THIS_MODULE; ++ pc->gpio_chip.request = gpiochip_generic_request; ++ pc->gpio_chip.free = gpiochip_generic_free; ++ pc->gpio_chip.direction_input = bcm6328_gpio_direction_input; ++ pc->gpio_chip.direction_output = bcm6328_gpio_direction_output; ++ pc->gpio_chip.get_direction = bcm6328_gpio_get_direction; ++ pc->gpio_chip.get = bcm6328_gpio_get; ++ pc->gpio_chip.set = bcm6328_gpio_set; ++ pc->gpio_chip.set_config = gpiochip_generic_config; ++ pc->gpio_chip.base = -1; ++ pc->gpio_chip.ngpio = BCM6328_NUM_GPIOS; ++ pc->gpio_chip.can_sleep = false; ++ pc->gpio_chip.parent = dev; ++ pc->gpio_chip.of_node = np; ++ ++ if (of_get_property(np, "interrupt-names", NULL)) ++ pc->gpio_chip.to_irq = bcm6328_gpio_to_irq; ++ ++ err = gpiochip_add_data(&pc->gpio_chip, pc); ++ if (err) { ++ dev_err(dev, "could not add GPIO chip\n"); ++ return err; ++ } ++ ++ pc->pctl_desc.name = MODULE_NAME, ++ pc->pctl_desc.pins = bcm6328_pins, ++ pc->pctl_desc.npins = ARRAY_SIZE(bcm6328_pins), ++ pc->pctl_desc.pctlops = &bcm6328_pctl_ops, ++ pc->pctl_desc.pmxops = &bcm6328_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)) { ++ gpiochip_remove(&pc->gpio_chip); ++ return PTR_ERR(pc->pctl_dev); ++ } ++ ++ pc->gpio_range.name = MODULE_NAME; ++ pc->gpio_range.npins = BCM6328_NUM_GPIOS; ++ pc->gpio_range.base = pc->gpio_chip.base; ++ pc->gpio_range.gc = &pc->gpio_chip; ++ pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range); ++ ++ dev_info(dev, "registered\n"); ++ ++ return 0; ++} ++ ++static const struct of_device_id bcm6328_pinctrl_match[] = { ++ { .compatible = "brcm,bcm6328-pinctrl", }, ++ { }, ++}; ++ ++static struct platform_driver bcm6328_pinctrl_driver = { ++ .probe = bcm6328_pinctrl_probe, ++ .driver = { ++ .name = MODULE_NAME, ++ .of_match_table = bcm6328_pinctrl_match, ++ }, ++}; ++ ++builtin_platform_driver(bcm6328_pinctrl_driver); diff --git a/target/linux/bmips/patches-5.10/402-Documentation-add-BCM6358-pincontroller-binding-docu.patch b/target/linux/bmips/patches-5.10/402-Documentation-add-BCM6358-pincontroller-binding-docu.patch new file mode 100644 index 0000000000..e4c6343e3f --- /dev/null +++ b/target/linux/bmips/patches-5.10/402-Documentation-add-BCM6358-pincontroller-binding-docu.patch @@ -0,0 +1,152 @@ +From 9fbcbe08479bcb3609952b66627e2d612173229a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= +Date: Wed, 27 Jul 2016 11:36:00 +0200 +Subject: [PATCH 03/12] Documentation: add BCM6358 pincontroller binding + documentation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add binding documentation for the pincontrol core found in BCM6358 SoCs. + +Signed-off-by: Álvaro Fernández Rojas +Signed-off-by: Jonas Gorski +--- + .../pinctrl/brcm,bcm6358-pinctrl.yaml | 131 ++++++++++++++++++ + 1 file changed, 131 insertions(+) + create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml + +--- /dev/null ++++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml +@@ -0,0 +1,131 @@ ++# 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 ++ - Jonas Gorski ++ ++description: |+ ++ The pin controller node should be the child of a syscon node. ++ ++ Refer to the the bindings described in ++ Documentation/devicetree/bindings/mfd/syscon.yaml ++ ++properties: ++ compatible: ++ const: brcm,bcm6358-pinctrl ++ ++ gpio-controller: true ++ ++ '#gpio-cells': ++ description: ++ Specifies the pin number and flags, as defined in ++ include/dt-bindings/gpio/gpio.h ++ const: 2 ++ ++ interrupts-extended: ++ description: ++ One interrupt per each of the 4 GPIO ports supported by the controller, ++ sorted by port number ascending order. ++ minItems: 6 ++ maxItems: 6 ++ ++patternProperties: ++ '^.*$': ++ if: ++ type: object ++ then: ++ properties: ++ function: ++ $ref: "/schemas/types.yaml#/definitions/string" ++ enum: [ ebi_cs, uart1, serial_led, legacy_led, led, spi_cs, utopia, ++ pwm_syn_clk, sys_irq ] ++ ++ pins: ++ $ref: "/schemas/types.yaml#/definitions/string" ++ 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 ++ - gpio-controller ++ - '#gpio-cells' ++ ++additionalProperties: false ++ ++examples: ++ - | ++ gpio@fffe0080 { ++ compatible = "syscon", "simple-mfd"; ++ reg = <0xfffe0080 0x80>; ++ ++ pinctrl: pinctrl { ++ compatible = "brcm,bcm6358-pinctrl"; ++ ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ interrupts-extended = <&ext_intc1 0 0>, ++ <&ext_intc1 1 0>, ++ <&ext_intc0 0 0>, ++ <&ext_intc0 1 0>, ++ <&ext_intc0 2 0>, ++ <&ext_intc0 3 0>; ++ interrupt-names = "gpio32", ++ "gpio33", ++ "gpio34", ++ "gpio35", ++ "gpio36", ++ "gpio37"; ++ ++ pinctrl_ebi_cs: ebi_cs { ++ function = "ebi_cs"; ++ groups = "ebi_cs_grp"; ++ }; ++ ++ pinctrl_uart1: uart1 { ++ function = "uart1"; ++ groups = "uart1_grp"; ++ }; ++ ++ pinctrl_serial_led: serial_led { ++ function = "serial_led"; ++ groups = "serial_led_grp"; ++ }; ++ ++ pinctrl_legacy_led: legacy_led { ++ function = "legacy_led"; ++ groups = "legacy_led_grp"; ++ }; ++ ++ pinctrl_led: led { ++ function = "led"; ++ groups = "led_grp"; ++ }; ++ ++ pinctrl_spi_cs_23: spi_cs { ++ function = "spi_cs"; ++ groups = "spi_cs_grp"; ++ }; ++ ++ pinctrl_utopia: utopia { ++ function = "utopia"; ++ groups = "utopia_grp"; ++ }; ++ ++ pinctrl_pwm_syn_clk: pwm_syn_clk { ++ function = "pwm_syn_clk"; ++ groups = "pwm_syn_clk_grp"; ++ }; ++ ++ pinctrl_sys_irq: sys_irq { ++ function = "sys_irq"; ++ groups = "sys_irq_grp"; ++ }; ++ }; ++ }; diff --git a/target/linux/bmips/patches-5.10/402-pinctrl-add-a-pincontrol-driver-for-BCM6328.patch b/target/linux/bmips/patches-5.10/402-pinctrl-add-a-pincontrol-driver-for-BCM6328.patch deleted file mode 100644 index b4043bdc1c..0000000000 --- a/target/linux/bmips/patches-5.10/402-pinctrl-add-a-pincontrol-driver-for-BCM6328.patch +++ /dev/null @@ -1,495 +0,0 @@ -From 393e9753f6492c1fdf55891ddee60d955ae8b119 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Fri, 24 Jun 2016 22:12:50 +0200 -Subject: [PATCH 03/16] pinctrl: add a pincontrol driver for BCM6328 - -Add a pincontrol driver for BCM6328. BCM628 supports muxing 32 pins as -GPIOs, as LEDs for the integrated LED controller, or various other -functions. Its pincontrol mux registers also control other aspects, like -switching the second USB port between host and device mode. - -Signed-off-by: Jonas Gorski ---- - drivers/pinctrl/bcm63xx/Kconfig | 7 + - drivers/pinctrl/bcm63xx/Makefile | 1 + - drivers/pinctrl/bcm63xx/pinctrl-bcm6328.c | 456 ++++++++++++++++++++++++++++++ - 3 files changed, 464 insertions(+) - create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6328.c - ---- a/drivers/pinctrl/bcm63xx/Kconfig -+++ b/drivers/pinctrl/bcm63xx/Kconfig -@@ -1,3 +1,10 @@ - config PINCTRL_BCM63XX - bool - select GPIO_GENERIC -+ -+config PINCTRL_BCM6328 -+ bool "BCM6328 pincontrol driver" -+ select PINMUX -+ select PINCONF -+ select PINCTRL_BCM63XX -+ select GENERIC_PINCONF ---- a/drivers/pinctrl/bcm63xx/Makefile -+++ b/drivers/pinctrl/bcm63xx/Makefile -@@ -1 +1,2 @@ - obj-$(CONFIG_PINCTRL_BCM63XX) += pinctrl-bcm63xx.o -+obj-$(CONFIG_PINCTRL_BCM6328) += pinctrl-bcm6328.o ---- /dev/null -+++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm6328.c -@@ -0,0 +1,456 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2016 Jonas Gorski -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "../core.h" -+#include "../pinctrl-utils.h" -+ -+#include "pinctrl-bcm63xx.h" -+ -+#define BCM6328_MUX_LO_REG 0x4 -+#define BCM6328_MUX_HI_REG 0x0 -+#define BCM6328_MUX_OTHER_REG 0x8 -+ -+#define BCM6328_NGPIO 32 -+ -+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; -+}; -+ -+struct bcm6328_pinctrl { -+ struct pinctrl_dev *pctldev; -+ struct pinctrl_desc desc; -+ -+ void __iomem *mode; -+ void __iomem *mux[3]; -+ -+ /* register access lock */ -+ spinlock_t lock; -+ -+ struct gpio_chip gpio; -+}; -+ -+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 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 bcm6328_pinctrl *pctl, unsigned pin, -+ u32 mode, u32 mux) -+{ -+ unsigned long flags; -+ u32 reg; -+ -+ spin_lock_irqsave(&pctl->lock, flags); -+ if (pin < 32) { -+ reg = __raw_readl(pctl->mode); -+ reg &= ~BIT(pin); -+ if (mode) -+ reg |= BIT(pin); -+ __raw_writel(reg, pctl->mode); -+ } -+ -+ reg = __raw_readl(pctl->mux[pin / 16]); -+ reg &= ~(3UL << ((pin % 16) * 2)); -+ reg |= mux << ((pin % 16) * 2); -+ __raw_writel(reg, pctl->mux[pin / 16]); -+ -+ spin_unlock_irqrestore(&pctl->lock, flags); -+} -+ -+static int bcm6328_pinctrl_set_mux(struct pinctrl_dev *pctldev, -+ unsigned selector, unsigned group) -+{ -+ struct bcm6328_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); -+ const struct bcm6328_pingroup *grp = &bcm6328_groups[group]; -+ const struct bcm6328_function *f = &bcm6328_funcs[selector]; -+ -+ bcm6328_rmw_mux(pctl, grp->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 bcm6328_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); -+ -+ /* disable all functions using this pin */ -+ bcm6328_rmw_mux(pctl, offset, 0, 0); -+ -+ return 0; -+} -+ -+static struct pinctrl_ops bcm6328_pctl_ops = { -+ .get_groups_count = bcm6328_pinctrl_get_group_count, -+ .get_group_name = bcm6328_pinctrl_get_group_name, -+ .get_group_pins = bcm6328_pinctrl_get_group_pins, -+#ifdef CONFIG_OF -+ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, -+ .dt_free_map = pinctrl_utils_free_map, -+#endif -+}; -+ -+static struct pinmux_ops bcm6328_pmx_ops = { -+ .get_functions_count = bcm6328_pinctrl_get_func_count, -+ .get_function_name = bcm6328_pinctrl_get_func_name, -+ .get_function_groups = bcm6328_pinctrl_get_groups, -+ .set_mux = bcm6328_pinctrl_set_mux, -+ .gpio_request_enable = bcm6328_gpio_request_enable, -+ .strict = true, -+}; -+ -+static int bcm6328_pinctrl_probe(struct platform_device *pdev) -+{ -+ struct bcm6328_pinctrl *pctl; -+ struct resource *res; -+ void __iomem *mode, *mux; -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode"); -+ mode = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(mode)) -+ return PTR_ERR(mode); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mux"); -+ mux = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(mux)) -+ return PTR_ERR(mux); -+ -+ pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL); -+ if (!pctl) -+ return -ENOMEM; -+ -+ spin_lock_init(&pctl->lock); -+ -+ pctl->mode = mode; -+ pctl->mux[0] = mux + BCM6328_MUX_LO_REG; -+ pctl->mux[1] = mux + BCM6328_MUX_HI_REG; -+ pctl->mux[2] = mux + BCM6328_MUX_OTHER_REG; -+ -+ pctl->desc.name = dev_name(&pdev->dev); -+ pctl->desc.owner = THIS_MODULE; -+ pctl->desc.pctlops = &bcm6328_pctl_ops; -+ pctl->desc.pmxops = &bcm6328_pmx_ops; -+ -+ pctl->desc.npins = ARRAY_SIZE(bcm6328_pins); -+ pctl->desc.pins = bcm6328_pins; -+ -+ platform_set_drvdata(pdev, pctl); -+ -+ pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl, -+ &pctl->gpio, BCM6328_NGPIO); -+ if (IS_ERR(pctl->pctldev)) -+ return PTR_ERR(pctl->pctldev); -+ -+ return 0; -+} -+ -+static const struct of_device_id bcm6328_pinctrl_match[] = { -+ { .compatible = "brcm,bcm6328-pinctrl", }, -+ { }, -+}; -+ -+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/target/linux/bmips/patches-5.10/403-Documentation-add-BCM6358-pincontroller-binding-docu.patch b/target/linux/bmips/patches-5.10/403-Documentation-add-BCM6358-pincontroller-binding-docu.patch deleted file mode 100644 index e8a7479915..0000000000 --- a/target/linux/bmips/patches-5.10/403-Documentation-add-BCM6358-pincontroller-binding-docu.patch +++ /dev/null @@ -1,61 +0,0 @@ -From c7c8fa7f5b5ee9bea751fa7bdae8ff4acde8f26e Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Wed, 27 Jul 2016 11:36:00 +0200 -Subject: [PATCH 06/16] Documentation: add BCM6358 pincontroller binding - documentation - -Add binding documentation for the pincontrol core found in BCM6358 SoCs. - -Signed-off-by: Jonas Gorski ---- - .../bindings/pinctrl/brcm,bcm6358-pinctrl.txt | 44 ++++++++++++++++++++++ - 1 file changed, 44 insertions(+) - create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.txt - ---- /dev/null -+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.txt -@@ -0,0 +1,44 @@ -+* Broadcom BCM6358 pin controller -+ -+Required properties: -+- compatible: Must be "brcm,bcm6358-pinctrl". -+- reg: Register specifiers of dirout, dat registers. -+- reg-names: Must be "dirout", "dat". -+- brcm,gpiomode: Phandle to the shared gpiomode register. -+- gpio-controller: Identifies this node as a gpio-controller. -+- #gpio-cells: Must be <2>. -+ -+Example: -+ -+pinctrl: pin-controller@fffe0080 { -+ compatible = "brcm,bcm6358-pinctrl"; -+ reg = <0xfffe0080 0x8>, -+ <0xfffe0088 0x8>, -+ <0xfffe0098 0x4>; -+ reg-names = "dirout", "dat"; -+ brcm,gpiomode = <&gpiomode>; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+}; -+ -+gpiomode: syscon@fffe0098 { -+ compatible = "brcm,bcm6358-gpiomode", "syscon"; -+ reg = <0xfffe0098 0x4>; -+ native-endian; -+}; -+ -+Available pins/groups and functions: -+ -+name pins functions -+----------------------------------------------------------- -+ebi_cs_grp 30-31 ebi_cs -+uart1_grp 28-31 uart1 -+spi_cs_grp 32-33 spi_cs -+async_modem_grp 12-15 async_modem -+legacy_led_grp 9-15 legacy_led -+serial_led_grp 6-7 serial_led -+led_grp 0-3 led -+utopia_grp 12-15, 22-31 utopia -+pwm_syn_clk_grp 8 pwm_syn_clk -+sys_irq_grp 5 sys_irq diff --git a/target/linux/bmips/patches-5.10/403-pinctrl-add-a-pincontrol-driver-for-BCM6358.patch b/target/linux/bmips/patches-5.10/403-pinctrl-add-a-pincontrol-driver-for-BCM6358.patch new file mode 100644 index 0000000000..fb8681d904 --- /dev/null +++ b/target/linux/bmips/patches-5.10/403-pinctrl-add-a-pincontrol-driver-for-BCM6358.patch @@ -0,0 +1,582 @@ +From b0e1ebc79a6d7f84f71a758f5a504c8cf954e2e0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= +Date: Fri, 24 Jun 2016 22:16:01 +0200 +Subject: [PATCH 04/12] pinctrl: add a pincontrol driver for BCM6358 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add a pincotrol driver for BCM6358. BCM6358 allow overlaying different +functions onto the GPIO pins. It does not support configuring individual +pins but only whole groups. These groups may overlap, and still require +the directions to be set correctly in the GPIO register. In addition the +functions register controls other, not directly mux related functions. + +Signed-off-by: Álvaro Fernández Rojas +Signed-off-by: Jonas Gorski +--- + drivers/pinctrl/bcm/Kconfig | 11 + + drivers/pinctrl/bcm/Makefile | 1 + + drivers/pinctrl/bcm/pinctrl-bcm6358.c | 526 ++++++++++++++++++++++++++ + 3 files changed, 538 insertions(+) + create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6358.c + +--- a/drivers/pinctrl/bcm/Kconfig ++++ b/drivers/pinctrl/bcm/Kconfig +@@ -40,6 +40,17 @@ config PINCTRL_BCM6328 + help + Say Y here to enable the Broadcom BCM6328 GPIO driver. + ++config PINCTRL_BCM6358 ++ bool "Broadcom BCM6358 GPIO driver" ++ depends on OF_GPIO && (BMIPS_GENERIC || COMPILE_TEST) ++ select PINMUX ++ select PINCONF ++ select GENERIC_PINCONF ++ select MFD_SYSCON ++ default BMIPS_GENERIC ++ help ++ Say Y here to enable the Broadcom BCM6358 GPIO driver. ++ + config PINCTRL_IPROC_GPIO + bool "Broadcom iProc GPIO (with PINCONF) driver" + depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST) +--- a/drivers/pinctrl/bcm/Makefile ++++ b/drivers/pinctrl/bcm/Makefile +@@ -4,6 +4,7 @@ + obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o + obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o + obj-$(CONFIG_PINCTRL_BCM6328) += pinctrl-bcm6328.o ++obj-$(CONFIG_PINCTRL_BCM6358) += pinctrl-bcm6358.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 +--- /dev/null ++++ b/drivers/pinctrl/bcm/pinctrl-bcm6358.c +@@ -0,0 +1,526 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Driver for BCM6358 GPIO unit (pinctrl + GPIO) ++ * ++ * Copyright (C) 2021 Álvaro Fernández Rojas ++ * Copyright (C) 2016 Jonas Gorski ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include "../core.h" ++#include "../pinctrl-utils.h" ++ ++#define MODULE_NAME "bcm6358-pinctrl" ++#define BCM6358_NUM_GPIOS 40 ++ ++#define BANK_SIZE sizeof(uint32_t) ++#define PINS_PER_BANK (BANK_SIZE * BITS_PER_BYTE) ++ ++#define BCM6358_DIROUT_REG 0x04 ++#define BCM6358_DATA_REG 0x0c ++#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_pinctrl { ++ struct device *dev; ++ struct regmap *regs; ++ struct regmap_field *overlays; ++ ++ struct pinctrl_dev *pctl_dev; ++ struct gpio_chip gpio_chip; ++ struct pinctrl_desc pctl_desc; ++ struct pinctrl_gpio_range gpio_range; ++}; ++ ++#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 inline unsigned int bcm6358_bank_pin(unsigned int pin) ++{ ++ return pin % PINS_PER_BANK; ++} ++ ++static inline unsigned int bcm6358_reg_off(unsigned int reg, unsigned int pin) ++{ ++ return reg - (pin / PINS_PER_BANK) * BANK_SIZE; ++} ++ ++static int bcm6358_gpio_direction_input(struct gpio_chip *chip, ++ unsigned int pin) ++{ ++ struct bcm6358_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int dirout = bcm6358_reg_off(BCM6358_DIROUT_REG, pin); ++ unsigned int bank_pin = bcm6358_bank_pin(pin); ++ int ret; ++ ++ /* ++ * Check with the pinctrl driver whether this pin is usable as ++ * an input GPIO ++ */ ++ ret = pinctrl_gpio_direction_input(chip->base + pin); ++ if (ret) ++ return ret; ++ ++ regmap_update_bits(pc->regs, dirout, BIT(bank_pin), 0); ++ ++ return 0; ++} ++ ++static int bcm6358_gpio_direction_output(struct gpio_chip *chip, ++ unsigned int pin, int value) ++{ ++ struct bcm6358_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int data = bcm6358_reg_off(BCM6358_DATA_REG, pin); ++ unsigned int dirout = bcm6358_reg_off(BCM6358_DIROUT_REG, pin); ++ unsigned int bank_pin = bcm6358_bank_pin(pin); ++ unsigned int val = value ? BIT(bank_pin) : 0; ++ int ret; ++ ++ /* ++ * Check with the pinctrl driver whether this pin is usable as ++ * an output GPIO ++ */ ++ ret = pinctrl_gpio_direction_output(chip->base + pin); ++ if (ret) ++ return ret; ++ ++ regmap_update_bits(pc->regs, dirout, BIT(bank_pin), BIT(bank_pin)); ++ regmap_update_bits(pc->regs, data, BIT(bank_pin), val); ++ ++ return 0; ++} ++ ++static int bcm6358_gpio_get(struct gpio_chip *chip, unsigned int pin) ++{ ++ struct bcm6358_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int data = bcm6358_reg_off(BCM6358_DATA_REG, pin); ++ unsigned int bank_pin = bcm6358_bank_pin(pin); ++ unsigned int val; ++ ++ regmap_read(pc->regs, data, &val); ++ ++ return !!(val & BIT(bank_pin)); ++} ++ ++static int bcm6358_gpio_get_direction(struct gpio_chip *chip, unsigned int pin) ++{ ++ struct bcm6358_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int dirout = bcm6358_reg_off(BCM6358_DIROUT_REG, pin); ++ unsigned int bank_pin = bcm6358_bank_pin(pin); ++ unsigned int val; ++ ++ regmap_read(pc->regs, dirout, &val); ++ ++ if (val & BIT(bank_pin)) ++ return GPIO_LINE_DIRECTION_OUT; ++ ++ return GPIO_LINE_DIRECTION_IN; ++} ++ ++static void bcm6358_gpio_set(struct gpio_chip *chip, unsigned int pin, ++ int value) ++{ ++ struct bcm6358_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int data = bcm6358_reg_off(BCM6358_DATA_REG, pin); ++ unsigned int bank_pin = bcm6358_bank_pin(pin); ++ unsigned int val = value ? BIT(bank_pin) : 0; ++ ++ regmap_update_bits(pc->regs, data, BIT(bank_pin), val); ++} ++ ++static int bcm6358_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) ++{ ++ char irq_name[7]; ++ ++ sprintf(irq_name, "gpio%d", gpio); ++ ++ return of_irq_get_byname(chip->of_node, irq_name); ++} ++ ++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 bcm6358_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); ++ 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(pc->overlays, mask, val); ++ ++ for (pin = 0; pin < pg->num_pins; pin++) { ++ int hw_gpio = bcm6358_pins[pin].number; ++ struct gpio_chip *gc = &pc->gpio_chip; ++ ++ 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 bcm6358_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); ++ 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(pc->overlays, mask, 0); ++} ++ ++static struct pinctrl_ops bcm6358_pctl_ops = { ++ .get_groups_count = bcm6358_pinctrl_get_group_count, ++ .get_group_name = bcm6358_pinctrl_get_group_name, ++ .get_group_pins = bcm6358_pinctrl_get_group_pins, ++ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, ++ .dt_free_map = pinctrl_utils_free_map, ++}; ++ ++static struct pinmux_ops bcm6358_pmx_ops = { ++ .get_functions_count = bcm6358_pinctrl_get_func_count, ++ .get_function_name = bcm6358_pinctrl_get_func_name, ++ .get_function_groups = bcm6358_pinctrl_get_groups, ++ .set_mux = bcm6358_pinctrl_set_mux, ++ .gpio_request_enable = bcm6358_gpio_request_enable, ++ .strict = true, ++}; ++ ++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 device_node *np = dev->of_node; ++ struct bcm6358_pinctrl *pc; ++ int err; ++ ++ pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); ++ if (!pc) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, pc); ++ pc->dev = dev; ++ ++ pc->regs = syscon_node_to_regmap(dev->parent->of_node); ++ if (IS_ERR(pc->regs)) ++ return PTR_ERR(pc->regs); ++ ++ pc->overlays = devm_regmap_field_alloc(&pdev->dev, pc->regs, overlays); ++ if (IS_ERR(pc->overlays)) ++ return PTR_ERR(pc->overlays); ++ ++ /* disable all muxes by default */ ++ regmap_field_write(pc->overlays, 0); ++ ++ pc->gpio_chip.label = MODULE_NAME; ++ pc->gpio_chip.owner = THIS_MODULE; ++ pc->gpio_chip.request = gpiochip_generic_request; ++ pc->gpio_chip.free = gpiochip_generic_free; ++ pc->gpio_chip.direction_input = bcm6358_gpio_direction_input; ++ pc->gpio_chip.direction_output = bcm6358_gpio_direction_output; ++ pc->gpio_chip.get_direction = bcm6358_gpio_get_direction; ++ pc->gpio_chip.get = bcm6358_gpio_get; ++ pc->gpio_chip.set = bcm6358_gpio_set; ++ pc->gpio_chip.set_config = gpiochip_generic_config; ++ pc->gpio_chip.base = -1; ++ pc->gpio_chip.ngpio = BCM6358_NUM_GPIOS; ++ pc->gpio_chip.can_sleep = false; ++ pc->gpio_chip.parent = dev; ++ pc->gpio_chip.of_node = np; ++ ++ if (of_get_property(np, "interrupt-names", NULL)) ++ pc->gpio_chip.to_irq = bcm6358_gpio_to_irq; ++ ++ err = gpiochip_add_data(&pc->gpio_chip, pc); ++ if (err) { ++ dev_err(dev, "could not add GPIO chip\n"); ++ return err; ++ } ++ ++ pc->pctl_desc.name = MODULE_NAME, ++ pc->pctl_desc.pins = bcm6358_pins, ++ pc->pctl_desc.npins = ARRAY_SIZE(bcm6358_pins), ++ pc->pctl_desc.pctlops = &bcm6358_pctl_ops, ++ pc->pctl_desc.pmxops = &bcm6358_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)) { ++ gpiochip_remove(&pc->gpio_chip); ++ return PTR_ERR(pc->pctl_dev); ++ } ++ ++ pc->gpio_range.name = MODULE_NAME; ++ pc->gpio_range.npins = BCM6358_NUM_GPIOS; ++ pc->gpio_range.base = pc->gpio_chip.base; ++ pc->gpio_range.gc = &pc->gpio_chip; ++ pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range); ++ ++ dev_info(dev, "registered\n"); ++ ++ return 0; ++} ++ ++static const struct of_device_id bcm6358_pinctrl_match[] = { ++ { .compatible = "brcm,bcm6358-pinctrl", }, ++ { }, ++}; ++ ++static struct platform_driver bcm6358_pinctrl_driver = { ++ .probe = bcm6358_pinctrl_probe, ++ .driver = { ++ .name = MODULE_NAME, ++ .of_match_table = bcm6358_pinctrl_match, ++ }, ++}; ++ ++builtin_platform_driver(bcm6358_pinctrl_driver); diff --git a/target/linux/bmips/patches-5.10/404-Documentation-add-BCM6362-pincontroller-binding-docu.patch b/target/linux/bmips/patches-5.10/404-Documentation-add-BCM6362-pincontroller-binding-docu.patch new file mode 100644 index 0000000000..18739091aa --- /dev/null +++ b/target/linux/bmips/patches-5.10/404-Documentation-add-BCM6362-pincontroller-binding-docu.patch @@ -0,0 +1,261 @@ +From 1c839f287a008023b3b3ae7d892b4d25e3d224ad Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= +Date: Wed, 27 Jul 2016 11:36:18 +0200 +Subject: [PATCH 05/12] Documentation: add BCM6362 pincontroller binding + documentation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add binding documentation for the pincontrol core found in BCM6362 SoCs. + +Signed-off-by: Álvaro Fernández Rojas +Signed-off-by: Jonas Gorski +--- + .../pinctrl/brcm,bcm6362-pinctrl.yaml | 240 ++++++++++++++++++ + 1 file changed, 240 insertions(+) + create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml + +--- /dev/null ++++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml +@@ -0,0 +1,240 @@ ++# 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 ++ - Jonas Gorski ++ ++description: |+ ++ The pin controller node should be the child of a syscon node. ++ ++ Refer to the the bindings described in ++ Documentation/devicetree/bindings/mfd/syscon.yaml ++ ++properties: ++ compatible: ++ const: brcm,bcm6362-pinctrl ++ ++ gpio-controller: true ++ ++ '#gpio-cells': ++ description: ++ Specifies the pin number and flags, as defined in ++ include/dt-bindings/gpio/gpio.h ++ const: 2 ++ ++ interrupts-extended: ++ description: ++ One interrupt per each of the 4 GPIO ports supported by the controller, ++ sorted by port number ascending order. ++ minItems: 4 ++ maxItems: 4 ++ ++patternProperties: ++ '^.*$': ++ if: ++ type: object ++ then: ++ properties: ++ function: ++ $ref: "/schemas/types.yaml#/definitions/string" ++ 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: ++ $ref: "/schemas/types.yaml#/definitions/string" ++ 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 ++ - gpio-controller ++ - '#gpio-cells' ++ ++additionalProperties: false ++ ++examples: ++ - | ++ gpio@10000080 { ++ compatible = "syscon", "simple-mfd"; ++ reg = <0x10000080 0x80>; ++ ++ pinctrl: pinctrl { ++ compatible = "brcm,bcm6362-pinctrl"; ++ ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ interrupts-extended = <&ext_intc 0 0>, ++ <&ext_intc 1 0>, ++ <&ext_intc 2 0>, ++ <&ext_intc 3 0>; ++ interrupt-names = "gpio24", ++ "gpio25", ++ "gpio26", ++ "gpio27"; ++ ++ pinctrl_usb_device_led: usb_device_led { ++ function = "usb_device_led"; ++ pins = "gpio0"; ++ }; ++ ++ pinctrl_sys_irq: sys_irq { ++ function = "sys_irq"; ++ pins = "gpio1"; ++ }; ++ ++ pinctrl_serial_led: serial_led { ++ pinctrl_serial_led_clk: serial_led_clk { ++ function = "serial_led_clk"; ++ pins = "gpio2"; ++ }; ++ ++ pinctrl_serial_led_data: serial_led_data { ++ function = "serial_led_data"; ++ pins = "gpio3"; ++ }; ++ }; ++ ++ pinctrl_robosw_led_data: robosw_led_data { ++ function = "robosw_led_data"; ++ pins = "gpio4"; ++ }; ++ ++ pinctrl_robosw_led_clk: robosw_led_clk { ++ function = "robosw_led_clk"; ++ pins = "gpio5"; ++ }; ++ ++ pinctrl_robosw_led0: robosw_led0 { ++ function = "robosw_led0"; ++ pins = "gpio6"; ++ }; ++ ++ pinctrl_robosw_led1: robosw_led1 { ++ function = "robosw_led1"; ++ pins = "gpio7"; ++ }; ++ ++ pinctrl_inet_led: inet_led { ++ function = "inet_led"; ++ pins = "gpio8"; ++ }; ++ ++ pinctrl_spi_cs2: spi_cs2 { ++ function = "spi_cs2"; ++ pins = "gpio9"; ++ }; ++ ++ pinctrl_spi_cs3: spi_cs3 { ++ function = "spi_cs3"; ++ pins = "gpio10"; ++ }; ++ ++ pinctrl_ntr_pulse: ntr_pulse { ++ function = "ntr_pulse"; ++ pins = "gpio11"; ++ }; ++ ++ pinctrl_uart1_scts: uart1_scts { ++ function = "uart1_scts"; ++ pins = "gpio12"; ++ }; ++ ++ pinctrl_uart1_srts: uart1_srts { ++ function = "uart1_srts"; ++ pins = "gpio13"; ++ }; ++ ++ pinctrl_uart1: uart1 { ++ pinctrl_uart1_sdin: uart1_sdin { ++ function = "uart1_sdin"; ++ pins = "gpio14"; ++ }; ++ ++ pinctrl_uart1_sdout: uart1_sdout { ++ function = "uart1_sdout"; ++ pins = "gpio15"; ++ }; ++ }; ++ ++ pinctrl_adsl_spi: adsl_spi { ++ pinctrl_adsl_spi_miso: adsl_spi_miso { ++ function = "adsl_spi_miso"; ++ pins = "gpio16"; ++ }; ++ ++ pinctrl_adsl_spi_mosi: adsl_spi_mosi { ++ function = "adsl_spi_mosi"; ++ pins = "gpio17"; ++ }; ++ ++ pinctrl_adsl_spi_clk: adsl_spi_clk { ++ function = "adsl_spi_clk"; ++ pins = "gpio18"; ++ }; ++ ++ pinctrl_adsl_spi_cs: adsl_spi_cs { ++ function = "adsl_spi_cs"; ++ pins = "gpio19"; ++ }; ++ }; ++ ++ pinctrl_ephy0_led: ephy0_led { ++ function = "ephy0_led"; ++ pins = "gpio20"; ++ }; ++ ++ pinctrl_ephy1_led: ephy1_led { ++ function = "ephy1_led"; ++ pins = "gpio21"; ++ }; ++ ++ pinctrl_ephy2_led: ephy2_led { ++ function = "ephy2_led"; ++ pins = "gpio22"; ++ }; ++ ++ pinctrl_ephy3_led: ephy3_led { ++ function = "ephy3_led"; ++ pins = "gpio23"; ++ }; ++ ++ pinctrl_ext_irq0: ext_irq0 { ++ function = "ext_irq0"; ++ pins = "gpio24"; ++ }; ++ ++ pinctrl_ext_irq1: ext_irq1 { ++ function = "ext_irq1"; ++ pins = "gpio25"; ++ }; ++ ++ pinctrl_ext_irq2: ext_irq2 { ++ function = "ext_irq2"; ++ pins = "gpio26"; ++ }; ++ ++ pinctrl_ext_irq3: ext_irq3 { ++ function = "ext_irq3"; ++ pins = "gpio27"; ++ }; ++ ++ pinctrl_nand: nand { ++ function = "nand"; ++ group = "nand_grp"; ++ }; ++ }; ++ }; diff --git a/target/linux/bmips/patches-5.10/404-pinctrl-add-a-pincontrol-driver-for-BCM6358.patch b/target/linux/bmips/patches-5.10/404-pinctrl-add-a-pincontrol-driver-for-BCM6358.patch deleted file mode 100644 index d102bda802..0000000000 --- a/target/linux/bmips/patches-5.10/404-pinctrl-add-a-pincontrol-driver-for-BCM6358.patch +++ /dev/null @@ -1,432 +0,0 @@ -From fb00ef462f3f8b70ea8902151cc72810fe90b999 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Fri, 24 Jun 2016 22:16:01 +0200 -Subject: [PATCH 07/16] pinctrl: add a pincontrol driver for BCM6358 - -Add a pincotrol driver for BCM6358. BCM6358 allow overlaying different -functions onto the GPIO pins. It does not support configuring individual -pins but only whole groups. These groups may overlap, and still require -the directions to be set correctly in the GPIO register. In addition the -functions register controls other, not directly mux related functions. - -Signed-off-by: Jonas Gorski ---- - drivers/pinctrl/bcm63xx/Kconfig | 8 + - drivers/pinctrl/bcm63xx/Makefile | 1 + - drivers/pinctrl/bcm63xx/pinctrl-bcm6358.c | 393 ++++++++++++++++++++++++++++++ - 3 files changed, 402 insertions(+) - create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6358.c - ---- a/drivers/pinctrl/bcm63xx/Kconfig -+++ b/drivers/pinctrl/bcm63xx/Kconfig -@@ -8,3 +8,11 @@ config PINCTRL_BCM6328 - select PINCONF - select PINCTRL_BCM63XX - select GENERIC_PINCONF -+ -+config PINCTRL_BCM6358 -+ bool "BCM6358 pincontrol driver" -+ select PINMUX -+ select PINCONF -+ select PINCTRL_BCM63XX -+ select GENERIC_PINCONF -+ select MFD_SYSCON ---- a/drivers/pinctrl/bcm63xx/Makefile -+++ b/drivers/pinctrl/bcm63xx/Makefile -@@ -1,2 +1,3 @@ - obj-$(CONFIG_PINCTRL_BCM63XX) += pinctrl-bcm63xx.o - obj-$(CONFIG_PINCTRL_BCM6328) += pinctrl-bcm6328.o -+obj-$(CONFIG_PINCTRL_BCM6358) += pinctrl-bcm6358.o ---- /dev/null -+++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm6358.c -@@ -0,0 +1,390 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2016 Jonas Gorski -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "../core.h" -+#include "../pinctrl-utils.h" -+ -+#include "pinctrl-bcm63xx.h" -+ -+/* GPIO_MODE register */ -+#define BCM6358_MODE_MUX_NONE 0 -+ -+/* overlays on gpio pins */ -+#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) -+ -+#define BCM6358_NGPIO 40 -+ -+struct bcm6358_pingroup { -+ const char *name; -+ const unsigned * const pins; -+ const unsigned num_pins; -+ -+ const u16 mode_val; -+ -+ /* non-GPIO function muxes require the gpio direction to be set */ -+ const u16 direction; -+}; -+ -+struct bcm6358_function { -+ const char *name; -+ const char * const *groups; -+ const unsigned num_groups; -+}; -+ -+struct bcm6358_pinctrl { -+ struct device *dev; -+ struct pinctrl_dev *pctldev; -+ struct pinctrl_desc desc; -+ -+ struct regmap_field *overlays; -+ -+ struct gpio_chip gpio[2]; -+}; -+ -+#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 bcm6358_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); -+ const struct bcm6358_pingroup *grp = &bcm6358_groups[group]; -+ u32 val = grp->mode_val; -+ u32 mask = val; -+ unsigned pin; -+ -+ for (pin = 0; pin < grp->num_pins; pin++) -+ mask |= (unsigned long)bcm6358_pins[pin].drv_data; -+ -+ regmap_field_update_bits(pctl->overlays, mask, val); -+ -+ for (pin = 0; pin < grp->num_pins; pin++) { -+ int hw_gpio = bcm6358_pins[pin].number; -+ struct gpio_chip *gc = &pctl->gpio[hw_gpio / 32]; -+ -+ if (grp->direction & BIT(pin)) -+ gc->direction_output(gc, hw_gpio % 32, 0); -+ else -+ gc->direction_input(gc, hw_gpio % 32); -+ } -+ -+ return 0; -+} -+ -+static int bcm6358_gpio_request_enable(struct pinctrl_dev *pctldev, -+ struct pinctrl_gpio_range *range, -+ unsigned offset) -+{ -+ struct bcm6358_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); -+ u32 mask; -+ -+ mask = (unsigned long)bcm6358_pins[offset].drv_data; -+ if (!mask) -+ return 0; -+ -+ /* disable all functions using this pin */ -+ return regmap_field_update_bits(pctl->overlays, mask, 0); -+} -+ -+static struct pinctrl_ops bcm6358_pctl_ops = { -+ .get_groups_count = bcm6358_pinctrl_get_group_count, -+ .get_group_name = bcm6358_pinctrl_get_group_name, -+ .get_group_pins = bcm6358_pinctrl_get_group_pins, -+#ifdef CONFIG_OF -+ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, -+ .dt_free_map = pinctrl_utils_free_map, -+#endif -+}; -+ -+static struct pinmux_ops bcm6358_pmx_ops = { -+ .get_functions_count = bcm6358_pinctrl_get_func_count, -+ .get_function_name = bcm6358_pinctrl_get_func_name, -+ .get_function_groups = bcm6358_pinctrl_get_groups, -+ .set_mux = bcm6358_pinctrl_set_mux, -+ .gpio_request_enable = bcm6358_gpio_request_enable, -+ .strict = true, -+}; -+ -+static int bcm6358_pinctrl_probe(struct platform_device *pdev) -+{ -+ struct bcm6358_pinctrl *pctl; -+ struct regmap *mode; -+ struct reg_field overlays = REG_FIELD(0, 0, 15); -+ -+ mode = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, -+ "brcm,gpiomode"); -+ -+ if (IS_ERR(mode)) -+ return PTR_ERR(mode); -+ -+ pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL); -+ if (!pctl) -+ return -ENOMEM; -+ -+ pctl->overlays = devm_regmap_field_alloc(&pdev->dev, mode, overlays); -+ if (IS_ERR(pctl->overlays)) -+ return PTR_ERR(pctl->overlays); -+ -+ /* disable all muxes by default */ -+ regmap_field_write(pctl->overlays, 0); -+ -+ pctl->desc.name = dev_name(&pdev->dev); -+ pctl->desc.owner = THIS_MODULE; -+ pctl->desc.pctlops = &bcm6358_pctl_ops; -+ pctl->desc.pmxops = &bcm6358_pmx_ops; -+ -+ pctl->desc.npins = ARRAY_SIZE(bcm6358_pins); -+ pctl->desc.pins = bcm6358_pins; -+ -+ platform_set_drvdata(pdev, pctl); -+ -+ pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl, -+ pctl->gpio, BCM6358_NGPIO); -+ if (IS_ERR(pctl->pctldev)) -+ return PTR_ERR(pctl->pctldev); -+ -+ return 0; -+} -+ -+static const struct of_device_id bcm6358_pinctrl_match[] = { -+ { .compatible = "brcm,bcm6358-pinctrl", }, -+ { }, -+}; -+ -+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/target/linux/bmips/patches-5.10/405-Documentation-add-BCM6362-pincontroller-binding-docu.patch b/target/linux/bmips/patches-5.10/405-Documentation-add-BCM6362-pincontroller-binding-docu.patch deleted file mode 100644 index 9fc424cb4c..0000000000 --- a/target/linux/bmips/patches-5.10/405-Documentation-add-BCM6362-pincontroller-binding-docu.patch +++ /dev/null @@ -1,96 +0,0 @@ -From ba03ea8ada2ca71c9095d96a1e4085c2c5cf0e69 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Wed, 27 Jul 2016 11:36:18 +0200 -Subject: [PATCH 08/16] Documentation: add BCM6362 pincontroller binding - documentation - -Add binding documentation for the pincontrol core found in BCM6362 SoCs. - -Signed-off-by: Jonas Gorski ---- - .../bindings/pinctrl/brcm,bcm6362-pinctrl.txt | 79 ++++++++++++++++++++++ - 1 file changed, 79 insertions(+) - create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.txt - ---- /dev/null -+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.txt -@@ -0,0 +1,79 @@ -+* Broadcom BCM6362 pin controller -+ -+Required properties: -+- compatible: Must be "brcm,bcm6362-pinctrl" -+- reg: Register specifiers of dirout, dat, led, mode, ctrl, basemode registers. -+- reg-names: Must be "dirout", "dat", "led", "mode", "ctrl", "basemode". -+- gpio-controller: Identifies this node as a GPIO controller. -+- #gpio-cells: Must be <2>. -+ -+Example: -+ -+pinctrl: pin-controller@10000080 { -+ compatible = "brcm,bcm6362-pinctrl"; -+ reg = <0x10000080 0x8>, -+ <0x10000088 0x8>, -+ <0x10000090 0x4>, -+ <0x10000098 0x4>, -+ <0x1000009c 0x4>, -+ <0x100000b8 0x4>; -+ reg-names = "dirout", "dat", "led", -+ "mode", "ctrl", "basemode"; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+}; -+ -+Available pins/groups and functions: -+ -+name pins functions -+----------------------------------------------------------- -+gpio0 0 led, usb_device_led -+gpio1 1 led, sys_irq -+gpio2 2 led, serial_led_clk -+gpio3 3 led, serial_led_data -+gpio4 4 led, robosw_led_data -+gpio5 5 led, robosw_led_clk -+gpio6 6 led, robosw_led0 -+gpio7 7 led, robosw_led1 -+gpio8 8 led, inet_led -+gpio9 9 led, spi_cs2 -+gpio10 10 led, spi_cs3 -+gpio11 11 led, ntr_pulse -+gpio12 12 led, uart1_scts -+gpio13 13 led, uart1_srts -+gpio14 14 led, uart1_sdin -+gpio15 15 led, uart1_sdout -+gpio16 16 led, adsl_spi_miso -+gpio17 17 led, adsl_spi_mosi -+gpio18 18 led, adsl_spi_clk -+gpio19 19 led, adsl_spi_cs -+gpio20 20 led, ephy0_led -+gpio21 21 led, ephy1_led -+gpio22 22 led, ephy2_led -+gpio23 23 led, ephy3_led -+gpio24 24 ext_irq0 -+gpio25 25 ext_irq1 -+gpio26 26 ext_irq2 -+gpio27 27 ext_irq3 -+gpio28 28 - -+gpio29 29 - -+gpio30 30 - -+gpio31 31 - -+gpio32 32 wifi -+gpio33 33 wifi -+gpio34 34 wifi -+gpio35 35 wifi -+gpio36 36 wifi -+gpio37 37 wifi -+gpio38 38 wifi -+gpio39 39 wifi -+gpio40 40 wifi -+gpio41 41 wifi -+gpio42 42 wifi -+gpio43 43 wifi -+gpio44 44 wifi -+gpio45 45 wifi -+gpio46 46 wifi -+gpio47 47 wifi -+nand_grp 8, 12-23, 27 nand diff --git a/target/linux/bmips/patches-5.10/405-pinctrl-add-a-pincontrol-driver-for-BCM6362.patch b/target/linux/bmips/patches-5.10/405-pinctrl-add-a-pincontrol-driver-for-BCM6362.patch new file mode 100644 index 0000000000..bfc6620ace --- /dev/null +++ b/target/linux/bmips/patches-5.10/405-pinctrl-add-a-pincontrol-driver-for-BCM6362.patch @@ -0,0 +1,849 @@ +From 2872fcb5eac02d3a74d696e6350410a9e66281b4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= +Date: Fri, 24 Jun 2016 22:17:20 +0200 +Subject: [PATCH 06/12] pinctrl: add a pincontrol driver for BCM6362 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add a pincotrol driver for BCM6362. BCM6362 allows muxing individual +GPIO pins to the LED controller, to be available by the integrated +wifi, or other functions. It also supports overlay groups, of which +only NAND is documented. + +Signed-off-by: Álvaro Fernández Rojas +Signed-off-by: Jonas Gorski +--- + drivers/pinctrl/bcm/Kconfig | 11 + + drivers/pinctrl/bcm/Makefile | 1 + + drivers/pinctrl/bcm/pinctrl-bcm6362.c | 794 ++++++++++++++++++++++++++ + 3 files changed, 806 insertions(+) + create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6362.c + +--- a/drivers/pinctrl/bcm/Kconfig ++++ b/drivers/pinctrl/bcm/Kconfig +@@ -51,6 +51,17 @@ config PINCTRL_BCM6358 + help + Say Y here to enable the Broadcom BCM6358 GPIO driver. + ++config PINCTRL_BCM6362 ++ bool "Broadcom BCM6362 GPIO driver" ++ depends on OF_GPIO && (BMIPS_GENERIC || COMPILE_TEST) ++ select PINMUX ++ select PINCONF ++ select GENERIC_PINCONF ++ select MFD_SYSCON ++ default BMIPS_GENERIC ++ help ++ Say Y here to enable the Broadcom BCM6362 GPIO driver. ++ + config PINCTRL_IPROC_GPIO + bool "Broadcom iProc GPIO (with PINCONF) driver" + depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST) +--- a/drivers/pinctrl/bcm/Makefile ++++ b/drivers/pinctrl/bcm/Makefile +@@ -5,6 +5,7 @@ obj-$(CONFIG_PINCTRL_BCM281XX) += pinct + obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.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_IPROC_GPIO) += pinctrl-iproc-gpio.o + obj-$(CONFIG_PINCTRL_CYGNUS_MUX) += pinctrl-cygnus-mux.o + obj-$(CONFIG_PINCTRL_NS) += pinctrl-ns.o +--- /dev/null ++++ b/drivers/pinctrl/bcm/pinctrl-bcm6362.c +@@ -0,0 +1,794 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Driver for BCM6362 GPIO unit (pinctrl + GPIO) ++ * ++ * Copyright (C) 2021 Álvaro Fernández Rojas ++ * Copyright (C) 2016 Jonas Gorski ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include "../core.h" ++#include "../pinctrl-utils.h" ++ ++#define MODULE_NAME "bcm6362-pinctrl" ++#define BCM6362_NUM_GPIOS 48 ++#define BCM6362_NUM_LEDS 24 ++ ++#define BANK_SIZE sizeof(uint32_t) ++#define PINS_PER_BANK (BANK_SIZE * BITS_PER_BYTE) ++ ++#define BCM6362_DIROUT_REG 0x04 ++#define BCM6362_DATA_REG 0x0c ++#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; ++}; ++ ++struct bcm6362_pinctrl { ++ struct device *dev; ++ struct regmap *regs; ++ ++ struct pinctrl_dev *pctl_dev; ++ struct gpio_chip gpio_chip; ++ struct pinctrl_desc pctl_desc; ++ struct pinctrl_gpio_range gpio_range; ++}; ++ ++#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 inline unsigned int bcm6362_bank_pin(unsigned int pin) ++{ ++ return pin % PINS_PER_BANK; ++} ++ ++static inline unsigned int bcm6362_reg_off(unsigned int reg, unsigned int pin) ++{ ++ return reg - (pin / PINS_PER_BANK) * BANK_SIZE; ++} ++ ++static int bcm6362_gpio_direction_input(struct gpio_chip *chip, ++ unsigned int pin) ++{ ++ struct bcm6362_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int dirout = bcm6362_reg_off(BCM6362_DIROUT_REG, pin); ++ unsigned int bank_pin = bcm6362_bank_pin(pin); ++ int ret; ++ ++ /* ++ * Check with the pinctrl driver whether this pin is usable as ++ * an input GPIO ++ */ ++ ret = pinctrl_gpio_direction_input(chip->base + pin); ++ if (ret) ++ return ret; ++ ++ regmap_update_bits(pc->regs, dirout, BIT(bank_pin), 0); ++ ++ return 0; ++} ++ ++static int bcm6362_gpio_direction_output(struct gpio_chip *chip, ++ unsigned int pin, int value) ++{ ++ struct bcm6362_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int data = bcm6362_reg_off(BCM6362_DATA_REG, pin); ++ unsigned int dirout = bcm6362_reg_off(BCM6362_DIROUT_REG, pin); ++ unsigned int bank_pin = bcm6362_bank_pin(pin); ++ unsigned int val = value ? BIT(bank_pin) : 0; ++ int ret; ++ ++ /* ++ * Check with the pinctrl driver whether this pin is usable as ++ * an output GPIO ++ */ ++ ret = pinctrl_gpio_direction_output(chip->base + pin); ++ if (ret) ++ return ret; ++ ++ regmap_update_bits(pc->regs, dirout, BIT(bank_pin), BIT(bank_pin)); ++ regmap_update_bits(pc->regs, data, BIT(bank_pin), val); ++ ++ return 0; ++} ++ ++static int bcm6362_gpio_get(struct gpio_chip *chip, unsigned int pin) ++{ ++ struct bcm6362_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int data = bcm6362_reg_off(BCM6362_DATA_REG, pin); ++ unsigned int bank_pin = bcm6362_bank_pin(pin); ++ unsigned int val; ++ ++ regmap_read(pc->regs, data, &val); ++ ++ return !!(val & BIT(bank_pin)); ++} ++ ++static int bcm6362_gpio_get_direction(struct gpio_chip *chip, unsigned int pin) ++{ ++ struct bcm6362_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int dirout = bcm6362_reg_off(BCM6362_DIROUT_REG, pin); ++ unsigned int bank_pin = bcm6362_bank_pin(pin); ++ unsigned int val; ++ ++ regmap_read(pc->regs, dirout, &val); ++ ++ if (val & BIT(bank_pin)) ++ return GPIO_LINE_DIRECTION_OUT; ++ ++ return GPIO_LINE_DIRECTION_IN; ++} ++ ++static void bcm6362_gpio_set(struct gpio_chip *chip, unsigned int pin, ++ int value) ++{ ++ struct bcm6362_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int data = bcm6362_reg_off(BCM6362_DATA_REG, pin); ++ unsigned int bank_pin = bcm6362_bank_pin(pin); ++ unsigned int val = value ? BIT(bank_pin) : 0; ++ ++ regmap_update_bits(pc->regs, data, BIT(bank_pin), val); ++} ++ ++static int bcm6362_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) ++{ ++ char irq_name[7]; ++ ++ sprintf(irq_name, "gpio%d", gpio); ++ ++ return of_irq_get_byname(chip->of_node, irq_name); ++} ++ ++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 bcm6362_pinctrl *pc, unsigned pin) ++{ ++ const struct pinctrl_pin_desc *desc = &bcm6362_pins[pin]; ++ unsigned int mask = bcm6362_bank_pin(pin); ++ ++ if (desc->drv_data) ++ regmap_update_bits(pc->regs, BCM6362_BASEMODE_REG, ++ (uint32_t) desc->drv_data, 0); ++ ++ if (pin < PINS_PER_BANK) { ++ /* 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 bcm6362_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 bcm6362_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 = { ++ .get_groups_count = bcm6362_pinctrl_get_group_count, ++ .get_group_name = bcm6362_pinctrl_get_group_name, ++ .get_group_pins = bcm6362_pinctrl_get_group_pins, ++ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, ++ .dt_free_map = pinctrl_utils_free_map, ++}; ++ ++static struct pinmux_ops bcm6362_pmx_ops = { ++ .get_functions_count = bcm6362_pinctrl_get_func_count, ++ .get_function_name = bcm6362_pinctrl_get_func_name, ++ .get_function_groups = bcm6362_pinctrl_get_groups, ++ .set_mux = bcm6362_pinctrl_set_mux, ++ .gpio_request_enable = bcm6362_gpio_request_enable, ++ .strict = true, ++}; ++ ++static int bcm6362_pinctrl_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *np = dev->of_node; ++ struct bcm6362_pinctrl *pc; ++ int err; ++ ++ pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); ++ if (!pc) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, pc); ++ pc->dev = dev; ++ ++ pc->regs = syscon_node_to_regmap(dev->parent->of_node); ++ if (IS_ERR(pc->regs)) ++ return PTR_ERR(pc->regs); ++ ++ pc->gpio_chip.label = MODULE_NAME; ++ pc->gpio_chip.owner = THIS_MODULE; ++ pc->gpio_chip.request = gpiochip_generic_request; ++ pc->gpio_chip.free = gpiochip_generic_free; ++ pc->gpio_chip.direction_input = bcm6362_gpio_direction_input; ++ pc->gpio_chip.direction_output = bcm6362_gpio_direction_output; ++ pc->gpio_chip.get_direction = bcm6362_gpio_get_direction; ++ pc->gpio_chip.get = bcm6362_gpio_get; ++ pc->gpio_chip.set = bcm6362_gpio_set; ++ pc->gpio_chip.set_config = gpiochip_generic_config; ++ pc->gpio_chip.base = -1; ++ pc->gpio_chip.ngpio = BCM6362_NUM_GPIOS; ++ pc->gpio_chip.can_sleep = false; ++ pc->gpio_chip.parent = dev; ++ pc->gpio_chip.of_node = np; ++ ++ if (of_get_property(np, "interrupt-names", NULL)) ++ pc->gpio_chip.to_irq = bcm6362_gpio_to_irq; ++ ++ err = gpiochip_add_data(&pc->gpio_chip, pc); ++ if (err) { ++ dev_err(dev, "could not add GPIO chip\n"); ++ return err; ++ } ++ ++ pc->pctl_desc.name = MODULE_NAME, ++ pc->pctl_desc.pins = bcm6362_pins, ++ pc->pctl_desc.npins = ARRAY_SIZE(bcm6362_pins), ++ pc->pctl_desc.pctlops = &bcm6362_pctl_ops, ++ pc->pctl_desc.pmxops = &bcm6362_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)) { ++ gpiochip_remove(&pc->gpio_chip); ++ return PTR_ERR(pc->pctl_dev); ++ } ++ ++ pc->gpio_range.name = MODULE_NAME; ++ pc->gpio_range.npins = BCM6362_NUM_GPIOS; ++ pc->gpio_range.base = pc->gpio_chip.base; ++ pc->gpio_range.gc = &pc->gpio_chip; ++ pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range); ++ ++ dev_info(dev, "registered\n"); ++ ++ return 0; ++} ++ ++static const struct of_device_id bcm6362_pinctrl_match[] = { ++ { .compatible = "brcm,bcm6362-pinctrl", }, ++ { }, ++}; ++ ++static struct platform_driver bcm6362_pinctrl_driver = { ++ .probe = bcm6362_pinctrl_probe, ++ .driver = { ++ .name = MODULE_NAME, ++ .of_match_table = bcm6362_pinctrl_match, ++ }, ++}; ++ ++builtin_platform_driver(bcm6362_pinctrl_driver); diff --git a/target/linux/bmips/patches-5.10/406-Documentation-add-BCM6368-pincontroller-binding-docu.patch b/target/linux/bmips/patches-5.10/406-Documentation-add-BCM6368-pincontroller-binding-docu.patch new file mode 100644 index 0000000000..59fbdaeaaa --- /dev/null +++ b/target/linux/bmips/patches-5.10/406-Documentation-add-BCM6368-pincontroller-binding-docu.patch @@ -0,0 +1,276 @@ +From 12f1d5123ee405266596eaea238d9810e0628d18 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= +Date: Wed, 27 Jul 2016 11:36:51 +0200 +Subject: [PATCH 07/12] Documentation: add BCM6368 pincontroller binding + documentation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add binding documentation for the pincontrol core found in BCM6368 SoCs. + +Signed-off-by: Álvaro Fernández Rojas +Signed-off-by: Jonas Gorski +--- + .../pinctrl/brcm,bcm6368-pinctrl.yaml | 255 ++++++++++++++++++ + 1 file changed, 255 insertions(+) + create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml + +--- /dev/null ++++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml +@@ -0,0 +1,255 @@ ++# 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 ++ - Jonas Gorski ++ ++description: |+ ++ The pin controller node should be the child of a syscon node. ++ ++ Refer to the the bindings described in ++ Documentation/devicetree/bindings/mfd/syscon.yaml ++ ++properties: ++ compatible: ++ const: brcm,bcm6368-pinctrl ++ ++ gpio-controller: true ++ ++ '#gpio-cells': ++ description: ++ Specifies the pin number and flags, as defined in ++ include/dt-bindings/gpio/gpio.h ++ const: 2 ++ ++ interrupts-extended: ++ description: ++ One interrupt per each of the 6 GPIO ports supported by the controller, ++ sorted by port number ascending order. ++ minItems: 6 ++ maxItems: 6 ++ ++patternProperties: ++ '^.*$': ++ if: ++ type: object ++ then: ++ properties: ++ function: ++ $ref: "/schemas/types.yaml#/definitions/string" ++ 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: ++ $ref: "/schemas/types.yaml#/definitions/string" ++ 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 ++ - gpio-controller ++ - '#gpio-cells' ++ ++additionalProperties: false ++ ++examples: ++ - | ++ gpio@10000080 { ++ compatible = "syscon", "simple-mfd"; ++ reg = <0x10000080 0x80>; ++ ++ pinctrl: pinctrl { ++ compatible = "brcm,bcm6368-pinctrl"; ++ ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ interrupts-extended = <&ext_intc1 0 0>, ++ <&ext_intc1 1 0>, ++ <&ext_intc0 0 0>, ++ <&ext_intc0 1 0>, ++ <&ext_intc0 2 0>, ++ <&ext_intc0 3 0>; ++ interrupt-names = "gpio32", ++ "gpio33", ++ "gpio34", ++ "gpio35", ++ "gpio36", ++ "gpio37"; ++ ++ pinctrl_analog_afe_0: analog_afe_0 { ++ function = "analog_afe_0"; ++ pins = "gpio0"; ++ }; ++ ++ pinctrl_analog_afe_1: analog_afe_1 { ++ function = "analog_afe_1"; ++ pins = "gpio1"; ++ }; ++ ++ pinctrl_sys_irq: sys_irq { ++ function = "sys_irq"; ++ pins = "gpio2"; ++ }; ++ ++ pinctrl_serial_led: serial_led { ++ pinctrl_serial_led_data: serial_led_data { ++ function = "serial_led_data"; ++ pins = "gpio3"; ++ }; ++ ++ pinctrl_serial_led_clk: serial_led_clk { ++ function = "serial_led_clk"; ++ pins = "gpio4"; ++ }; ++ }; ++ ++ pinctrl_inet_led: inet_led { ++ function = "inet_led"; ++ pins = "gpio5"; ++ }; ++ ++ pinctrl_ephy0_led: ephy0_led { ++ function = "ephy0_led"; ++ pins = "gpio6"; ++ }; ++ ++ pinctrl_ephy1_led: ephy1_led { ++ function = "ephy1_led"; ++ pins = "gpio7"; ++ }; ++ ++ pinctrl_ephy2_led: ephy2_led { ++ function = "ephy2_led"; ++ pins = "gpio8"; ++ }; ++ ++ pinctrl_ephy3_led: ephy3_led { ++ function = "ephy3_led"; ++ pins = "gpio9"; ++ }; ++ ++ pinctrl_robosw_led_data: robosw_led_data { ++ function = "robosw_led_data"; ++ pins = "gpio10"; ++ }; ++ ++ pinctrl_robosw_led_clk: robosw_led_clk { ++ function = "robosw_led_clk"; ++ pins = "gpio11"; ++ }; ++ ++ pinctrl_robosw_led0: robosw_led0 { ++ function = "robosw_led0"; ++ pins = "gpio12"; ++ }; ++ ++ pinctrl_robosw_led1: robosw_led1 { ++ function = "robosw_led1"; ++ pins = "gpio13"; ++ }; ++ ++ pinctrl_usb_device_led: usb_device_led { ++ function = "usb_device_led"; ++ pins = "gpio14"; ++ }; ++ ++ pinctrl_pci: pci { ++ pinctrl_pci_req1: pci_req1 { ++ function = "pci_req1"; ++ pins = "gpio16"; ++ }; ++ ++ pinctrl_pci_gnt1: pci_gnt1 { ++ function = "pci_gnt1"; ++ pins = "gpio17"; ++ }; ++ ++ pinctrl_pci_intb: pci_intb { ++ function = "pci_intb"; ++ pins = "gpio18"; ++ }; ++ ++ pinctrl_pci_req0: pci_req0 { ++ function = "pci_req0"; ++ pins = "gpio19"; ++ }; ++ ++ pinctrl_pci_gnt0: pci_gnt0 { ++ function = "pci_gnt0"; ++ pins = "gpio20"; ++ }; ++ }; ++ ++ pinctrl_pcmcia: pcmcia { ++ pinctrl_pcmcia_cd1: pcmcia_cd1 { ++ function = "pcmcia_cd1"; ++ pins = "gpio22"; ++ }; ++ ++ pinctrl_pcmcia_cd2: pcmcia_cd2 { ++ function = "pcmcia_cd2"; ++ pins = "gpio23"; ++ }; ++ ++ pinctrl_pcmcia_vs1: pcmcia_vs1 { ++ function = "pcmcia_vs1"; ++ pins = "gpio24"; ++ }; ++ ++ pinctrl_pcmcia_vs2: pcmcia_vs2 { ++ function = "pcmcia_vs2"; ++ pins = "gpio25"; ++ }; ++ }; ++ ++ pinctrl_ebi_cs2: ebi_cs2 { ++ function = "ebi_cs2"; ++ pins = "gpio26"; ++ }; ++ ++ pinctrl_ebi_cs3: ebi_cs3 { ++ function = "ebi_cs3"; ++ pins = "gpio27"; ++ }; ++ ++ pinctrl_spi_cs2: spi_cs2 { ++ function = "spi_cs2"; ++ pins = "gpio28"; ++ }; ++ ++ pinctrl_spi_cs3: spi_cs3 { ++ function = "spi_cs3"; ++ pins = "gpio29"; ++ }; ++ ++ pinctrl_spi_cs4: spi_cs4 { ++ function = "spi_cs4"; ++ pins = "gpio30"; ++ }; ++ ++ pinctrl_spi_cs5: spi_cs5 { ++ function = "spi_cs5"; ++ pins = "gpio31"; ++ }; ++ ++ pinctrl_uart1: uart1 { ++ function = "uart1"; ++ group = "uart1_grp"; ++ }; ++ }; ++ }; diff --git a/target/linux/bmips/patches-5.10/406-pinctrl-add-a-pincontrol-driver-for-BCM6362.patch b/target/linux/bmips/patches-5.10/406-pinctrl-add-a-pincontrol-driver-for-BCM6362.patch deleted file mode 100644 index 30b95158e4..0000000000 --- a/target/linux/bmips/patches-5.10/406-pinctrl-add-a-pincontrol-driver-for-BCM6362.patch +++ /dev/null @@ -1,733 +0,0 @@ -From eea6b96701d734095e2f823f3a82d9b063f553ae Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Fri, 24 Jun 2016 22:17:20 +0200 -Subject: [PATCH 09/16] pinctrl: add a pincontrol driver for BCM6362 - -Add a pincotrol driver for BCM6362. BCM6362 allows muxing individual -GPIO pins to the LED controller, to be available by the integrated -wifi, or other functions. It also supports overlay groups, of which -only NAND is documented. - -Signed-off-by: Jonas Gorski ---- - drivers/pinctrl/bcm63xx/Kconfig | 7 + - drivers/pinctrl/bcm63xx/Makefile | 1 + - drivers/pinctrl/bcm63xx/pinctrl-bcm6362.c | 692 ++++++++++++++++++++++++++++++ - 3 files changed, 700 insertions(+) - create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6362.c - ---- a/drivers/pinctrl/bcm63xx/Kconfig -+++ b/drivers/pinctrl/bcm63xx/Kconfig -@@ -16,3 +16,10 @@ config PINCTRL_BCM6358 - select PINCTRL_BCM63XX - select GENERIC_PINCONF - select MFD_SYSCON -+ -+config PINCTRL_BCM6362 -+ bool "BCM6362 pincontrol driver" -+ select PINMUX -+ select PINCONF -+ select PINCTRL_BCM63XX -+ select GENERIC_PINCONF ---- a/drivers/pinctrl/bcm63xx/Makefile -+++ b/drivers/pinctrl/bcm63xx/Makefile -@@ -1,3 +1,4 @@ - obj-$(CONFIG_PINCTRL_BCM63XX) += pinctrl-bcm63xx.o - obj-$(CONFIG_PINCTRL_BCM6328) += pinctrl-bcm6328.o - obj-$(CONFIG_PINCTRL_BCM6358) += pinctrl-bcm6358.o -+obj-$(CONFIG_PINCTRL_BCM6362) += pinctrl-bcm6362.o ---- /dev/null -+++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm6362.c -@@ -0,0 +1,692 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2016 Jonas Gorski -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "../core.h" -+#include "../pinctrl-utils.h" -+ -+#include "pinctrl-bcm63xx.h" -+ -+#define BCM6362_NGPIO 48 -+ -+/* GPIO_BASEMODE register */ -+#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; -+ u32 basemode_mask; -+}; -+ -+struct bcm6362_pinctrl { -+ struct pinctrl_dev *pctldev; -+ struct pinctrl_desc desc; -+ -+ void __iomem *led; -+ void __iomem *mode; -+ void __iomem *ctrl; -+ void __iomem *basemode; -+ -+ /* register access lock */ -+ spinlock_t lock; -+ -+ struct gpio_chip gpio[2]; -+}; -+ -+#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_rmw_mux(struct bcm6362_pinctrl *pctl, void __iomem *reg, -+ u32 mask, u32 val) -+{ -+ unsigned long flags; -+ u32 tmp; -+ -+ spin_lock_irqsave(&pctl->lock, flags); -+ tmp = __raw_readl(reg); -+ tmp &= ~mask; -+ tmp |= val & mask; -+ __raw_writel(tmp, reg); -+ -+ spin_unlock_irqrestore(&pctl->lock, flags); -+} -+ -+static void bcm6362_set_gpio(struct bcm6362_pinctrl *pctl, unsigned pin) -+{ -+ const struct pinctrl_pin_desc *desc = &bcm6362_pins[pin]; -+ u32 mask = BIT(pin % 32); -+ -+ if (desc->drv_data) -+ bcm6362_rmw_mux(pctl, pctl->basemode, (u32)desc->drv_data, 0); -+ -+ if (pin < 32) { -+ /* base mode 0 => gpio 1 => mux function */ -+ bcm6362_rmw_mux(pctl, pctl->mode, mask, 0); -+ -+ /* pins 0-23 might be muxed to led */ -+ if (pin < 24) -+ bcm6362_rmw_mux(pctl, pctl->led, mask, 0); -+ } else { -+ /* ctrl reg 0 => wifi function 1 => gpio */ -+ bcm6362_rmw_mux(pctl, pctl->ctrl, mask, mask); -+ } -+} -+ -+static int bcm6362_pinctrl_set_mux(struct pinctrl_dev *pctldev, -+ unsigned selector, unsigned group) -+{ -+ struct bcm6362_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); -+ const struct bcm6362_pingroup *grp = &bcm6362_groups[group]; -+ const struct bcm6362_function *f = &bcm6362_funcs[selector]; -+ unsigned i; -+ void __iomem *reg; -+ u32 val, mask; -+ -+ for (i = 0; i < grp->num_pins; i++) -+ bcm6362_set_gpio(pctl, grp->pins[i]); -+ -+ switch (f->reg) { -+ case BCM6362_LEDCTRL: -+ reg = pctl->led; -+ mask = BIT(grp->pins[0]); -+ val = BIT(grp->pins[0]); -+ break; -+ case BCM6362_MODE: -+ reg = pctl->mode; -+ mask = BIT(grp->pins[0]); -+ val = BIT(grp->pins[0]); -+ break; -+ case BCM6362_CTRL: -+ reg = pctl->ctrl; -+ mask = BIT(grp->pins[0]); -+ val = 0; -+ break; -+ case BCM6362_BASEMODE: -+ reg = pctl->basemode; -+ mask = f->basemode_mask; -+ val = f->basemode_mask; -+ break; -+ default: -+ WARN_ON(1); -+ return -EINVAL; -+ } -+ -+ bcm6362_rmw_mux(pctl, reg, mask, val); -+ -+ return 0; -+} -+ -+static int bcm6362_gpio_request_enable(struct pinctrl_dev *pctldev, -+ struct pinctrl_gpio_range *range, -+ unsigned offset) -+{ -+ struct bcm6362_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); -+ -+ /* disable all functions using this pin */ -+ bcm6362_set_gpio(pctl, offset); -+ -+ return 0; -+} -+ -+static struct pinctrl_ops bcm6362_pctl_ops = { -+ .get_groups_count = bcm6362_pinctrl_get_group_count, -+ .get_group_name = bcm6362_pinctrl_get_group_name, -+ .get_group_pins = bcm6362_pinctrl_get_group_pins, -+#ifdef CONFIG_OF -+ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, -+ .dt_free_map = pinctrl_utils_free_map, -+#endif -+}; -+ -+static struct pinmux_ops bcm6362_pmx_ops = { -+ .get_functions_count = bcm6362_pinctrl_get_func_count, -+ .get_function_name = bcm6362_pinctrl_get_func_name, -+ .get_function_groups = bcm6362_pinctrl_get_groups, -+ .set_mux = bcm6362_pinctrl_set_mux, -+ .gpio_request_enable = bcm6362_gpio_request_enable, -+ .strict = true, -+}; -+ -+static int bcm6362_pinctrl_probe(struct platform_device *pdev) -+{ -+ struct bcm6362_pinctrl *pctl; -+ struct resource *res; -+ void __iomem *led, *mode, *ctrl, *basemode; -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "led"); -+ led = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(led)) -+ return PTR_ERR(led); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode"); -+ mode = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(mode)) -+ return PTR_ERR(mode); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl"); -+ ctrl = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(ctrl)) -+ return PTR_ERR(ctrl); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "basemode"); -+ basemode = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(basemode)) -+ return PTR_ERR(basemode); -+ -+ pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL); -+ if (!pctl) -+ return -ENOMEM; -+ -+ spin_lock_init(&pctl->lock); -+ -+ pctl->led = led; -+ pctl->mode = mode; -+ pctl->ctrl = ctrl; -+ pctl->basemode = basemode; -+ -+ pctl->desc.name = dev_name(&pdev->dev); -+ pctl->desc.owner = THIS_MODULE; -+ pctl->desc.pctlops = &bcm6362_pctl_ops; -+ pctl->desc.pmxops = &bcm6362_pmx_ops; -+ -+ pctl->desc.npins = ARRAY_SIZE(bcm6362_pins); -+ pctl->desc.pins = bcm6362_pins; -+ -+ platform_set_drvdata(pdev, pctl); -+ -+ pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl, -+ pctl->gpio, BCM6362_NGPIO); -+ if (IS_ERR(pctl->pctldev)) -+ return PTR_ERR(pctl->pctldev); -+ -+ return 0; -+} -+ -+static const struct of_device_id bcm6362_pinctrl_match[] = { -+ { .compatible = "brcm,bcm6362-pinctrl", }, -+ { }, -+}; -+ -+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/target/linux/bmips/patches-5.10/407-Documentation-add-BCM6368-pincontroller-binding-docu.patch b/target/linux/bmips/patches-5.10/407-Documentation-add-BCM6368-pincontroller-binding-docu.patch deleted file mode 100644 index e0a698fc12..0000000000 --- a/target/linux/bmips/patches-5.10/407-Documentation-add-BCM6368-pincontroller-binding-docu.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 30594cf9bfff176a9e4b14c50dcd8b9d0cc3edec Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Wed, 27 Jul 2016 11:36:51 +0200 -Subject: [PATCH 10/16] Documentation: add BCM6368 pincontroller binding - documentation - -Add binding documentation for the pincontrol core found in BCM6368 SoCs. - -Signed-off-by: Jonas Gorski ---- - .../bindings/pinctrl/brcm,bcm6368-pinctrl.txt | 67 ++++++++++++++++++++++ - 1 file changed, 67 insertions(+) - create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.txt - ---- /dev/null -+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.txt -@@ -0,0 +1,67 @@ -+* Broadcom BCM6368 pin controller -+ -+Required properties: -+- compatible: Must be "brcm,bcm6368-pinctrl". -+- reg: Register specifiers of dirout, dat, mode registers. -+- reg-names: Must be "dirout", "dat", "mode". -+- brcm,gpiobasemode: Phandle to the gpio basemode register. -+- gpio-controller: Identifies this node as a GPIO controller. -+- #gpio-cells: Must be <2>. -+ -+Example: -+ -+pinctrl: pin-controller@10000080 { -+ compatible = "brcm,bcm6368-pinctrl"; -+ reg = <0x10000080 0x08>, -+ <0x10000088 0x08>, -+ <0x10000098 0x04>; -+ reg-names = "dirout", "dat", "mode"; -+ brcm,gpiobasemode = <&gpiobasemode>; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+}; -+ -+gpiobasemode: syscon@100000b8 { -+ compatible = "brcm,bcm6368-gpiobasemode", "syscon"; -+ reg = <0x100000b8 4>; -+ native-endian; -+}; -+ -+Available pins/groups and functions: -+ -+name pins functions -+----------------------------------------------------------- -+gpio0 0 analog_afe0 -+gpio1 1 analog_afe1 -+gpio2 2 sys_irq -+gpio3 3 serial_led_data -+gpio4 4 serial_led_clk -+gpio5 5 inet_led -+gpio6 6 ephy0_led -+gpio7 7 ephy1_led -+gpio8 8 ephy2_led -+gpio9 9 ephy3_led -+gpio10 10 robosw_led_data -+gpio11 11 robosw_led_clk -+gpio12 12 robosw_led0 -+gpio13 13 robosw_led1 -+gpio14 14 usb_device_led -+gpio15 15 - -+gpio16 16 pci_req1 -+gpio17 17 pci_gnt1 -+gpio18 18 pci_intb -+gpio19 19 pci_req0 -+gpio20 20 pci_gnt0 -+gpio21 21 - -+gpio22 22 pcmcia_cd1 -+gpio23 23 pcmcia_cd2 -+gpio24 24 pcmcia_vs1 -+gpio25 25 pcmcia_vs2 -+gpio26 26 ebi_cs2 -+gpio27 27 ebi_cs3 -+gpio28 28 spi_cs2 -+gpio29 29 spi_cs3 -+gpio30 30 spi_cs4 -+gpio31 31 spi_cs5 -+uart1_grp 30-33 uart1 diff --git a/target/linux/bmips/patches-5.10/407-pinctrl-add-a-pincontrol-driver-for-BCM6368.patch b/target/linux/bmips/patches-5.10/407-pinctrl-add-a-pincontrol-driver-for-BCM6368.patch new file mode 100644 index 0000000000..5a5dac3487 --- /dev/null +++ b/target/linux/bmips/patches-5.10/407-pinctrl-add-a-pincontrol-driver-for-BCM6368.patch @@ -0,0 +1,732 @@ +From a212dcb2f04ae42f35ec11122a2532b1bcf8a94f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= +Date: Fri, 24 Jun 2016 22:18:25 +0200 +Subject: [PATCH 08/12] pinctrl: add a pincontrol driver for BCM6368 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add a pincontrol driver for BCM6368. BCM6368 allows muxing the first 32 +GPIOs onto alternative functions. Not all are documented. + +Signed-off-by: Álvaro Fernández Rojas +Signed-off-by: Jonas Gorski +--- + drivers/pinctrl/bcm/Kconfig | 11 + + drivers/pinctrl/bcm/Makefile | 1 + + drivers/pinctrl/bcm/pinctrl-bcm6368.c | 679 ++++++++++++++++++++++++++ + 3 files changed, 691 insertions(+) + create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6368.c + +--- a/drivers/pinctrl/bcm/Kconfig ++++ b/drivers/pinctrl/bcm/Kconfig +@@ -62,6 +62,17 @@ config PINCTRL_BCM6362 + help + Say Y here to enable the Broadcom BCM6362 GPIO driver. + ++config PINCTRL_BCM6368 ++ bool "Broadcom BCM6368 GPIO driver" ++ depends on OF_GPIO && (BMIPS_GENERIC || COMPILE_TEST) ++ select PINMUX ++ select PINCONF ++ select GENERIC_PINCONF ++ select MFD_SYSCON ++ default BMIPS_GENERIC ++ help ++ Say Y here to enable the Broadcom BCM6368 GPIO driver. ++ + config PINCTRL_IPROC_GPIO + bool "Broadcom iProc GPIO (with PINCONF) driver" + depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST) +--- a/drivers/pinctrl/bcm/Makefile ++++ b/drivers/pinctrl/bcm/Makefile +@@ -6,6 +6,7 @@ obj-$(CONFIG_PINCTRL_BCM2835) += pinctr + 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_IPROC_GPIO) += pinctrl-iproc-gpio.o + obj-$(CONFIG_PINCTRL_CYGNUS_MUX) += pinctrl-cygnus-mux.o + obj-$(CONFIG_PINCTRL_NS) += pinctrl-ns.o +--- /dev/null ++++ b/drivers/pinctrl/bcm/pinctrl-bcm6368.c +@@ -0,0 +1,679 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Driver for BCM6368 GPIO unit (pinctrl + GPIO) ++ * ++ * Copyright (C) 2021 Álvaro Fernández Rojas ++ * Copyright (C) 2016 Jonas Gorski ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include "../core.h" ++#include "../pinctrl-utils.h" ++ ++#define MODULE_NAME "bcm6368-pinctrl" ++#define BCM6368_NUM_GPIOS 38 ++ ++#define BANK_SIZE sizeof(uint32_t) ++#define PINS_PER_BANK (BANK_SIZE * BITS_PER_BYTE) ++ ++#define BCM6368_DIROUT_REG 0x04 ++#define BCM6368_DATA_REG 0x0c ++#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_pinctrl { ++ struct device *dev; ++ struct regmap *regs; ++ struct regmap_field *overlays; ++ ++ struct pinctrl_dev *pctl_dev; ++ struct gpio_chip gpio_chip; ++ struct pinctrl_desc pctl_desc; ++ struct pinctrl_gpio_range gpio_range; ++}; ++ ++#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 inline unsigned int bcm6368_bank_pin(unsigned int pin) ++{ ++ return pin % PINS_PER_BANK; ++} ++ ++static inline unsigned int bcm6368_reg_off(unsigned int reg, unsigned int pin) ++{ ++ return reg - (pin / PINS_PER_BANK) * BANK_SIZE; ++} ++ ++static int bcm6368_gpio_direction_input(struct gpio_chip *chip, ++ unsigned int pin) ++{ ++ struct bcm6368_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int dirout = bcm6368_reg_off(BCM6368_DIROUT_REG, pin); ++ unsigned int bank_pin = bcm6368_bank_pin(pin); ++ int ret; ++ ++ /* ++ * Check with the pinctrl driver whether this pin is usable as ++ * an input GPIO ++ */ ++ ret = pinctrl_gpio_direction_input(chip->base + pin); ++ if (ret) ++ return ret; ++ ++ regmap_update_bits(pc->regs, dirout, BIT(bank_pin), 0); ++ ++ return 0; ++} ++ ++static int bcm6368_gpio_direction_output(struct gpio_chip *chip, ++ unsigned int pin, int value) ++{ ++ struct bcm6368_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int data = bcm6368_reg_off(BCM6368_DATA_REG, pin); ++ unsigned int dirout = bcm6368_reg_off(BCM6368_DIROUT_REG, pin); ++ unsigned int bank_pin = bcm6368_bank_pin(pin); ++ unsigned int val = value ? BIT(bank_pin) : 0; ++ int ret; ++ ++ /* ++ * Check with the pinctrl driver whether this pin is usable as ++ * an output GPIO ++ */ ++ ret = pinctrl_gpio_direction_output(chip->base + pin); ++ if (ret) ++ return ret; ++ ++ regmap_update_bits(pc->regs, dirout, BIT(bank_pin), BIT(bank_pin)); ++ regmap_update_bits(pc->regs, data, BIT(bank_pin), val); ++ ++ return 0; ++} ++ ++static int bcm6368_gpio_get(struct gpio_chip *chip, unsigned int pin) ++{ ++ struct bcm6368_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int data = bcm6368_reg_off(BCM6368_DATA_REG, pin); ++ unsigned int bank_pin = bcm6368_bank_pin(pin); ++ unsigned int val; ++ ++ regmap_read(pc->regs, data, &val); ++ ++ return !!(val & BIT(bank_pin)); ++} ++ ++static int bcm6368_gpio_get_direction(struct gpio_chip *chip, unsigned int pin) ++{ ++ struct bcm6368_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int dirout = bcm6368_reg_off(BCM6368_DIROUT_REG, pin); ++ unsigned int bank_pin = bcm6368_bank_pin(pin); ++ unsigned int val; ++ ++ regmap_read(pc->regs, dirout, &val); ++ ++ if (val & BIT(bank_pin)) ++ return GPIO_LINE_DIRECTION_OUT; ++ ++ return GPIO_LINE_DIRECTION_IN; ++} ++ ++static void bcm6368_gpio_set(struct gpio_chip *chip, unsigned int pin, ++ int value) ++{ ++ struct bcm6368_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int data = bcm6368_reg_off(BCM6368_DATA_REG, pin); ++ unsigned int bank_pin = bcm6368_bank_pin(pin); ++ unsigned int val = value ? BIT(bank_pin) : 0; ++ ++ regmap_update_bits(pc->regs, data, BIT(bank_pin), val); ++} ++ ++static int bcm6368_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) ++{ ++ char irq_name[7]; ++ ++ sprintf(irq_name, "gpio%d", gpio); ++ ++ return of_irq_get_byname(chip->of_node, irq_name); ++} ++ ++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 bcm6368_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); ++ 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 < PINS_PER_BANK) ++ mask |= BIT(pin); ++ } ++ ++ regmap_update_bits(pc->regs, BCM6368_MODE_REG, mask, 0); ++ regmap_field_write(pc->overlays, fun->basemode); ++ } else { ++ pin = pg->pins[0]; ++ ++ if (bcm6368_pins[pin].drv_data) ++ regmap_field_write(pc->overlays, ++ BCM6368_BASEMODE_GPIO); ++ ++ regmap_update_bits(pc->regs, BCM6368_MODE_REG, BIT(pin), ++ BIT(pin)); ++ } ++ ++ for (pin = 0; pin < pg->num_pins; pin++) { ++ int hw_gpio = bcm6368_pins[pin].number; ++ struct gpio_chip *gc = &pc->gpio_chip; ++ ++ 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 bcm6368_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); ++ ++ if (offset >= PINS_PER_BANK && !bcm6368_pins[offset].drv_data) ++ return 0; ++ ++ /* disable all functions using this pin */ ++ if (offset < PINS_PER_BANK) ++ regmap_update_bits(pc->regs, BCM6368_MODE_REG, BIT(offset), 0); ++ ++ if (bcm6368_pins[offset].drv_data) ++ regmap_field_write(pc->overlays, BCM6368_BASEMODE_GPIO); ++ ++ return 0; ++} ++ ++static struct pinctrl_ops bcm6368_pctl_ops = { ++ .get_groups_count = bcm6368_pinctrl_get_group_count, ++ .get_group_name = bcm6368_pinctrl_get_group_name, ++ .get_group_pins = bcm6368_pinctrl_get_group_pins, ++ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, ++ .dt_free_map = pinctrl_utils_free_map, ++}; ++ ++static struct pinmux_ops bcm6368_pmx_ops = { ++ .get_functions_count = bcm6368_pinctrl_get_func_count, ++ .get_function_name = bcm6368_pinctrl_get_func_name, ++ .get_function_groups = bcm6368_pinctrl_get_groups, ++ .set_mux = bcm6368_pinctrl_set_mux, ++ .gpio_request_enable = bcm6368_gpio_request_enable, ++ .strict = true, ++}; ++ ++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 device_node *np = dev->of_node; ++ struct bcm6368_pinctrl *pc; ++ int err; ++ ++ pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); ++ if (!pc) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, pc); ++ pc->dev = dev; ++ ++ pc->regs = syscon_node_to_regmap(dev->parent->of_node); ++ if (IS_ERR(pc->regs)) ++ return PTR_ERR(pc->regs); ++ ++ pc->overlays = devm_regmap_field_alloc(&pdev->dev, pc->regs, overlays); ++ if (IS_ERR(pc->overlays)) ++ return PTR_ERR(pc->overlays); ++ ++ /* disable all muxes by default */ ++ regmap_field_write(pc->overlays, 0); ++ ++ pc->gpio_chip.label = MODULE_NAME; ++ pc->gpio_chip.owner = THIS_MODULE; ++ pc->gpio_chip.request = gpiochip_generic_request; ++ pc->gpio_chip.free = gpiochip_generic_free; ++ pc->gpio_chip.direction_input = bcm6368_gpio_direction_input; ++ pc->gpio_chip.direction_output = bcm6368_gpio_direction_output; ++ pc->gpio_chip.get_direction = bcm6368_gpio_get_direction; ++ pc->gpio_chip.get = bcm6368_gpio_get; ++ pc->gpio_chip.set = bcm6368_gpio_set; ++ pc->gpio_chip.set_config = gpiochip_generic_config; ++ pc->gpio_chip.base = -1; ++ pc->gpio_chip.ngpio = BCM6368_NUM_GPIOS; ++ pc->gpio_chip.can_sleep = false; ++ pc->gpio_chip.parent = dev; ++ pc->gpio_chip.of_node = np; ++ ++ if (of_get_property(np, "interrupt-names", NULL)) ++ pc->gpio_chip.to_irq = bcm6368_gpio_to_irq; ++ ++ err = gpiochip_add_data(&pc->gpio_chip, pc); ++ if (err) { ++ dev_err(dev, "could not add GPIO chip\n"); ++ return err; ++ } ++ ++ pc->pctl_desc.name = MODULE_NAME, ++ pc->pctl_desc.pins = bcm6368_pins, ++ pc->pctl_desc.npins = ARRAY_SIZE(bcm6368_pins), ++ pc->pctl_desc.pctlops = &bcm6368_pctl_ops, ++ pc->pctl_desc.pmxops = &bcm6368_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)) { ++ gpiochip_remove(&pc->gpio_chip); ++ return PTR_ERR(pc->pctl_dev); ++ } ++ ++ pc->gpio_range.name = MODULE_NAME; ++ pc->gpio_range.npins = BCM6368_NUM_GPIOS; ++ pc->gpio_range.base = pc->gpio_chip.base; ++ pc->gpio_range.gc = &pc->gpio_chip; ++ pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range); ++ ++ dev_info(dev, "registered\n"); ++ ++ return 0; ++} ++ ++static const struct of_device_id bcm6368_pinctrl_match[] = { ++ { .compatible = "brcm,bcm6368-pinctrl", }, ++ { }, ++}; ++ ++static struct platform_driver bcm6368_pinctrl_driver = { ++ .probe = bcm6368_pinctrl_probe, ++ .driver = { ++ .name = MODULE_NAME, ++ .of_match_table = bcm6368_pinctrl_match, ++ }, ++}; ++ ++builtin_platform_driver(bcm6368_pinctrl_driver); diff --git a/target/linux/bmips/patches-5.10/408-Documentation-add-BCM63268-pincontroller-binding-doc.patch b/target/linux/bmips/patches-5.10/408-Documentation-add-BCM63268-pincontroller-binding-doc.patch new file mode 100644 index 0000000000..d51af84328 --- /dev/null +++ b/target/linux/bmips/patches-5.10/408-Documentation-add-BCM63268-pincontroller-binding-doc.patch @@ -0,0 +1,220 @@ +From 826266914f8397c996d2d4d821b315d614bfc325 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= +Date: Wed, 27 Jul 2016 11:37:08 +0200 +Subject: [PATCH 09/12] Documentation: add BCM63268 pincontroller binding + documentation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add binding documentation for the pincontrol core found in the BCM63268 +family SoCs. + +Signed-off-by: Álvaro Fernández Rojas +Signed-off-by: Jonas Gorski +--- + .../pinctrl/brcm,bcm63268-pinctrl.yaml | 198 ++++++++++++++++++ + 1 file changed, 198 insertions(+) + create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml + +--- /dev/null ++++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml +@@ -0,0 +1,198 @@ ++# 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 ++ - Jonas Gorski ++ ++description: |+ ++ The pin controller node should be the child of a syscon node. ++ ++ Refer to the the bindings described in ++ Documentation/devicetree/bindings/mfd/syscon.yaml ++ ++properties: ++ compatible: ++ const: brcm,bcm63268-pinctrl ++ ++ gpio-controller: true ++ ++ '#gpio-cells': ++ description: ++ Specifies the pin number and flags, as defined in ++ include/dt-bindings/gpio/gpio.h ++ const: 2 ++ ++ interrupts-extended: ++ description: ++ One interrupt per each of the 4 GPIO ports supported by the controller, ++ sorted by port number ascending order. ++ minItems: 4 ++ maxItems: 4 ++ ++patternProperties: ++ '^.*$': ++ if: ++ type: object ++ then: ++ properties: ++ function: ++ $ref: "/schemas/types.yaml#/definitions/string" ++ 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: ++ $ref: "/schemas/types.yaml#/definitions/string" ++ 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 ++ - gpio-controller ++ - '#gpio-cells' ++ ++additionalProperties: false ++ ++examples: ++ - | ++ gpio@100000c0 { ++ compatible = "syscon", "simple-mfd"; ++ reg = <0x100000c0 0x80>; ++ ++ pinctrl: pinctrl { ++ compatible = "brcm,bcm63268-pinctrl"; ++ ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ interrupts-extended = <&ext_intc 0 0>, ++ <&ext_intc 1 0>, ++ <&ext_intc 2 0>, ++ <&ext_intc 3 0>; ++ interrupt-names = "gpio32", ++ "gpio33", ++ "gpio34", ++ "gpio35"; ++ ++ pinctrl_serial_led: serial_led { ++ pinctrl_serial_led_clk: serial_led_clk { ++ function = "serial_led_clk"; ++ pins = "gpio0"; ++ }; ++ ++ pinctrl_serial_led_data: serial_led_data { ++ function = "serial_led_data"; ++ pins = "gpio1"; ++ }; ++ }; ++ ++ pinctrl_hsspi_cs4: hsspi_cs4 { ++ function = "hsspi_cs4"; ++ pins = "gpio16"; ++ }; ++ ++ pinctrl_hsspi_cs5: hsspi_cs5 { ++ function = "hsspi_cs5"; ++ pins = "gpio17"; ++ }; ++ ++ pinctrl_hsspi_cs6: hsspi_cs6 { ++ function = "hsspi_cs6"; ++ pins = "gpio8"; ++ }; ++ ++ pinctrl_hsspi_cs7: hsspi_cs7 { ++ function = "hsspi_cs7"; ++ pins = "gpio9"; ++ }; ++ ++ pinctrl_adsl_spi: adsl_spi { ++ pinctrl_adsl_spi_miso: adsl_spi_miso { ++ function = "adsl_spi_miso"; ++ pins = "gpio18"; ++ }; ++ ++ pinctrl_adsl_spi_mosi: adsl_spi_mosi { ++ function = "adsl_spi_mosi"; ++ pins = "gpio19"; ++ }; ++ }; ++ ++ pinctrl_vreq_clk: vreq_clk { ++ function = "vreq_clk"; ++ pins = "gpio22"; ++ }; ++ ++ pinctrl_pcie_clkreq_b: pcie_clkreq_b { ++ function = "pcie_clkreq_b"; ++ pins = "gpio23"; ++ }; ++ ++ pinctrl_robosw_led_clk: robosw_led_clk { ++ function = "robosw_led_clk"; ++ pins = "gpio30"; ++ }; ++ ++ pinctrl_robosw_led_data: robosw_led_data { ++ function = "robosw_led_data"; ++ pins = "gpio31"; ++ }; ++ ++ pinctrl_nand: nand { ++ function = "nand"; ++ group = "nand_grp"; ++ }; ++ ++ pinctrl_gpio35_alt: gpio35_alt { ++ function = "gpio35_alt"; ++ pin = "gpio35"; ++ }; ++ ++ pinctrl_dectpd: dectpd { ++ function = "dectpd"; ++ group = "dectpd_grp"; ++ }; ++ ++ pinctrl_vdsl_phy_override_0: vdsl_phy_override_0 { ++ function = "vdsl_phy_override_0"; ++ group = "vdsl_phy_override_0_grp"; ++ }; ++ ++ pinctrl_vdsl_phy_override_1: vdsl_phy_override_1 { ++ function = "vdsl_phy_override_1"; ++ group = "vdsl_phy_override_1_grp"; ++ }; ++ ++ pinctrl_vdsl_phy_override_2: vdsl_phy_override_2 { ++ function = "vdsl_phy_override_2"; ++ group = "vdsl_phy_override_2_grp"; ++ }; ++ ++ pinctrl_vdsl_phy_override_3: vdsl_phy_override_3 { ++ function = "vdsl_phy_override_3"; ++ group = "vdsl_phy_override_3_grp"; ++ }; ++ ++ pinctrl_dsl_gpio8: dsl_gpio8 { ++ function = "dsl_gpio8"; ++ group = "dsl_gpio8"; ++ }; ++ ++ pinctrl_dsl_gpio9: dsl_gpio9 { ++ function = "dsl_gpio9"; ++ group = "dsl_gpio9"; ++ }; ++ }; ++ }; diff --git a/target/linux/bmips/patches-5.10/408-pinctrl-add-a-pincontrol-driver-for-BCM6368.patch b/target/linux/bmips/patches-5.10/408-pinctrl-add-a-pincontrol-driver-for-BCM6368.patch deleted file mode 100644 index 80b007799f..0000000000 --- a/target/linux/bmips/patches-5.10/408-pinctrl-add-a-pincontrol-driver-for-BCM6368.patch +++ /dev/null @@ -1,610 +0,0 @@ -From 90be3cb4f1a45b8be4a4ec264cd66c2f8e893fcb Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Fri, 24 Jun 2016 22:18:25 +0200 -Subject: [PATCH 11/16] pinctrl: add a pincontrol driver for BCM6368 - -Add a pincontrol driver for BCM6368. BCM6368 allows muxing the first 32 -GPIOs onto alternative functions. Not all are documented. - -Signed-off-by: Jonas Gorski ---- - drivers/pinctrl/bcm63xx/Kconfig | 15 + - drivers/pinctrl/bcm63xx/Makefile | 1 + - drivers/pinctrl/bcm63xx/pinctrl-bcm6368.c | 573 ++++++++++++++++++++++++++++++ - 3 files changed, 589 insertions(+) - create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6368.c - ---- a/drivers/pinctrl/bcm63xx/Kconfig -+++ b/drivers/pinctrl/bcm63xx/Kconfig -@@ -23,3 +23,11 @@ config PINCTRL_BCM6362 - select PINCONF - select PINCTRL_BCM63XX - select GENERIC_PINCONF -+ -+config PINCTRL_BCM6368 -+ bool "BCM6368 pincontrol driver" -+ select PINMUX -+ select PINCONF -+ select PINCTRL_BCM63XX -+ select GENERIC_PINCONF -+ select MFD_SYSCON ---- a/drivers/pinctrl/bcm63xx/Makefile -+++ b/drivers/pinctrl/bcm63xx/Makefile -@@ -2,3 +2,4 @@ obj-$(CONFIG_PINCTRL_BCM63XX) += pinctrl - 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 ---- /dev/null -+++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm6368.c -@@ -0,0 +1,570 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2016 Jonas Gorski -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "../core.h" -+#include "../pinctrl-utils.h" -+ -+#include "pinctrl-bcm63xx.h" -+ -+#define BCM6368_NGPIO 38 -+ -+#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_pinctrl { -+ struct pinctrl_dev *pctldev; -+ struct pinctrl_desc desc; -+ -+ void __iomem *mode; -+ struct regmap_field *overlay; -+ -+ /* register access lock */ -+ spinlock_t lock; -+ -+ struct gpio_chip gpio[2]; -+}; -+ -+#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 void bcm6368_rmw_mux(struct bcm6368_pinctrl *pctl, void __iomem *reg, -+ u32 mask, u32 val) -+{ -+ u32 tmp; -+ -+ tmp = __raw_readl(reg); -+ tmp &= ~mask; -+ tmp |= (val & mask); -+ __raw_writel(tmp, reg); -+} -+ -+static int bcm6368_pinctrl_set_mux(struct pinctrl_dev *pctldev, -+ unsigned selector, unsigned group) -+{ -+ struct bcm6368_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); -+ const struct bcm6368_pingroup *grp = &bcm6368_groups[group]; -+ const struct bcm6368_function *fun = &bcm6368_funcs[selector]; -+ unsigned long flags; -+ int i, pin; -+ -+ spin_lock_irqsave(&pctl->lock, flags); -+ if (fun->basemode) { -+ u32 mask = 0; -+ -+ for (i = 0; i < grp->num_pins; i++) { -+ pin = grp->pins[i]; -+ if (pin < 32) -+ mask |= BIT(pin); -+ } -+ -+ bcm6368_rmw_mux(pctl, pctl->mode, mask, 0); -+ regmap_field_write(pctl->overlay, fun->basemode); -+ } else { -+ pin = grp->pins[0]; -+ -+ if (bcm6368_pins[pin].drv_data) -+ regmap_field_write(pctl->overlay, -+ BCM6368_BASEMODE_GPIO); -+ -+ bcm6368_rmw_mux(pctl, pctl->mode, BIT(pin), BIT(pin)); -+ } -+ spin_unlock_irqrestore(&pctl->lock, flags); -+ -+ for (pin = 0; pin < grp->num_pins; pin++) { -+ int hw_gpio = bcm6368_pins[pin].number; -+ struct gpio_chip *gc = &pctl->gpio[hw_gpio / 32]; -+ -+ if (fun->dir_out & BIT(pin)) -+ gc->direction_output(gc, hw_gpio % 32, 0); -+ else -+ gc->direction_input(gc, hw_gpio % 32); -+ } -+ -+ return 0; -+} -+ -+static int bcm6368_gpio_request_enable(struct pinctrl_dev *pctldev, -+ struct pinctrl_gpio_range *range, -+ unsigned offset) -+{ -+ struct bcm6368_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); -+ unsigned long flags; -+ -+ if (offset >= 32 && !bcm6368_pins[offset].drv_data) -+ return 0; -+ -+ spin_lock_irqsave(&pctl->lock, flags); -+ /* disable all functions using this pin */ -+ if (offset < 32) -+ bcm6368_rmw_mux(pctl, pctl->mode, BIT(offset), 0); -+ -+ if (bcm6368_pins[offset].drv_data) -+ regmap_field_write(pctl->overlay, BCM6368_BASEMODE_GPIO); -+ -+ spin_unlock_irqrestore(&pctl->lock, flags); -+ -+ return 0; -+} -+ -+static struct pinctrl_ops bcm6368_pctl_ops = { -+ .get_groups_count = bcm6368_pinctrl_get_group_count, -+ .get_group_name = bcm6368_pinctrl_get_group_name, -+ .get_group_pins = bcm6368_pinctrl_get_group_pins, -+#ifdef CONFIG_OF -+ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, -+ .dt_free_map = pinctrl_utils_free_map, -+#endif -+}; -+ -+static struct pinmux_ops bcm6368_pmx_ops = { -+ .get_functions_count = bcm6368_pinctrl_get_func_count, -+ .get_function_name = bcm6368_pinctrl_get_func_name, -+ .get_function_groups = bcm6368_pinctrl_get_groups, -+ .set_mux = bcm6368_pinctrl_set_mux, -+ .gpio_request_enable = bcm6368_gpio_request_enable, -+ .strict = true, -+}; -+ -+static int bcm6368_pinctrl_probe(struct platform_device *pdev) -+{ -+ struct bcm6368_pinctrl *pctl; -+ struct resource *res; -+ void __iomem *mode; -+ struct regmap *basemode; -+ struct reg_field overlay = REG_FIELD(0, 0, 3); -+ -+ basemode = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, -+ "brcm,gpiobasemode"); -+ -+ if (IS_ERR(basemode)) -+ return PTR_ERR(basemode); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode"); -+ mode = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(mode)) -+ return PTR_ERR(mode); -+ -+ pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL); -+ if (!pctl) -+ return -ENOMEM; -+ -+ pctl->overlay = devm_regmap_field_alloc(&pdev->dev, basemode, overlay); -+ if (IS_ERR(pctl->overlay)) -+ return PTR_ERR(pctl->overlay); -+ -+ spin_lock_init(&pctl->lock); -+ -+ pctl->mode = mode; -+ -+ /* disable all muxes by default */ -+ __raw_writel(0, pctl->mode); -+ -+ pctl->desc.name = dev_name(&pdev->dev); -+ pctl->desc.owner = THIS_MODULE; -+ pctl->desc.pctlops = &bcm6368_pctl_ops; -+ pctl->desc.pmxops = &bcm6368_pmx_ops; -+ -+ pctl->desc.npins = ARRAY_SIZE(bcm6368_pins); -+ pctl->desc.pins = bcm6368_pins; -+ -+ platform_set_drvdata(pdev, pctl); -+ -+ pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl, -+ pctl->gpio, BCM6368_NGPIO); -+ if (IS_ERR(pctl->pctldev)) -+ return PTR_ERR(pctl->pctldev); -+ -+ return 0; -+} -+ -+static const struct of_device_id bcm6368_pinctrl_match[] = { -+ { .compatible = "brcm,bcm6368-pinctrl", }, -+ { }, -+}; -+ -+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/target/linux/bmips/patches-5.10/409-Documentation-add-BCM63268-pincontroller-binding-doc.patch b/target/linux/bmips/patches-5.10/409-Documentation-add-BCM63268-pincontroller-binding-doc.patch deleted file mode 100644 index ffe842fd73..0000000000 --- a/target/linux/bmips/patches-5.10/409-Documentation-add-BCM63268-pincontroller-binding-doc.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 28cc80e4ada5d73d5305fd268297825cd8d01936 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Wed, 27 Jul 2016 11:37:08 +0200 -Subject: [PATCH 12/16] Documentation: add BCM63268 pincontroller binding - documentation - -Add binding documentation for the pincontrol core found in the BCM63268 -family SoCs. - -Signed-off-by: Jonas Gorski ---- - .../bindings/pinctrl/brcm,bcm63268-pinctrl.txt | 88 ++++++++++++++++++++++ - 1 file changed, 88 insertions(+) - create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.txt - ---- /dev/null -+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.txt -@@ -0,0 +1,88 @@ -+* Broadcom BCM63268 pin controller -+ -+Required properties: -+- compatible: Must be "brcm,bcm6362-pinctrl". -+- reg: Register specifiers of dirout, dat, led, mode, ctrl, basemode registers. -+- reg-names: Must be "dirout", "dat", "led", "mode", "ctrl", "basemode". -+- gpio-controller: Identifies this node as a GPIO controller. -+- #gpio-cells: Must be <2>. -+ -+Example: -+ -+pinctrl: pin-controller@100000c0 { -+ compatible = "brcm,bcm63268-pinctrl"; -+ reg = <0x100000c0 0x8>, -+ <0x100000c8 0x8>, -+ <0x100000d0 0x4>, -+ <0x100000d8 0x4>, -+ <0x100000dc 0x4>, -+ <0x100000f8 0x4>; -+ reg-names = "dirout", "dat", "led", "mode", -+ "ctrl", "basemode"; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+}; -+ -+Available pins/groups and functions: -+ -+name pins functions -+----------------------------------------------------------- -+gpio0 0 led, serial_led_clk -+gpio1 1 led, serial_led_data -+gpio2 2 led, -+gpio3 3 led, -+gpio4 4 led, -+gpio5 5 led, -+gpio6 6 led, -+gpio7 7 led, -+gpio8 8 led, hsspi_cs6 -+gpio9 9 led, hsspi_cs7 -+gpio10 10 led, uart1_scts -+gpio11 11 led, uart1_srts -+gpio12 12 led, uart1_sdin -+gpio13 13 led, uart1_sdout -+gpio14 14 led, ntr_pulse_in -+gpio15 15 led, dsl_ntr_pulse_out -+gpio16 16 led, hsspi_cs4 -+gpio17 17 led, hsspi_cs5 -+gpio18 18 led, adsl_spi_miso -+gpio19 19 led, adsl_spi_mosi -+gpio20 20 led, -+gpio21 21 led, -+gpio22 22 led, vreg_clk -+gpio23 23 led, pcie_clkreq_b -+gpio24 24 uart1_scts -+gpio25 25 uart1_srts -+gpio26 26 uart1_sdin -+gpio27 27 uart1_sdout -+gpio28 28 ntr_pulse_in -+gpio29 29 dsl_ntr_pulse_out -+gpio30 30 switch_led_clk -+gpio31 31 switch_led_data -+gpio32 32 wifi -+gpio33 33 wifi -+gpio34 34 wifi -+gpio35 35 wifi -+gpio36 36 wifi -+gpio37 37 wifi -+gpio38 38 wifi -+gpio39 39 wifi -+gpio40 40 wifi -+gpio41 41 wifi -+gpio42 42 wifi -+gpio43 43 wifi -+gpio44 44 wifi -+gpio45 45 wifi -+gpio46 46 wifi -+gpio47 47 wifi -+gpio48 48 wifi -+gpio49 49 wifi -+gpio50 50 wifi -+gpio51 51 wifi -+nand_grp 2-7,24-31 nand -+dect_pd_grp 8-9 dect_pd -+vdsl_phy0_grp 10-11 vdsl_phy0 -+vdsl_phy1_grp 12-13 vdsl_phy1 -+vdsl_phy2_grp 24-25 vdsl_phy2 -+vdsl_phy3_grp 26-27 vdsl_phy3 diff --git a/target/linux/bmips/patches-5.10/409-pinctrl-add-a-pincontrol-driver-for-BCM63268.patch b/target/linux/bmips/patches-5.10/409-pinctrl-add-a-pincontrol-driver-for-BCM63268.patch new file mode 100644 index 0000000000..8acc5dbfbb --- /dev/null +++ b/target/linux/bmips/patches-5.10/409-pinctrl-add-a-pincontrol-driver-for-BCM63268.patch @@ -0,0 +1,875 @@ +From 8ec959299a6e4bbdc65d62180aa952ae04cdcf07 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= +Date: Fri, 24 Jun 2016 22:19:12 +0200 +Subject: [PATCH 10/12] pinctrl: add a pincontrol driver for BCM63268 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add a pincontrol driver for BCM63268. BCM63268 allows muxing GPIOs +to different functions. Depending on the mux, these are either single +pin configurations or whole pin groups. + +Signed-off-by: Álvaro Fernández Rojas +Signed-off-by: Jonas Gorski +--- + drivers/pinctrl/bcm/Kconfig | 11 + + drivers/pinctrl/bcm/Makefile | 1 + + drivers/pinctrl/bcm/pinctrl-bcm63268.c | 821 +++++++++++++++++++++++++ + 3 files changed, 833 insertions(+) + create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63268.c + +--- a/drivers/pinctrl/bcm/Kconfig ++++ b/drivers/pinctrl/bcm/Kconfig +@@ -73,6 +73,17 @@ config PINCTRL_BCM6368 + help + Say Y here to enable the Broadcom BCM6368 GPIO driver. + ++config PINCTRL_BCM63268 ++ bool "Broadcom BCM63268 GPIO driver" ++ depends on OF_GPIO && (BMIPS_GENERIC || COMPILE_TEST) ++ select PINMUX ++ select PINCONF ++ select GENERIC_PINCONF ++ select MFD_SYSCON ++ 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) +--- a/drivers/pinctrl/bcm/Makefile ++++ b/drivers/pinctrl/bcm/Makefile +@@ -7,6 +7,7 @@ obj-$(CONFIG_PINCTRL_BCM6328) += pinctr + 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 +--- /dev/null ++++ b/drivers/pinctrl/bcm/pinctrl-bcm63268.c +@@ -0,0 +1,821 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Driver for BCM63268 GPIO unit (pinctrl + GPIO) ++ * ++ * Copyright (C) 2021 Álvaro Fernández Rojas ++ * Copyright (C) 2016 Jonas Gorski ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include "../core.h" ++#include "../pinctrl-utils.h" ++ ++#define MODULE_NAME "bcm63268-pinctrl" ++#define BCM63268_NUM_GPIOS 52 ++#define BCM63268_NUM_LEDS 24 ++ ++#define BANK_SIZE sizeof(uint32_t) ++#define PINS_PER_BANK (BANK_SIZE * BITS_PER_BYTE) ++ ++#define BCM63268_DIROUT_REG 0x04 ++#define BCM63268_DATA_REG 0x0c ++#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; ++}; ++ ++struct bcm63268_pinctrl { ++ struct device *dev; ++ struct regmap *regs; ++ ++ struct pinctrl_dev *pctl_dev; ++ struct gpio_chip gpio_chip; ++ struct pinctrl_desc pctl_desc; ++ struct pinctrl_gpio_range gpio_range; ++}; ++ ++#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 inline unsigned int bcm63268_bank_pin(unsigned int pin) ++{ ++ return pin % PINS_PER_BANK; ++} ++ ++static inline unsigned int bcm63268_reg_off(unsigned int reg, unsigned int pin) ++{ ++ return reg - (pin / PINS_PER_BANK) * BANK_SIZE; ++} ++ ++static int bcm63268_gpio_direction_input(struct gpio_chip *chip, ++ unsigned int pin) ++{ ++ struct bcm63268_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int dirout = bcm63268_reg_off(BCM63268_DIROUT_REG, pin); ++ unsigned int bank_pin = bcm63268_bank_pin(pin); ++ int ret; ++ ++ /* ++ * Check with the pinctrl driver whether this pin is usable as ++ * an input GPIO ++ */ ++ ret = pinctrl_gpio_direction_input(chip->base + pin); ++ if (ret) ++ return ret; ++ ++ regmap_update_bits(pc->regs, dirout, BIT(bank_pin), 0); ++ ++ return 0; ++} ++ ++static int bcm63268_gpio_direction_output(struct gpio_chip *chip, ++ unsigned int pin, int value) ++{ ++ struct bcm63268_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int data = bcm63268_reg_off(BCM63268_DATA_REG, pin); ++ unsigned int dirout = bcm63268_reg_off(BCM63268_DIROUT_REG, pin); ++ unsigned int bank_pin = bcm63268_bank_pin(pin); ++ unsigned int val = value ? BIT(bank_pin) : 0; ++ int ret; ++ ++ /* ++ * Check with the pinctrl driver whether this pin is usable as ++ * an output GPIO ++ */ ++ ret = pinctrl_gpio_direction_output(chip->base + pin); ++ if (ret) ++ return ret; ++ ++ regmap_update_bits(pc->regs, dirout, BIT(bank_pin), BIT(bank_pin)); ++ regmap_update_bits(pc->regs, data, BIT(bank_pin), val); ++ ++ return 0; ++} ++ ++static int bcm63268_gpio_get(struct gpio_chip *chip, unsigned int pin) ++{ ++ struct bcm63268_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int data = bcm63268_reg_off(BCM63268_DATA_REG, pin); ++ unsigned int bank_pin = bcm63268_bank_pin(pin); ++ unsigned int val; ++ ++ regmap_read(pc->regs, data, &val); ++ ++ return !!(val & BIT(bank_pin)); ++} ++ ++static int bcm63268_gpio_get_direction(struct gpio_chip *chip, unsigned int pin) ++{ ++ struct bcm63268_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int dirout = bcm63268_reg_off(BCM63268_DIROUT_REG, pin); ++ unsigned int bank_pin = bcm63268_bank_pin(pin); ++ unsigned int val; ++ ++ regmap_read(pc->regs, dirout, &val); ++ ++ if (val & BIT(bank_pin)) ++ return GPIO_LINE_DIRECTION_OUT; ++ ++ return GPIO_LINE_DIRECTION_IN; ++} ++ ++static void bcm63268_gpio_set(struct gpio_chip *chip, unsigned int pin, ++ int value) ++{ ++ struct bcm63268_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int data = bcm63268_reg_off(BCM63268_DATA_REG, pin); ++ unsigned int bank_pin = bcm63268_bank_pin(pin); ++ unsigned int val = value ? BIT(bank_pin) : 0; ++ ++ regmap_update_bits(pc->regs, data, BIT(bank_pin), val); ++} ++ ++static int bcm63268_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) ++{ ++ char irq_name[7]; ++ ++ sprintf(irq_name, "gpio%d", gpio); ++ ++ return of_irq_get_byname(chip->of_node, irq_name); ++} ++ ++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 bcm63268_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(bcm63268_bank_pin(pin)); ++ ++ if (basemode) ++ regmap_update_bits(pc->regs, BCM63268_BASEMODE_REG, basemode, ++ 0); ++ ++ if (pin < PINS_PER_BANK) { ++ /* 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 bcm63268_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 bcm63268_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 = { ++ .get_groups_count = bcm63268_pinctrl_get_group_count, ++ .get_group_name = bcm63268_pinctrl_get_group_name, ++ .get_group_pins = bcm63268_pinctrl_get_group_pins, ++ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, ++ .dt_free_map = pinctrl_utils_free_map, ++}; ++ ++static struct pinmux_ops bcm63268_pmx_ops = { ++ .get_functions_count = bcm63268_pinctrl_get_func_count, ++ .get_function_name = bcm63268_pinctrl_get_func_name, ++ .get_function_groups = bcm63268_pinctrl_get_groups, ++ .set_mux = bcm63268_pinctrl_set_mux, ++ .gpio_request_enable = bcm63268_gpio_request_enable, ++ .strict = true, ++}; ++ ++static int bcm63268_pinctrl_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *np = dev->of_node; ++ struct bcm63268_pinctrl *pc; ++ int err; ++ ++ pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); ++ if (!pc) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, pc); ++ pc->dev = dev; ++ ++ pc->regs = syscon_node_to_regmap(dev->parent->of_node); ++ if (IS_ERR(pc->regs)) ++ return PTR_ERR(pc->regs); ++ ++ pc->gpio_chip.label = MODULE_NAME; ++ pc->gpio_chip.owner = THIS_MODULE; ++ pc->gpio_chip.request = gpiochip_generic_request; ++ pc->gpio_chip.free = gpiochip_generic_free; ++ pc->gpio_chip.direction_input = bcm63268_gpio_direction_input; ++ pc->gpio_chip.direction_output = bcm63268_gpio_direction_output; ++ pc->gpio_chip.get_direction = bcm63268_gpio_get_direction; ++ pc->gpio_chip.get = bcm63268_gpio_get; ++ pc->gpio_chip.set = bcm63268_gpio_set; ++ pc->gpio_chip.set_config = gpiochip_generic_config; ++ pc->gpio_chip.base = -1; ++ pc->gpio_chip.ngpio = BCM63268_NUM_GPIOS; ++ pc->gpio_chip.can_sleep = false; ++ pc->gpio_chip.parent = dev; ++ pc->gpio_chip.of_node = np; ++ ++ if (of_get_property(np, "interrupt-names", NULL)) ++ pc->gpio_chip.to_irq = bcm63268_gpio_to_irq; ++ ++ err = gpiochip_add_data(&pc->gpio_chip, pc); ++ if (err) { ++ dev_err(dev, "could not add GPIO chip\n"); ++ return err; ++ } ++ ++ pc->pctl_desc.name = MODULE_NAME, ++ pc->pctl_desc.pins = bcm63268_pins, ++ pc->pctl_desc.npins = ARRAY_SIZE(bcm63268_pins), ++ pc->pctl_desc.pctlops = &bcm63268_pctl_ops, ++ pc->pctl_desc.pmxops = &bcm63268_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)) { ++ gpiochip_remove(&pc->gpio_chip); ++ return PTR_ERR(pc->pctl_dev); ++ } ++ ++ pc->gpio_range.name = MODULE_NAME; ++ pc->gpio_range.npins = BCM63268_NUM_GPIOS; ++ pc->gpio_range.base = pc->gpio_chip.base; ++ pc->gpio_range.gc = &pc->gpio_chip; ++ pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range); ++ ++ dev_info(dev, "registered\n"); ++ ++ return 0; ++} ++ ++static const struct of_device_id bcm63268_pinctrl_match[] = { ++ { .compatible = "brcm,bcm63268-pinctrl", }, ++ { }, ++}; ++ ++static struct platform_driver bcm63268_pinctrl_driver = { ++ .probe = bcm63268_pinctrl_probe, ++ .driver = { ++ .name = MODULE_NAME, ++ .of_match_table = bcm63268_pinctrl_match, ++ }, ++}; ++ ++builtin_platform_driver(bcm63268_pinctrl_driver); diff --git a/target/linux/bmips/patches-5.10/410-Documentation-add-BCM6318-pincontroller-binding-docu.patch b/target/linux/bmips/patches-5.10/410-Documentation-add-BCM6318-pincontroller-binding-docu.patch new file mode 100644 index 0000000000..6577038756 --- /dev/null +++ b/target/linux/bmips/patches-5.10/410-Documentation-add-BCM6318-pincontroller-binding-docu.patch @@ -0,0 +1,194 @@ +From f909bf5d5cf3db6b35c082f27f7982dfcb1447c2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= +Date: Wed, 27 Jul 2016 11:38:05 +0200 +Subject: [PATCH 11/12] Documentation: add BCM6318 pincontroller binding + documentation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add binding documentation for the pincontrol core found in BCM6318 SoCs. + +Signed-off-by: Álvaro Fernández Rojas +Signed-off-by: Jonas Gorski +--- + .../pinctrl/brcm,bcm6318-pinctrl.yaml | 173 ++++++++++++++++++ + 1 file changed, 173 insertions(+) + create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml + +--- /dev/null ++++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml +@@ -0,0 +1,173 @@ ++# 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 ++ - Jonas Gorski ++ ++description: |+ ++ The pin controller node should be the child of a syscon node. ++ ++ Refer to the the bindings described in ++ Documentation/devicetree/bindings/mfd/syscon.yaml ++ ++properties: ++ compatible: ++ const: brcm,bcm6318-pinctrl ++ ++ gpio-controller: true ++ ++ '#gpio-cells': ++ description: ++ Specifies the pin number and flags, as defined in ++ include/dt-bindings/gpio/gpio.h ++ const: 2 ++ ++ interrupts-extended: ++ description: ++ One interrupt per each of the 2 GPIO ports supported by the controller, ++ sorted by port number ascending order. ++ minItems: 2 ++ maxItems: 2 ++ ++patternProperties: ++ '^.*$': ++ if: ++ type: object ++ then: ++ properties: ++ function: ++ $ref: "/schemas/types.yaml#/definitions/string" ++ 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: ++ $ref: "/schemas/types.yaml#/definitions/string" ++ enum: [ gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7, ++ gpio8, gpio9, gpio10, gpio11, gpio12, gpio13, gpio40 ] ++ ++required: ++ - compatible ++ - gpio-controller ++ - '#gpio-cells' ++ ++additionalProperties: false ++ ++examples: ++ - | ++ gpio@10000080 { ++ compatible = "syscon", "simple-mfd"; ++ reg = <0x10000080 0x80>; ++ ++ pinctrl: pinctrl { ++ compatible = "brcm,bcm6318-pinctrl"; ++ ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ interrupts-extended = <&ext_intc 0 0>, ++ <&ext_intc 1 0>; ++ interrupt-names = "gpio33", ++ "gpio34"; ++ ++ pinctrl_ephy0_spd_led: ephy0_spd_led { ++ function = "ephy0_spd_led"; ++ pins = "gpio0"; ++ }; ++ ++ pinctrl_ephy1_spd_led: ephy1_spd_led { ++ function = "ephy1_spd_led"; ++ pins = "gpio1"; ++ }; ++ ++ pinctrl_ephy2_spd_led: ephy2_spd_led { ++ function = "ephy2_spd_led"; ++ pins = "gpio2"; ++ }; ++ ++ pinctrl_ephy3_spd_led: ephy3_spd_led { ++ function = "ephy3_spd_led"; ++ pins = "gpio3"; ++ }; ++ ++ pinctrl_ephy0_act_led: ephy0_act_led { ++ function = "ephy0_act_led"; ++ pins = "gpio4"; ++ }; ++ ++ pinctrl_ephy1_act_led: ephy1_act_led { ++ function = "ephy1_act_led"; ++ pins = "gpio5"; ++ }; ++ ++ pinctrl_ephy2_act_led: ephy2_act_led { ++ function = "ephy2_act_led"; ++ pins = "gpio6"; ++ }; ++ ++ pinctrl_ephy3_act_led: ephy3_act_led { ++ function = "ephy3_act_led"; ++ pins = "gpio7"; ++ }; ++ ++ pinctrl_serial_led: serial_led { ++ pinctrl_serial_led_data: serial_led_data { ++ function = "serial_led_data"; ++ pins = "gpio6"; ++ }; ++ ++ pinctrl_serial_led_clk: serial_led_clk { ++ function = "serial_led_clk"; ++ pins = "gpio7"; ++ }; ++ }; ++ ++ pinctrl_inet_act_led: inet_act_led { ++ function = "inet_act_led"; ++ pins = "gpio8"; ++ }; ++ ++ pinctrl_inet_fail_led: inet_fail_led { ++ function = "inet_fail_led"; ++ pins = "gpio9"; ++ }; ++ ++ pinctrl_dsl_led: dsl_led { ++ function = "dsl_led"; ++ pins = "gpio10"; ++ }; ++ ++ pinctrl_post_fail_led: post_fail_led { ++ function = "post_fail_led"; ++ pins = "gpio11"; ++ }; ++ ++ pinctrl_wlan_wps_led: wlan_wps_led { ++ function = "wlan_wps_led"; ++ pins = "gpio12"; ++ }; ++ ++ pinctrl_usb_pwron: usb_pwron { ++ function = "usb_pwron"; ++ pins = "gpio13"; ++ }; ++ ++ pinctrl_usb_device_led: usb_device_led { ++ function = "usb_device_led"; ++ pins = "gpio13"; ++ }; ++ ++ pinctrl_usb_active: usb_active { ++ function = "usb_active"; ++ pins = "gpio40"; ++ }; ++ }; ++ }; diff --git a/target/linux/bmips/patches-5.10/410-pinctrl-add-a-pincontrol-driver-for-BCM63268.patch b/target/linux/bmips/patches-5.10/410-pinctrl-add-a-pincontrol-driver-for-BCM63268.patch deleted file mode 100644 index 1607f23061..0000000000 --- a/target/linux/bmips/patches-5.10/410-pinctrl-add-a-pincontrol-driver-for-BCM63268.patch +++ /dev/null @@ -1,749 +0,0 @@ -From 8665d3ea63649cc155286c75f83f694a930580e5 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Fri, 24 Jun 2016 22:19:12 +0200 -Subject: [PATCH 13/16] pinctrl: add a pincontrol driver for BCM63268 - -Add a pincontrol driver for BCM63268. BCM63268 allows muxing GPIOs -to different functions. Depending on the mux, these are either single -pin configurations or whole pin groups. - -Signed-off-by: Jonas Gorski ---- - drivers/pinctrl/bcm63xx/Makefile | 1 + - drivers/pinctrl/bcm63xx/pinctrl-bcm63268.c | 710 +++++++++++++++++++++++++++++ - 2 files changed, 711 insertions(+) - create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm63268.c - ---- a/drivers/pinctrl/bcm63xx/Kconfig -+++ b/drivers/pinctrl/bcm63xx/Kconfig -@@ -31,3 +31,10 @@ config PINCTRL_BCM6368 - select PINCTRL_BCM63XX - select GENERIC_PINCONF - select MFD_SYSCON -+ -+config PINCTRL_BCM63268 -+ bool "BCM63268 pincontrol driver" -+ select PINMUX -+ select PINCONF -+ select PINCTRL_BCM63XX -+ select GENERIC_PINCONF ---- a/drivers/pinctrl/bcm63xx/Makefile -+++ b/drivers/pinctrl/bcm63xx/Makefile -@@ -3,3 +3,4 @@ obj-$(CONFIG_PINCTRL_BCM6328) += pinctrl - 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 ---- /dev/null -+++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm63268.c -@@ -0,0 +1,710 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2016 Jonas Gorski -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "../core.h" -+#include "../pinctrl-utils.h" -+ -+#include "pinctrl-bcm63xx.h" -+ -+#define BCM63268_NGPIO 52 -+ -+/* GPIO_BASEMODE register */ -+#define BASEMODE_NAND BIT(2) /* GPIOs 2-7, 24-31 */ -+#define BASEMODE_GPIO35 BIT(4) /* GPIO 35 */ -+#define BASEMODE_DECTPD BIT(5) /* GPIOs 8/9 */ -+#define BASEMODE_VDSL_PHY_0 BIT(6) /* GPIOs 10/11 */ -+#define BASEMODE_VDSL_PHY_1 BIT(7) /* GPIOs 12/13 */ -+#define BASEMODE_VDSL_PHY_2 BIT(8) /* GPIOs 24/25 */ -+#define 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; -+ u32 mask; -+}; -+ -+struct bcm63268_pinctrl { -+ struct pinctrl_dev *pctldev; -+ struct pinctrl_desc desc; -+ -+ void __iomem *led; -+ void __iomem *mode; -+ void __iomem *ctrl; -+ void __iomem *basemode; -+ -+ /* register access lock */ -+ spinlock_t lock; -+ -+ struct gpio_chip gpio[2]; -+}; -+ -+#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", BASEMODE_NAND), -+ BCM63268_PIN(3, "gpio3", BASEMODE_NAND), -+ BCM63268_PIN(4, "gpio4", BASEMODE_NAND), -+ BCM63268_PIN(5, "gpio5", BASEMODE_NAND), -+ BCM63268_PIN(6, "gpio6", BASEMODE_NAND), -+ BCM63268_PIN(7, "gpio7", BASEMODE_NAND), -+ BCM63268_PIN(8, "gpio8", BASEMODE_DECTPD), -+ BCM63268_PIN(9, "gpio9", BASEMODE_DECTPD), -+ BCM63268_PIN(10, "gpio10", BASEMODE_VDSL_PHY_0), -+ BCM63268_PIN(11, "gpio11", BASEMODE_VDSL_PHY_0), -+ BCM63268_PIN(12, "gpio12", BASEMODE_VDSL_PHY_1), -+ BCM63268_PIN(13, "gpio13", 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", BASEMODE_NAND | BASEMODE_VDSL_PHY_2), -+ BCM63268_PIN(25, "gpio25", BASEMODE_NAND | BASEMODE_VDSL_PHY_2), -+ BCM63268_PIN(26, "gpio26", BASEMODE_NAND | BASEMODE_VDSL_PHY_3), -+ BCM63268_PIN(27, "gpio27", BASEMODE_NAND | BASEMODE_VDSL_PHY_3), -+ BCM63268_PIN(28, "gpio28", BASEMODE_NAND), -+ BCM63268_PIN(29, "gpio29", BASEMODE_NAND), -+ BCM63268_PIN(30, "gpio30", BASEMODE_NAND), -+ BCM63268_PIN(31, "gpio31", 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, BASEMODE_NAND), -+ BCM63268_BASEMODE_FUN(dectpd, BASEMODE_DECTPD), -+ BCM63268_BASEMODE_FUN(vdsl_phy_override_0, BASEMODE_VDSL_PHY_0), -+ BCM63268_BASEMODE_FUN(vdsl_phy_override_1, BASEMODE_VDSL_PHY_1), -+ BCM63268_BASEMODE_FUN(vdsl_phy_override_2, BASEMODE_VDSL_PHY_2), -+ BCM63268_BASEMODE_FUN(vdsl_phy_override_3, 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_rmw_mux(struct bcm63268_pinctrl *pctl, void __iomem *reg, -+ u32 mask, u32 val) -+{ -+ unsigned long flags; -+ u32 tmp; -+ -+ spin_lock_irqsave(&pctl->lock, flags); -+ tmp = __raw_readl(reg); -+ tmp &= ~mask; -+ tmp |= val; -+ __raw_writel(tmp, reg); -+ -+ spin_unlock_irqrestore(&pctl->lock, flags); -+} -+ -+static void bcm63268_set_gpio(struct bcm63268_pinctrl *pctl, unsigned pin) -+{ -+ const struct pinctrl_pin_desc *desc = &bcm63268_pins[pin]; -+ u32 basemode = (unsigned long)desc->drv_data; -+ u32 mask = BIT(pin % 32); -+ -+ if (basemode) -+ bcm63268_rmw_mux(pctl, pctl->basemode, basemode, 0); -+ -+ if (pin < 32) { -+ /* base mode: 0 => gpio, 1 => mux function */ -+ bcm63268_rmw_mux(pctl, pctl->mode, mask, 0); -+ -+ /* pins 0-23 might be muxed to led */ -+ if (pin < 24) -+ bcm63268_rmw_mux(pctl, pctl->led, mask, 0); -+ } else if (pin < 52) { -+ /* ctrl reg: 0 => wifi function, 1 => gpio */ -+ bcm63268_rmw_mux(pctl, pctl->ctrl, mask, mask); -+ } -+} -+ -+static int bcm63268_pinctrl_set_mux(struct pinctrl_dev *pctldev, -+ unsigned selector, unsigned group) -+{ -+ struct bcm63268_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); -+ const struct bcm63268_pingroup *grp = &bcm63268_groups[group]; -+ const struct bcm63268_function *f = &bcm63268_funcs[selector]; -+ unsigned i; -+ void __iomem *reg; -+ u32 val, mask; -+ -+ for (i = 0; i < grp->num_pins; i++) -+ bcm63268_set_gpio(pctl, grp->pins[i]); -+ -+ switch (f->reg) { -+ case BCM63268_LEDCTRL: -+ reg = pctl->led; -+ mask = BIT(grp->pins[0]); -+ val = BIT(grp->pins[0]); -+ break; -+ case BCM63268_MODE: -+ reg = pctl->mode; -+ mask = BIT(grp->pins[0]); -+ val = BIT(grp->pins[0]); -+ break; -+ case BCM63268_CTRL: -+ reg = pctl->ctrl; -+ mask = BIT(grp->pins[0]); -+ val = 0; -+ break; -+ case BCM63268_BASEMODE: -+ reg = pctl->basemode; -+ mask = f->mask; -+ val = f->mask; -+ break; -+ default: -+ WARN_ON(1); -+ return -EINVAL; -+ } -+ -+ bcm63268_rmw_mux(pctl, reg, mask, val); -+ -+ return 0; -+} -+ -+static int bcm63268_gpio_request_enable(struct pinctrl_dev *pctldev, -+ struct pinctrl_gpio_range *range, -+ unsigned offset) -+{ -+ struct bcm63268_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); -+ -+ /* disable all functions using this pin */ -+ bcm63268_set_gpio(pctl, offset); -+ -+ return 0; -+} -+ -+static struct pinctrl_ops bcm63268_pctl_ops = { -+ .get_groups_count = bcm63268_pinctrl_get_group_count, -+ .get_group_name = bcm63268_pinctrl_get_group_name, -+ .get_group_pins = bcm63268_pinctrl_get_group_pins, -+#ifdef CONFIG_OF -+ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, -+ .dt_free_map = pinctrl_utils_free_map, -+#endif -+}; -+ -+static struct pinmux_ops bcm63268_pmx_ops = { -+ .get_functions_count = bcm63268_pinctrl_get_func_count, -+ .get_function_name = bcm63268_pinctrl_get_func_name, -+ .get_function_groups = bcm63268_pinctrl_get_groups, -+ .set_mux = bcm63268_pinctrl_set_mux, -+ .gpio_request_enable = bcm63268_gpio_request_enable, -+ .strict = true, -+}; -+ -+static int bcm63268_pinctrl_probe(struct platform_device *pdev) -+{ -+ struct bcm63268_pinctrl *pctl; -+ struct resource *res; -+ void __iomem *led, *mode, *ctrl, *basemode; -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "led"); -+ led = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(led)) -+ return PTR_ERR(led); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode"); -+ mode = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(mode)) -+ return PTR_ERR(mode); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl"); -+ ctrl = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(ctrl)) -+ return PTR_ERR(ctrl); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "basemode"); -+ basemode = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(basemode)) -+ return PTR_ERR(basemode); -+ -+ pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL); -+ if (!pctl) -+ return -ENOMEM; -+ -+ spin_lock_init(&pctl->lock); -+ -+ pctl->led = led; -+ pctl->mode = mode; -+ pctl->ctrl = ctrl; -+ pctl->basemode = basemode; -+ -+ pctl->desc.name = dev_name(&pdev->dev); -+ pctl->desc.owner = THIS_MODULE; -+ pctl->desc.pctlops = &bcm63268_pctl_ops; -+ pctl->desc.pmxops = &bcm63268_pmx_ops; -+ -+ pctl->desc.npins = ARRAY_SIZE(bcm63268_pins); -+ pctl->desc.pins = bcm63268_pins; -+ -+ platform_set_drvdata(pdev, pctl); -+ -+ pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl, -+ pctl->gpio, BCM63268_NGPIO); -+ if (IS_ERR(pctl->pctldev)) -+ return PTR_ERR(pctl->pctldev); -+ -+ return 0; -+} -+ -+static const struct of_device_id bcm63268_pinctrl_match[] = { -+ { .compatible = "brcm,bcm63268-pinctrl", }, -+ { }, -+}; -+ -+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/target/linux/bmips/patches-5.10/411-Documentation-add-BCM6318-pincontroller-binding-docu.patch b/target/linux/bmips/patches-5.10/411-Documentation-add-BCM6318-pincontroller-binding-docu.patch deleted file mode 100644 index 5d4265f7fe..0000000000 --- a/target/linux/bmips/patches-5.10/411-Documentation-add-BCM6318-pincontroller-binding-docu.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 8439e5d2e69f54a532bb5f8ec001b4b5a3035574 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Wed, 27 Jul 2016 11:38:05 +0200 -Subject: [PATCH 14/16] Documentation: add BCM6318 pincontroller binding - documentation - -Add binding documentation for the pincontrol core found in BCM6318 SoCs. - -Signed-off-by: Jonas Gorski ---- - .../bindings/pinctrl/brcm,bcm6318-pinctrl.txt | 79 ++++++++++++++++++++++ - 1 file changed, 79 insertions(+) - create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.txt - ---- /dev/null -+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.txt -@@ -0,0 +1,79 @@ -+* Broadcom BCM6318 pin controller -+ -+Required properties: -+- compatible: Must be "brcm,bcm6318-pinctrl". -+- regs: Register specifiers of dirout, dat, mode, mux, and pad registers. -+- reg-names: Must be "dirout", "dat", "mode", "mux", "pad". -+- gpio-controller: Identifies this node as a gpio controller. -+- #gpio-cells: Must be <2>. -+ -+Example: -+ -+pinctrl: pin-controller@10000080 { -+ compatible = "brcm,bcm6318-pinctrl"; -+ reg = <0x10000080 0x08>, -+ <0x10000088 0x08>, -+ <0x10000098 0x04>, -+ <0x1000009c 0x0c>, -+ <0x100000d4 0x18>; -+ reg-names = "dirout", "dat", "mode", "mux", "pad"; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+}; -+ -+ -+Available pins/groups and functions: -+ -+name pins functions -+----------------------------------------------------------- -+gpio0 0 led, ephy0_spd_led -+gpio1 1 led, ephy1_spd_led -+gpio2 2 led, ephy2_spd_led -+gpio3 3 led, ephy3_spd_led -+gpio4 4 led, ephy0_act_led -+gpio5 5 led, ephy1_act_led -+gpio6 6 led, ephy2_act_led, serial_led_data -+gpio7 7 led, ephy3_act_led, serial_led_clk -+gpio8 8 led, inet_act_led -+gpio9 9 led, inet_fail_led -+gpio10 10 led, dsl_led -+gpio11 11 led, post_fail_led -+gpio12 12 led, wlan_wps_led -+gpio13 13 led, usb_pwron, usb_device_led -+gpio14 14 led -+gpio15 15 led -+gpio16 16 led -+gpio17 17 led -+gpio18 18 led -+gpio19 19 led -+gpio20 20 led -+gpio21 21 led -+gpio22 22 led -+gpio23 23 led -+gpio24 24 - -+gpio25 25 - -+gpio26 26 - -+gpio27 27 - -+gpio28 28 - -+gpio29 29 - -+gpio30 30 - -+gpio31 31 - -+gpio32 32 - -+gpio33 33 - -+gpio34 34 - -+gpio35 35 - -+gpio36 36 - -+gpio37 37 - -+gpio38 38 - -+gpio39 39 - -+gpio40 40 usb_active -+gpio41 41 - -+gpio42 42 - -+gpio43 43 - -+gpio44 44 - -+gpio45 45 - -+gpio46 46 - -+gpio47 47 - -+gpio48 48 - -+gpio49 49 - diff --git a/target/linux/bmips/patches-5.10/411-pinctrl-add-a-pincontrol-driver-for-BCM6318.patch b/target/linux/bmips/patches-5.10/411-pinctrl-add-a-pincontrol-driver-for-BCM6318.patch new file mode 100644 index 0000000000..b57b49d35f --- /dev/null +++ b/target/linux/bmips/patches-5.10/411-pinctrl-add-a-pincontrol-driver-for-BCM6318.patch @@ -0,0 +1,729 @@ +From e1764f96eb563a11c822ff91d1c6d7ed01c3925b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= +Date: Fri, 24 Jun 2016 22:20:39 +0200 +Subject: [PATCH 12/12] pinctrl: add a pincontrol driver for BCM6318 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add a pincontrol driver for BCM6318. BCM6318 allows muxing most GPIOs +to different functions. BCM6318 is similar to BCM6328 with the addition +of a pad register, and the GPIO meaning of the mux register changes +based on the GPIO number. + +Signed-off-by: Álvaro Fernández Rojas +Signed-off-by: Jonas Gorski +--- + drivers/pinctrl/bcm/Kconfig | 11 + + drivers/pinctrl/bcm/Makefile | 1 + + drivers/pinctrl/bcm/pinctrl-bcm6318.c | 674 ++++++++++++++++++++++++++ + 3 files changed, 686 insertions(+) + create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6318.c + +--- a/drivers/pinctrl/bcm/Kconfig ++++ b/drivers/pinctrl/bcm/Kconfig +@@ -29,6 +29,17 @@ config PINCTRL_BCM2835 + help + Say Y here to enable the Broadcom BCM2835 GPIO driver. + ++config PINCTRL_BCM6318 ++ bool "Broadcom BCM6318 GPIO driver" ++ depends on OF_GPIO && (BMIPS_GENERIC || COMPILE_TEST) ++ select PINMUX ++ select PINCONF ++ select GENERIC_PINCONF ++ select MFD_SYSCON ++ default BMIPS_GENERIC ++ help ++ Say Y here to enable the Broadcom BCM6318 GPIO driver. ++ + config PINCTRL_BCM6328 + bool "Broadcom BCM6328 GPIO driver" + depends on OF_GPIO && (BMIPS_GENERIC || COMPILE_TEST) +--- a/drivers/pinctrl/bcm/Makefile ++++ b/drivers/pinctrl/bcm/Makefile +@@ -3,6 +3,7 @@ + + obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o + obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.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 +--- /dev/null ++++ b/drivers/pinctrl/bcm/pinctrl-bcm6318.c +@@ -0,0 +1,674 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Driver for BCM6318 GPIO unit (pinctrl + GPIO) ++ * ++ * Copyright (C) 2021 Álvaro Fernández Rojas ++ * Copyright (C) 2016 Jonas Gorski ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include "../core.h" ++#include "../pinctrl-utils.h" ++ ++#define MODULE_NAME "bcm6318-pinctrl" ++#define BCM6318_NUM_GPIOS 50 ++#define BCM6318_NUM_MUX 48 ++ ++#define BANK_SIZE sizeof(uint32_t) ++#define PINS_PER_BANK (BANK_SIZE * BITS_PER_BYTE) ++ ++#define BCM6318_DIROUT_REG 0x04 ++#define BCM6318_DATA_REG 0x0c ++#define BCM6318_MODE_REG 0x18 ++#define BCM6318_MUX_REG 0x1c ++#define BCM6318_PAD_REG 0x54 ++ ++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; ++}; ++ ++struct bcm6318_pinctrl { ++ struct device *dev; ++ struct regmap *regs; ++ ++ struct pinctrl_dev *pctl_dev; ++ struct gpio_chip gpio_chip; ++ struct pinctrl_desc pctl_desc; ++ struct pinctrl_gpio_range gpio_range; ++}; ++ ++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_bank_pin(unsigned int pin) ++{ ++ return pin % PINS_PER_BANK; ++} ++ ++static inline unsigned int bcm6318_mux_off(unsigned int pin) ++{ ++ return BCM6318_MUX_REG + (pin / 16) * BANK_SIZE; ++} ++ ++static inline unsigned int bcm6318_pad_off(unsigned int pin) ++{ ++ return BCM6318_PAD_REG + (pin / 8) * BANK_SIZE; ++} ++ ++static inline unsigned int bcm6318_reg_off(unsigned int reg, unsigned int pin) ++{ ++ return reg - (pin / PINS_PER_BANK) * BANK_SIZE; ++} ++ ++static int bcm6318_gpio_direction_input(struct gpio_chip *chip, ++ unsigned int pin) ++{ ++ struct bcm6318_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int dirout = bcm6318_reg_off(BCM6318_DIROUT_REG, pin); ++ unsigned int bank_pin = bcm6318_bank_pin(pin); ++ int ret; ++ ++ /* ++ * Check with the pinctrl driver whether this pin is usable as ++ * an input GPIO ++ */ ++ ret = pinctrl_gpio_direction_input(chip->base + pin); ++ if (ret) ++ return ret; ++ ++ regmap_update_bits(pc->regs, dirout, BIT(bank_pin), 0); ++ ++ return 0; ++} ++ ++static int bcm6318_gpio_direction_output(struct gpio_chip *chip, ++ unsigned int pin, int value) ++{ ++ struct bcm6318_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int data = bcm6318_reg_off(BCM6318_DATA_REG, pin); ++ unsigned int dirout = bcm6318_reg_off(BCM6318_DIROUT_REG, pin); ++ unsigned int bank_pin = bcm6318_bank_pin(pin); ++ unsigned int val = value ? BIT(bank_pin) : 0; ++ int ret; ++ ++ /* ++ * Check with the pinctrl driver whether this pin is usable as ++ * an output GPIO ++ */ ++ ret = pinctrl_gpio_direction_output(chip->base + pin); ++ if (ret) ++ return ret; ++ ++ regmap_update_bits(pc->regs, dirout, BIT(bank_pin), BIT(bank_pin)); ++ regmap_update_bits(pc->regs, data, BIT(bank_pin), val); ++ ++ return 0; ++} ++ ++static int bcm6318_gpio_get(struct gpio_chip *chip, unsigned int pin) ++{ ++ struct bcm6318_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int data = bcm6318_reg_off(BCM6318_DATA_REG, pin); ++ unsigned int bank_pin = bcm6318_bank_pin(pin); ++ unsigned int val; ++ ++ regmap_read(pc->regs, data, &val); ++ ++ return !!(val & BIT(bank_pin)); ++} ++ ++static int bcm6318_gpio_get_direction(struct gpio_chip *chip, unsigned int pin) ++{ ++ struct bcm6318_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int dirout = bcm6318_reg_off(BCM6318_DIROUT_REG, pin); ++ unsigned int bank_pin = bcm6318_bank_pin(pin); ++ unsigned int val; ++ ++ regmap_read(pc->regs, dirout, &val); ++ ++ if (val & BIT(bank_pin)) ++ return GPIO_LINE_DIRECTION_OUT; ++ ++ return GPIO_LINE_DIRECTION_IN; ++} ++ ++static void bcm6318_gpio_set(struct gpio_chip *chip, unsigned int pin, ++ int value) ++{ ++ struct bcm6318_pinctrl *pc = gpiochip_get_data(chip); ++ unsigned int data = bcm6318_reg_off(BCM6318_DATA_REG, pin); ++ unsigned int bank_pin = bcm6318_bank_pin(pin); ++ unsigned int val = value ? BIT(bank_pin) : 0; ++ ++ regmap_update_bits(pc->regs, data, BIT(bank_pin), val); ++} ++ ++static int bcm6318_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) ++{ ++ char irq_name[7]; ++ ++ sprintf(irq_name, "gpio%d", gpio); ++ ++ return of_irq_get_byname(chip->of_node, irq_name); ++} ++ ++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 bcm6318_pinctrl *pc, unsigned pin, ++ unsigned int mode, unsigned int mux) ++{ ++ if (pin < PINS_PER_BANK) ++ 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), ++ 3UL << ((pin % 16) * 2), ++ mux << ((pin % 16) * 2)); ++} ++ ++static inline void bcm6318_set_pad(struct bcm6318_pinctrl *pc, unsigned pin, ++ uint8_t val) ++{ ++ regmap_update_bits(pc->regs, bcm6318_pad_off(pin), ++ 0xfUL << ((pin % 8) * 4), ++ val << ((pin % 8) * 4)); ++} ++ ++static int bcm6318_pinctrl_set_mux(struct pinctrl_dev *pctldev, ++ unsigned selector, unsigned group) ++{ ++ struct bcm6318_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 bcm6318_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 = { ++ .get_groups_count = bcm6318_pinctrl_get_group_count, ++ .get_group_name = bcm6318_pinctrl_get_group_name, ++ .get_group_pins = bcm6318_pinctrl_get_group_pins, ++ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, ++ .dt_free_map = pinctrl_utils_free_map, ++}; ++ ++static struct pinmux_ops bcm6318_pmx_ops = { ++ .get_functions_count = bcm6318_pinctrl_get_func_count, ++ .get_function_name = bcm6318_pinctrl_get_func_name, ++ .get_function_groups = bcm6318_pinctrl_get_groups, ++ .set_mux = bcm6318_pinctrl_set_mux, ++ .gpio_request_enable = bcm6318_gpio_request_enable, ++ .strict = true, ++}; ++ ++static int bcm6318_pinctrl_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *np = dev->of_node; ++ struct bcm6318_pinctrl *pc; ++ int err; ++ ++ pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); ++ if (!pc) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, pc); ++ pc->dev = dev; ++ ++ pc->regs = syscon_node_to_regmap(dev->parent->of_node); ++ if (IS_ERR(pc->regs)) ++ return PTR_ERR(pc->regs); ++ ++ pc->gpio_chip.label = MODULE_NAME; ++ pc->gpio_chip.owner = THIS_MODULE; ++ pc->gpio_chip.request = gpiochip_generic_request; ++ pc->gpio_chip.free = gpiochip_generic_free; ++ pc->gpio_chip.direction_input = bcm6318_gpio_direction_input; ++ pc->gpio_chip.direction_output = bcm6318_gpio_direction_output; ++ pc->gpio_chip.get_direction = bcm6318_gpio_get_direction; ++ pc->gpio_chip.get = bcm6318_gpio_get; ++ pc->gpio_chip.set = bcm6318_gpio_set; ++ pc->gpio_chip.set_config = gpiochip_generic_config; ++ pc->gpio_chip.base = -1; ++ pc->gpio_chip.ngpio = BCM6318_NUM_GPIOS; ++ pc->gpio_chip.can_sleep = false; ++ pc->gpio_chip.parent = dev; ++ pc->gpio_chip.of_node = np; ++ ++ if (of_get_property(np, "interrupt-names", NULL)) ++ pc->gpio_chip.to_irq = bcm6318_gpio_to_irq; ++ ++ err = gpiochip_add_data(&pc->gpio_chip, pc); ++ if (err) { ++ dev_err(dev, "could not add GPIO chip\n"); ++ return err; ++ } ++ ++ pc->pctl_desc.name = MODULE_NAME, ++ pc->pctl_desc.pins = bcm6318_pins, ++ pc->pctl_desc.npins = ARRAY_SIZE(bcm6318_pins), ++ pc->pctl_desc.pctlops = &bcm6318_pctl_ops, ++ pc->pctl_desc.pmxops = &bcm6318_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)) { ++ gpiochip_remove(&pc->gpio_chip); ++ return PTR_ERR(pc->pctl_dev); ++ } ++ ++ pc->gpio_range.name = MODULE_NAME; ++ pc->gpio_range.npins = BCM6318_NUM_GPIOS; ++ pc->gpio_range.base = pc->gpio_chip.base; ++ pc->gpio_range.gc = &pc->gpio_chip; ++ pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range); ++ ++ dev_info(dev, "registered\n"); ++ ++ return 0; ++} ++ ++static const struct of_device_id bcm6318_pinctrl_match[] = { ++ { .compatible = "brcm,bcm6318-pinctrl", }, ++ { }, ++}; ++ ++static struct platform_driver bcm6318_pinctrl_driver = { ++ .probe = bcm6318_pinctrl_probe, ++ .driver = { ++ .name = MODULE_NAME, ++ .of_match_table = bcm6318_pinctrl_match, ++ }, ++}; ++ ++builtin_platform_driver(bcm6318_pinctrl_driver); diff --git a/target/linux/bmips/patches-5.10/412-pinctrl-add-a-pincontrol-driver-for-BCM6318.patch b/target/linux/bmips/patches-5.10/412-pinctrl-add-a-pincontrol-driver-for-BCM6318.patch deleted file mode 100644 index 1cc907434c..0000000000 --- a/target/linux/bmips/patches-5.10/412-pinctrl-add-a-pincontrol-driver-for-BCM6318.patch +++ /dev/null @@ -1,609 +0,0 @@ -From bd9c250ef85e6f99aa5d59b21abb87d0a48f2f61 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Fri, 24 Jun 2016 22:20:39 +0200 -Subject: [PATCH 15/16] pinctrl: add a pincontrol driver for BCM6318 - -Add a pincontrol driver for BCM6318. BCM6318 allows muxing most GPIOs -to different functions. BCM6318 is similar to BCM6328 with the addition -of a pad register, and the GPIO meaning of the mux register changes -based on the GPIO number. - -Signed-off-by: Jonas Gorski ---- - drivers/pinctrl/bcm63xx/Kconfig | 7 + - drivers/pinctrl/bcm63xx/Makefile | 1 + - drivers/pinctrl/bcm63xx/pinctrl-bcm6318.c | 564 ++++++++++++++++++++++++++++++ - 3 files changed, 572 insertions(+) - create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6318.c - ---- a/drivers/pinctrl/bcm63xx/Kconfig -+++ b/drivers/pinctrl/bcm63xx/Kconfig -@@ -2,6 +2,13 @@ config PINCTRL_BCM63XX - bool - select GPIO_GENERIC - -+config PINCTRL_BCM6318 -+ bool "BCM6318 pincontrol driver" -+ select PINMUX -+ select PINCONF -+ select PINCTRL_BCM63XX -+ select GENERIC_PINCONF -+ - config PINCTRL_BCM6328 - bool "BCM6328 pincontrol driver" - select PINMUX ---- a/drivers/pinctrl/bcm63xx/Makefile -+++ b/drivers/pinctrl/bcm63xx/Makefile -@@ -1,4 +1,5 @@ - 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 ---- /dev/null -+++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm6318.c -@@ -0,0 +1,564 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2016 Jonas Gorski -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "../core.h" -+#include "../pinctrl-utils.h" -+ -+#include "pinctrl-bcm63xx.h" -+ -+#define BCM6318_NGPIO 50 -+ -+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; -+}; -+ -+struct bcm6318_pinctrl { -+ struct pinctrl_dev *pctldev; -+ struct pinctrl_desc desc; -+ -+ void __iomem *mode; -+ void __iomem *mux[3]; -+ void __iomem *pad[6]; -+ -+ /* register access lock */ -+ spinlock_t lock; -+ -+ struct gpio_chip gpio[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 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 void bcm6318_rmw_mux(struct bcm6318_pinctrl *pctl, unsigned pin, -+ u32 mode, u32 mux) -+{ -+ unsigned long flags; -+ u32 reg; -+ -+ spin_lock_irqsave(&pctl->lock, flags); -+ if (pin < 32) { -+ reg = __raw_readl(pctl->mode); -+ reg &= ~BIT(pin); -+ if (mode) -+ reg |= BIT(pin); -+ __raw_writel(reg, pctl->mode); -+ } -+ -+ if (pin < 48) { -+ reg = __raw_readl(pctl->mux[pin / 16]); -+ reg &= ~(3UL << ((pin % 16) * 2)); -+ reg |= mux << ((pin % 16) * 2); -+ __raw_writel(reg, pctl->mux[pin / 16]); -+ } -+ spin_unlock_irqrestore(&pctl->lock, flags); -+} -+ -+static void bcm6318_set_pad(struct bcm6318_pinctrl *pctl, unsigned pin, u8 val) -+{ -+ unsigned long flags; -+ u32 reg; -+ -+ spin_lock_irqsave(&pctl->lock, flags); -+ reg = __raw_readl(pctl->pad[pin / 8]); -+ reg &= ~(0xfUL << ((pin % 8) * 4)); -+ reg |= val << ((pin % 8) * 4); -+ __raw_writel(reg, pctl->pad[pin / 8]); -+ spin_unlock_irqrestore(&pctl->lock, flags); -+} -+ -+static int bcm6318_pinctrl_set_mux(struct pinctrl_dev *pctldev, -+ unsigned selector, unsigned group) -+{ -+ struct bcm6318_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); -+ const struct bcm6318_pingroup *grp = &bcm6318_groups[group]; -+ const struct bcm6318_function *f = &bcm6318_funcs[selector]; -+ -+ bcm6318_rmw_mux(pctl, grp->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 bcm6318_pinctrl *pctl = 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(pctl, offset, 0, 0); -+ } else if (offset < 42) { -+ /* GPIOs 13-41 use mux 3 as GPIO function */ -+ bcm6318_rmw_mux(pctl, offset, 0, 3); -+ -+ /* FIXME: revert to old value for non gpio? */ -+ bcm6318_set_pad(pctl, offset, 0); -+ } else { -+ /* no idea, really */ -+ } -+ -+ return 0; -+} -+ -+static struct pinctrl_ops bcm6318_pctl_ops = { -+ .get_groups_count = bcm6318_pinctrl_get_group_count, -+ .get_group_name = bcm6318_pinctrl_get_group_name, -+ .get_group_pins = bcm6318_pinctrl_get_group_pins, -+#ifdef CONFIG_OF -+ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, -+ .dt_free_map = pinctrl_utils_free_map, -+#endif -+}; -+ -+static struct pinmux_ops bcm6318_pmx_ops = { -+ .get_functions_count = bcm6318_pinctrl_get_func_count, -+ .get_function_name = bcm6318_pinctrl_get_func_name, -+ .get_function_groups = bcm6318_pinctrl_get_groups, -+ .set_mux = bcm6318_pinctrl_set_mux, -+ .gpio_request_enable = bcm6318_gpio_request_enable, -+ .strict = true, -+}; -+ -+static int bcm6318_pinctrl_probe(struct platform_device *pdev) -+{ -+ struct bcm6318_pinctrl *pctl; -+ struct resource *res; -+ void __iomem *mode, *mux, *pad; -+ unsigned i; -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode"); -+ mode = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(mode)) -+ return PTR_ERR(mode); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mux"); -+ mux = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(mux)) -+ return PTR_ERR(mux); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pad"); -+ pad = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(pad)) -+ return PTR_ERR(pad); -+ -+ pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL); -+ if (!pctl) -+ return -ENOMEM; -+ -+ spin_lock_init(&pctl->lock); -+ -+ pctl->mode = mode; -+ -+ for (i = 0; i < 3; i++) -+ pctl->mux[i] = mux + (i * 4); -+ -+ for (i = 0; i < 6; i++) -+ pctl->pad[i] = pad + (i * 4); -+ -+ pctl->desc.name = dev_name(&pdev->dev); -+ pctl->desc.owner = THIS_MODULE; -+ pctl->desc.pctlops = &bcm6318_pctl_ops; -+ pctl->desc.pmxops = &bcm6318_pmx_ops; -+ -+ pctl->desc.npins = ARRAY_SIZE(bcm6318_pins); -+ pctl->desc.pins = bcm6318_pins; -+ -+ platform_set_drvdata(pdev, pctl); -+ -+ pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl, -+ pctl->gpio, BCM6318_NGPIO); -+ if (IS_ERR(pctl->pctldev)) -+ return PTR_ERR(pctl->pctldev); -+ -+ return 0; -+} -+ -+static const struct of_device_id bcm6318_pinctrl_match[] = { -+ { .compatible = "brcm,bcm6318-pinctrl", }, -+ { }, -+}; -+ -+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);