
Hi Philipp,
On Fri, Feb 17, 2017 at 06:52:39PM +0100, Philipp Tomsich wrote:
This change adds a full device-model pinctrl driver for sunxi (tested with sun50iw1p1) based on the support available in Linux.
Details are:
- implements a driver for pinctrl devices and assigns sun50i-a64-pinctrl and sun50i-a64-r-pinctrl to it
- defines and implements a binding for sunxi-style GPIO banks (to make it easier to describe controllers like the A64 which may not start at 'A') and provide the necessary translation mechanisms:
- As all our gpio-reference point back to either <&pio ..> or <&r_pio ..> the device framework will try to access a UCLASS_GPIO device bound to the same node id as the pinctrl device to perform it's of_xlate lookup. For this, we provide a 'gpiobridge' driver (which needs to access the platdata of the pinctrl device) and which can then map accesses to an actual GPIO bank device.
- For the individual GPIO banks, we use a new driver (which shares most of its ops with the existing sunxi_gpio driver, except probe and bind) and provides configuration without any platdata structure.
- lifts and reuses the pinctrl-sunxi.h and pinctrl-sun50i-a64.c files from Linux (thanks to Maxime and Andre) and adds a pinctrl-sun50i-a64-r.c (to be picked up for inclusion into Linux again)
The active DM tree at runtime (with this enabled) should look similar to the following:
pinctrl [ + ] | |-- pinctrl@1c20800 gpio [ + ] | | |-- gpiob@24 gpio [ + ] | | |-- gpioc@48 gpio [ + ] | | |-- gpiod@6c gpio [ + ] | | |-- gpioe@90 gpio [ + ] | | |-- gpiof@b4 gpio [ + ] | | |-- gpiog@d8 gpio [ + ] | | |-- gpioh@fc pinconfig [ + ] | | |-- uart0_pins_a pinconfig [ ] | | |-- uart0_pins_b pinconfig [ ] | | |-- uart1_2pins pinconfig [ ] | | |-- uart1_4pins pinconfig [ ] | | |-- uart2_2pins pinconfig [ ] | | |-- uart2_4 pinconfig [ ] | | |-- uart3 pinconfig [ ] | | |-- uart3_2 pinconfig [ ] | | |-- uart3_4 pinconfig [ ] | | |-- uart4_2 pinconfig [ ] | | |-- uart4_4 pinconfig [ + ] | | |-- mmc0 pinconfig [ + ] | | |-- mmc0_cd_pin pinconfig [ ] | | |-- mmc1 pinconfig [ ] | | |-- mmc2 pinconfig [ + ] | | |-- mmc2_8bit pinconfig [ ] | | |-- i2c0_pins pinconfig [ ] | | |-- i2c1_pins pinconfig [ ] | | |-- i2c2_pins pinconfig [ ] | | |-- rmii_pins pinconfig [ + ] | | |-- rgmii_pins pinconfig [ + ] | | |-- spi0_pins pinconfig [ ] | | |-- spi1_pins pinconfig [ + ] | | |-- led_pins_sdio pinconfig [ + ] | | |-- ethphy_reset_pin gpio [ + ] | | `-- gpiobridge pinctrl [ + ] | |-- pinctrl@01f02c00 gpio [ + ] | | |-- gpiol@0 pinconfig [ + ] | | |-- led_pins_power gpio [ + ] | | `-- gpiobridge
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com
.../pinctrl/allwinner,pinctrl.txt | 130 +++++ drivers/gpio/sunxi_gpio.c | 97 +++- drivers/pinctrl/Kconfig | 10 + drivers/pinctrl/Makefile | 2 + drivers/pinctrl/sunxi/Makefile | 10 + drivers/pinctrl/sunxi/pinctrl-sun50i-a64-r.c | 92 ++++ drivers/pinctrl/sunxi/pinctrl-sun50i-a64.c | 577 +++++++++++++++++++++ drivers/pinctrl/sunxi/pinctrl-sunxi.c | 326 ++++++++++++ drivers/pinctrl/sunxi/pinctrl-sunxi.h | 311 +++++++++++ 9 files changed, 1553 insertions(+), 2 deletions(-) create mode 100644 doc/device-tree-bindings/pinctrl/allwinner,pinctrl.txt create mode 100644 drivers/pinctrl/sunxi/Makefile create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun50i-a64-r.c create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun50i-a64.c create mode 100644 drivers/pinctrl/sunxi/pinctrl-sunxi.c create mode 100644 drivers/pinctrl/sunxi/pinctrl-sunxi.h
diff --git a/doc/device-tree-bindings/pinctrl/allwinner,pinctrl.txt b/doc/device-tree-bindings/pinctrl/allwinner,pinctrl.txt new file mode 100644 index 0000000..e536ea3 --- /dev/null +++ b/doc/device-tree-bindings/pinctrl/allwinner,pinctrl.txt @@ -0,0 +1,130 @@ +* Allwinner Pinmux Controller
+Allwinner integrates multiple banks (of 32 pins each) of pin-muxing, +GPIO functionality and (optional) external interrupt functionality +into a single controller.
+For each configurable pad (certain driver-cells, such as the IO from +integrated USB PHYs or DRAM, have a fixed function and can not be +configured), the muxing options (input, output or one of the several +functions) can be selected.
+The Allwinner pinctrl node contains a description of the pinctrl block +(i.e. including GPIO and external interrupt capability, if available) +and subnodes describing individual GPIO banks and pin-configuration.
+Properties for the pinctrl node:
- compatible: should be "allwinner,sun50i-pinctrl"
- reg: address and length of the register set for the device.
- interrupts: interrupt for the device
- clocks: A phandle to the reference clock for this device
+Properties for the pinconfig sub-nodes:
- allwinner,pins: a list of pins (e.g. "PH2", "PH3") to configure
- allwinner,function: the name of pinmux function (e.g. "mmc2")
- drive-strength: a drive-stength setting of 10, 20, 30 or 40 mA
- bias-pull-up
- bias-pull-down
- bias-disable (default)
+Deprecated properties for the pinconfig sub-nodes:
- allwinner,drive: one of <SUN4I_PINCTRL_10_MA>, <SUN4I_PINCTRL_20_MA>,
<SUN4I_PINCTRL_30_MA> or <SUN4I_PINCTRL_40_MA>
- allwinner,pull: one of <SUN4I_PINCTRL_NO_PULL>, <SUN4I_PINCTRL_PULL_UP>
or <SUN4I_PINCTRL_PULL_DOWN>
+Properties for the gpio sub-nodes:
- compatible: should be "allwinner,sunxi-gpiobank"
- allwinner,gpiobank-name: the name of the bank (e.g. <'A'>, <'B'>, ...)
- reg: offsets (within the address range of the enclosing pinctrl
node's address space) and length of the registers, where
- The first entry points to the mux/gpio registers.
- An (optional) second entry points to the extint registers.
Note, that the second entry should be provided, if the
interrupt property is present.
- interrupt: the interrupt used for external interrupt signalling
(should be one of the interrupts specified in the
enclosing pinctrl node)
+Example:
- pio: pinctrl@1c20800 {
compatible = "allwinner,sun50i-a64-pinctrl";
reg = <0x01c20800 0x400>;
interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&bus_gates 69>;
gpio-controller;
#gpio-cells = <3>;
interrupt-controller;
#interrupt-cells = <2>;
#address-cells = <1>;
#size-cells = <1>;
/* The A64 does not have bank A and leaves a hole in the
address space where it normally would be */
gpiob: gpiob@24 {
compatible = "allwinner,sunxi-gpiobank";
allwinner,gpiobank-name = <'B'>;
reg = < 0x24 0x24 >, < 0x200 0x1c >;
interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
};
gpioc: gpioc@48 {
compatible = "allwinner,sunxi-gpiobank";
reg = < 0x48 0x24 >;
allwinner,gpiobank-name = <'C'>;
};
gpiod: gpiod@6c {
compatible = "allwinner,sunxi-gpiobank";
reg = < 0x6c 0x24 >;
allwinner,gpiobank-name = <'D'>;
};
gpioe: gpioe@90 {
compatible = "allwinner,sunxi-gpiobank";
reg = < 0x90 0x24 >;
allwinner,gpiobank-name = <'E'>;
};
gpiof: gpiof@b4 {
compatible = "allwinner,sunxi-gpiobank";
reg = < 0xb4 0x24 >;
allwinner,gpiobank-name = <'F'>;
};
gpiog: gpiog@d8 {
compatible = "allwinner,sunxi-gpiobank";
reg = < 0xd8 0x24 >, < 0x220 0x1c >;
allwinner,gpiobank-name = <'G'>;
interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
};
gpioh: gpioh@fc {
compatible = "allwinner,sunxi-gpiobank";
reg = < 0xfc 0x24 >, < 0x220 0x1c >;
allwinner,gpiobank-name = <'H'>;
interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
};
uart0_pins_a: uart0_pins_a {
allwinner,pins = "PB8", "PB9";
allwinner,function = "uart0";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
uart0_pins_b: uart0_pins_b {
allwinner,pins = "PF2", "PF3";
allwinner,function = "uart0";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
- };
Unfortunately, we're using the DT bindings coming from Linux, and this is not the bindings used there. For every new bindings, this should be submitted, reviewed and accepted first by the DT maintainers there.
In this case, there's no particular need to make that addition in the first place, since we can use some other means to implement that.
Maxime