]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'pinctrl/for-next'
authorThierry Reding <treding@nvidia.com>
Thu, 24 Oct 2013 12:59:39 +0000 (14:59 +0200)
committerThierry Reding <treding@nvidia.com>
Thu, 24 Oct 2013 12:59:39 +0000 (14:59 +0200)
54 files changed:
Documentation/devicetree/bindings/gpio/gpio.txt
Documentation/devicetree/bindings/pinctrl/abilis,tb10x-iomux.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/pinctrl-palmas.txt
Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt
Documentation/pinctrl.txt
arch/arm/boot/dts/atlas6.dtsi
arch/arm/boot/dts/prima2.dtsi
arch/blackfin/Kconfig
arch/blackfin/include/asm/gpio.h
arch/blackfin/include/asm/portmux.h
arch/blackfin/kernel/Makefile
arch/blackfin/mach-bf548/include/mach/portmux.h
arch/blackfin/mach-bf609/include/mach/portmux.h
drivers/gpio/gpiolib-of.c
drivers/gpio/gpiolib.c
drivers/pinctrl/Kconfig
drivers/pinctrl/Makefile
drivers/pinctrl/core.c
drivers/pinctrl/mvebu/pinctrl-armada-370.c
drivers/pinctrl/mvebu/pinctrl-armada-xp.c
drivers/pinctrl/mvebu/pinctrl-dove.c
drivers/pinctrl/mvebu/pinctrl-kirkwood.c
drivers/pinctrl/pinctrl-adi2-bf54x.c [new file with mode: 0644]
drivers/pinctrl/pinctrl-adi2-bf60x.c [new file with mode: 0644]
drivers/pinctrl/pinctrl-adi2.c [new file with mode: 0644]
drivers/pinctrl/pinctrl-adi2.h [new file with mode: 0644]
drivers/pinctrl/pinctrl-as3722.c [new file with mode: 0644]
drivers/pinctrl/pinctrl-at91.c
drivers/pinctrl/pinctrl-exynos5440.c
drivers/pinctrl/pinctrl-imx35.c
drivers/pinctrl/pinctrl-imx51.c
drivers/pinctrl/pinctrl-imx53.c
drivers/pinctrl/pinctrl-imx6dl.c
drivers/pinctrl/pinctrl-imx6q.c
drivers/pinctrl/pinctrl-imx6sl.c
drivers/pinctrl/pinctrl-palmas.c
drivers/pinctrl/pinctrl-rockchip.c
drivers/pinctrl/pinctrl-samsung.c
drivers/pinctrl/pinctrl-tb10x.c [new file with mode: 0644]
drivers/pinctrl/pinctrl-vf610.c
drivers/pinctrl/sh-pfc/pfc-r8a7778.c
drivers/pinctrl/sh-pfc/pfc-r8a7790.c
drivers/pinctrl/sirf/pinctrl-atlas6.c
drivers/pinctrl/sirf/pinctrl-prima2.c
drivers/pinctrl/sirf/pinctrl-sirf.c
drivers/pinctrl/sirf/pinctrl-sirf.h
drivers/pinctrl/spear/pinctrl-plgpio.c
include/asm-generic/gpio.h
include/dt-bindings/pinctrl/at91.h
include/linux/gpio.h
include/linux/pinctrl/pinctrl.h
include/linux/platform_data/pinctrl-adi2.h [new file with mode: 0644]

index 6cec6ff20d2e576ff51010389bcb494c4d2cd225..0c85bb6e3a80282edce785cad57468c6e11cfae0 100644 (file)
@@ -87,8 +87,10 @@ controllers. The gpio-ranges property described below represents this, and
 contains information structures as follows:
 
        gpio-range-list ::= <single-gpio-range> [gpio-range-list]
-       single-gpio-range ::=
+       single-gpio-range ::= <numeric-gpio-range> | <named-gpio-range>
+       numeric-gpio-range ::=
                        <pinctrl-phandle> <gpio-base> <pinctrl-base> <count>
+       named-gpio-range ::= <pinctrl-phandle> <gpio-base> '<0 0>'
        gpio-phandle : phandle to pin controller node.
        gpio-base : Base GPIO ID in the GPIO controller
        pinctrl-base : Base pinctrl pin ID in the pin controller
@@ -97,6 +99,19 @@ contains information structures as follows:
 The "pin controller node" mentioned above must conform to the bindings
 described in ../pinctrl/pinctrl-bindings.txt.
 
+In case named gpio ranges are used (ranges with both <pinctrl-base> and
+<count> set to 0), the property gpio-ranges-group-names contains one string
+for every single-gpio-range in gpio-ranges:
+       gpiorange-names-list ::= <gpiorange-name> [gpiorange-names-list]
+       gpiorange-name : Name of the pingroup associated to the GPIO range in
+                       the respective pin controller.
+
+Elements of gpiorange-names-list corresponding to numeric ranges contain
+the empty string. Elements of gpiorange-names-list corresponding to named
+ranges contain the name of a pin group defined in the respective pin
+controller. The number of pins/GPIOs in the range is the number of pins in
+that pin group.
+
 Previous versions of this binding required all pin controller nodes that
 were referenced by any gpio-ranges property to contain a property named
 #gpio-range-cells with value <3>. This requirement is now deprecated.
@@ -104,7 +119,7 @@ However, that property may still exist in older device trees for
 compatibility reasons, and would still be required even in new device
 trees that need to be compatible with older software.
 
-Example:
+Example 1:
 
        qe_pio_e: gpio-controller@1460 {
                #gpio-cells = <2>;
@@ -117,3 +132,24 @@ Example:
 Here, a single GPIO controller has GPIOs 0..9 routed to pin controller
 pinctrl1's pins 20..29, and GPIOs 10..19 routed to pin controller pinctrl2's
 pins 50..59.
+
+Example 2:
+
+       gpio_pio_i: gpio-controller@14B0 {
+               #gpio-cells = <2>;
+               compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank";
+               reg = <0x1480 0x18>;
+               gpio-controller;
+               gpio-ranges =                   <&pinctrl1 0 20 10>,
+                                               <&pinctrl2 10 0 0>,
+                                               <&pinctrl1 15 0 10>,
+                                               <&pinctrl2 25 0 0>;
+               gpio-ranges-group-names =       "",
+                                               "foo",
+                                               "",
+                                               "bar";
+       };
+
+Here, three GPIO ranges are defined wrt. two pin controllers. pinctrl1 GPIO
+ranges are defined using pin numbers whereas the GPIO ranges wrt. pinctrl2
+are named "foo" and "bar".
diff --git a/Documentation/devicetree/bindings/pinctrl/abilis,tb10x-iomux.txt b/Documentation/devicetree/bindings/pinctrl/abilis,tb10x-iomux.txt
new file mode 100644 (file)
index 0000000..2c11866
--- /dev/null
@@ -0,0 +1,80 @@
+Abilis Systems TB10x pin controller
+===================================
+
+Required properties
+-------------------
+
+- compatible: should be "abilis,tb10x-iomux";
+- reg: should contain the physical address and size of the pin controller's
+  register range.
+
+
+Function definitions
+--------------------
+
+Functions are defined (and referenced) by sub-nodes of the pin controller.
+Every sub-node defines exactly one function (implying a set of pins).
+Every function is associated to one named pin group inside the pin controller
+driver and these names are used to associate pin group predefinitions to pin
+controller sub-nodes.
+
+Required function definition subnode properties:
+  - abilis,function: should be set to the name of the function's pin group.
+
+The following pin groups are available:
+  - GPIO ports: gpioa, gpiob, gpioc, gpiod, gpioe, gpiof, gpiog,
+                gpioh, gpioi, gpioj, gpiok, gpiol, gpiom, gpion
+  - Serial TS input ports: mis0, mis1, mis2, mis3, mis4, mis5, mis6, mis7
+  - Parallel TS input ports: mip1, mip3, mip5, mip7
+  - Serial TS output ports: mos0, mos1, mos2, mos3
+  - Parallel TS output port: mop
+  - CI+ port: ciplus
+  - CableCard (Mcard) port: mcard
+  - Smart card ports: stc0, stc1
+  - UART ports: uart0, uart1
+  - SPI ports: spi1, spi3
+  - JTAG: jtag
+
+All other ports of the chip are not multiplexed and thus not managed by this
+driver.
+
+
+GPIO ranges definition
+----------------------
+
+The named pin groups of GPIO ports can be used to define GPIO ranges as
+explained in Documentation/devicetree/bindings/gpio/gpio.txt.
+
+
+Example
+-------
+
+iomux: iomux@FF10601c {
+       compatible = "abilis,tb10x-iomux";
+       reg = <0xFF10601c 0x4>;
+       pctl_gpio_a: pctl-gpio-a {
+               abilis,function = "gpioa";
+       };
+       pctl_uart0: pctl-uart0 {
+               abilis,function = "uart0";
+       };
+};
+uart@FF100000 {
+       compatible = "snps,dw-apb-uart";
+       reg = <0xFF100000 0x100>;
+       clock-frequency = <166666666>;
+       interrupts = <25 1>;
+       reg-shift = <2>;
+       reg-io-width = <4>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pctl_uart0>;
+};
+gpioa: gpio@FF140000 {
+       compatible = "abilis,tb10x-gpio";
+       reg = <0xFF140000 0x1000>;
+       gpio-controller;
+       #gpio-cells = <2>;
+       ngpio = <3>;
+       gpio-ranges = <&iomux 0 0>;
+       gpio-ranges-group-names = "gpioa";
+};
index 7ccae490ff6dcc6936f7c9e5791435685d3ded30..02ab5ab198a4cfcb19da6a31fdaec6720f1fccfb 100644 (file)
@@ -18,7 +18,7 @@ mode) this pin can work on and the 'config' configures various pad settings
 such as pull-up, multi drive, etc.
 
 Required properties for iomux controller:
-- compatible: "atmel,at91rm9200-pinctrl"
+- compatible: "atmel,at91rm9200-pinctrl" or "atmel,at91sam9x5-pinctrl"
 - atmel,mux-mask: array of mask (periph per bank) to describe if a pin can be
   configured in this periph mode. All the periph and bank need to be describe.
 
index 3a7caf7a744a98d0b08538b157c12441e31d2987..9fde25f1401a55b64b8b3fa80f27f9310e7cb706 100644 (file)
@@ -22,11 +22,12 @@ Required properties for iomux controller:
   Please refer to each fsl,<soc>-pinctrl.txt binding doc for supported SoCs.
 
 Required properties for pin configuration node:
-- fsl,pins: two integers array, represents a group of pins mux and config
-  setting. The format is fsl,pins = <PIN_FUNC_ID CONFIG>, PIN_FUNC_ID is a
-  pin working on a specific function, which consists of a tuple of
-  <mux_reg conf_reg input_reg mux_val input_val>.  CONFIG is the pad setting
-  value like pull-up on this pin.
+- fsl,pins: each entry consists of 6 integers and represents the mux and config
+  setting for one pin. The first 5 integers <mux_reg conf_reg input_reg mux_val
+  input_val> are specified using a PIN_FUNC_ID macro, which can be found in
+  imx*-pinfunc.h under device tree source folder. The last integer CONFIG is
+  the pad setting value like pull-up on this pin. And that's why fsl,pins entry
+  looks like <PIN_FUNC_ID CONFIG> in the example below.
 
 Bits used for CONFIG:
 NO_PAD_CTL(1 << 31): indicate this pin does not need config.
@@ -72,17 +73,18 @@ iomuxc@020e0000 {
        /* shared pinctrl settings */
        usdhc4 {
                pinctrl_usdhc4_1: usdhc4grp-1 {
-                       fsl,pins = <1386 0x17059        /* MX6Q_PAD_SD4_CMD__USDHC4_CMD */
-                                   1392 0x10059        /* MX6Q_PAD_SD4_CLK__USDHC4_CLK */
-                                   1462 0x17059        /* MX6Q_PAD_SD4_DAT0__USDHC4_DAT0 */
-                                   1470 0x17059        /* MX6Q_PAD_SD4_DAT1__USDHC4_DAT1 */
-                                   1478 0x17059        /* MX6Q_PAD_SD4_DAT2__USDHC4_DAT2 */
-                                   1486 0x17059        /* MX6Q_PAD_SD4_DAT3__USDHC4_DAT3 */
-                                   1493 0x17059        /* MX6Q_PAD_SD4_DAT4__USDHC4_DAT4 */
-                                   1501 0x17059        /* MX6Q_PAD_SD4_DAT5__USDHC4_DAT5 */
-                                   1509 0x17059        /* MX6Q_PAD_SD4_DAT6__USDHC4_DAT6 */
-                                   1517 0x17059>;      /* MX6Q_PAD_SD4_DAT7__USDHC4_DAT7 */
-               };
+                       fsl,pins = <
+                               MX6QDL_PAD_SD4_CMD__SD4_CMD    0x17059
+                               MX6QDL_PAD_SD4_CLK__SD4_CLK    0x10059
+                               MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
+                               MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
+                               MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
+                               MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
+                               MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
+                               MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
+                               MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
+                               MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
+                       >;
        };
        ....
 };
@@ -90,6 +92,3 @@ Refer to the IOMUXC controller chapter in imx6q datasheet,
 0x17059 means enable hysteresis, 47KOhm Pull Up, 50Mhz speed,
 80Ohm driver strength and Fast Slew Rate.
 User should refer to each SoC spec to set the correct value.
-
-TODO: when dtc macro support is available, we can change above raw data
-to dt macro which can get better readability in dts file.
index 734d9b04d5337c6c9591e9c41482fd9a5afc50d5..caf297bee1fb4c34ef5151912656f9636fe1565e 100644 (file)
@@ -41,7 +41,7 @@ pinctrl-bindings.txt:
 
 Required: pins
 Options: function, bias-disable, bias-pull-up, bias-pull-down,
-        bias-pin-default, drive-open-drain.
+        drive-open-drain.
 
 Note that many of these properties are only valid for certain specific pins.
 See the Palmas device datasheet for complete details regarding which pins
index b0fb1018d7ad764059a595265c8700a0c8f0ffad..f378d342aae4c46fdaf70a92ecd385fc618a7449 100644 (file)
@@ -21,10 +21,13 @@ defined as gpio sub-nodes of the pinmux controller.
 Required properties for iomux controller:
   - compatible: one of "rockchip,rk2928-pinctrl", "rockchip,rk3066a-pinctrl"
                       "rockchip,rk3066b-pinctrl", "rockchip,rk3188-pinctrl"
+  - reg: first element is the general register space of the iomux controller
+        second element is the separate pull register space of the rk3188
 
 Required properties for gpio sub nodes:
-  - compatible: "rockchip,gpio-bank"
+  - compatible: "rockchip,gpio-bank", "rockchip,rk3188-gpio-bank0"
   - reg: register of the gpio bank (different than the iomux registerset)
+         second element: separate pull register for rk3188 bank0
   - interrupts: base interrupt of the gpio bank in the interrupt controller
   - clocks: clock that drives this bank
   - gpio-controller: identifies the node as a gpio controller and pin bank.
@@ -95,3 +98,44 @@ uart2: serial@20064000 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart2_xfer>;
 };
+
+Example for rk3188:
+
+       pinctrl@20008000 {
+               compatible = "rockchip,rk3188-pinctrl";
+               reg = <0x20008000 0xa0>,
+                     <0x20008164 0x1a0>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               gpio0: gpio0@0x2000a000 {
+                       compatible = "rockchip,rk3188-gpio-bank0";
+                       reg = <0x2000a000 0x100>,
+                             <0x20004064 0x8>;
+                       interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clk_gates8 9>;
+
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpio1: gpio1@0x2003c000 {
+                       compatible = "rockchip,gpio-bank";
+                       reg = <0x2003c000 0x100>;
+                       interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clk_gates8 10>;
+
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               ...
+
+       };
index c0ffd30eb55eae219cc9a6606ea5b3b71cf01f63..a7929cb47e7c182392ccbd811972c63eaba19b64 100644 (file)
@@ -358,7 +358,12 @@ static struct pinctrl_gpio_range gpio_range = {
        .gc = &chip;
 };
 
-In this case the pin_base property will be ignored.
+In this case the pin_base property will be ignored. If the name of a pin
+group is known, the pins and npins elements of the above structure can be
+initialised using the function pinctrl_get_group_pins(), e.g. for pin
+group "foo":
+
+pinctrl_get_group_pins(pctl, "foo", &gpio_range.pins, &gpio_range.npins);
 
 When GPIO-specific functions in the pin control subsystem are called, these
 ranges will be used to look up the appropriate pin controller by inspecting
index 6db4f81d4795d2855b83aac5a72cc3c7b8cb6727..0600bad24c042a0477fa42ed3c06c0f0b3579baf 100644 (file)
                                                 sirf,function = "usb1_utmi_drvbus";
                                         };
                                 };
+                                usb1_dp_dn_pins_a: usb1_dp_dn@0 {
+                                        usb1_dp_dn {
+                                                sirf,pins = "usb1_dp_dngrp";
+                                                sirf,function = "usb1_dp_dn";
+                                        };
+                                };
+                                uart1_route_io_usb1_pins_a: uart1_route_io_usb1@0 {
+                                        uart1_route_io_usb1 {
+                                                sirf,pins = "uart1_route_io_usb1grp";
+                                                sirf,function = "uart1_route_io_usb1";
+                                        };
+                                };
                                 warm_rst_pins_a: warm_rst@0 {
                                         warm_rst {
                                                 sirf,pins = "warm_rstgrp";
index 27ed9f5144bcb927d777cf4468c1ddaa5c11c837..006952da97f0ddc426c1163b3a1f116d3ebf9de3 100644 (file)
                                                sirf,function = "uart0";
                                        };
                                };
+                               uart0_noflow_pins_a: uart0@1 {
+                                       uart {
+                                               sirf,pins = "uart0_nostreamctrlgrp";
+                                               sirf,function = "uart0_nostreamctrl";
+                                       };
+                               };
                                uart1_pins_a: uart1@0 {
                                        uart {
                                                sirf,pins = "uart1grp";
                                                 sirf,function = "usp0";
                                         };
                                 };
+                               usp0_uart_nostreamctrl_pins_a: usp0@1 {
+                                        usp0 {
+                                                sirf,pins =
+                                                       "usp0_uart_nostreamctrl_grp";
+                                                sirf,function =
+                                                       "usp0_uart_nostreamctrl";
+                                        };
+                                };
                                 usp1_pins_a: usp1@0 {
                                         usp1 {
                                                 sirf,pins = "usp1grp";
                                                 sirf,function = "usp1";
                                         };
                                 };
+                               usp1_uart_nostreamctrl_pins_a: usp1@1 {
+                                        usp1 {
+                                                sirf,pins =
+                                                       "usp1_uart_nostreamctrl_grp";
+                                                sirf,function =
+                                                       "usp1_uart_nostreamctrl";
+                                        };
+                                };
                                 usp2_pins_a: usp2@0 {
                                         usp2 {
                                                 sirf,pins = "usp2grp";
                                                 sirf,function = "usp2";
                                         };
                                 };
+                               usp2_uart_nostreamctrl_pins_a: usp2@1 {
+                                        usp2 {
+                                                sirf,pins =
+                                                       "usp2_uart_nostreamctrl_grp";
+                                                sirf,function =
+                                                       "usp2_uart_nostreamctrl";
+                                        };
+                                };
                                 usb0_utmi_drvbus_pins_a: usb0_utmi_drvbus@0 {
                                         usb0_utmi_drvbus {
                                                 sirf,pins = "usb0_utmi_drvbusgrp";
                                                 sirf,function = "usb1_utmi_drvbus";
                                         };
                                 };
+                                usb1_dp_dn_pins_a: usb1_dp_dn@0 {
+                                        usb1_dp_dn {
+                                                sirf,pins = "usb1_dp_dngrp";
+                                                sirf,function = "usb1_dp_dn";
+                                        };
+                                };
+                                uart1_route_io_usb1_pins_a: uart1_route_io_usb1@0 {
+                                        uart1_route_io_usb1 {
+                                                sirf,pins = "uart1_route_io_usb1grp";
+                                                sirf,function = "uart1_route_io_usb1";
+                                        };
+                                };
                                 warm_rst_pins_a: warm_rst@0 {
                                         warm_rst {
                                                 sirf,pins = "warm_rstgrp";
index eb382aedd9a232c9d85173356bf4ed44d33fb6b5..e887b57c3176705d90beeebcc39123836f5eff1b 100644 (file)
@@ -52,6 +52,9 @@ config GENERIC_BUG
 config ZONE_DMA
        def_bool y
 
+config GENERIC_GPIO
+       def_bool y
+
 config FORCE_MAX_ZONEORDER
        int
        default "14"
@@ -317,6 +320,14 @@ config BF53x
        depends on (BF531 || BF532 || BF533 || BF534 || BF536 || BF537)
        default y
 
+config GPIO_ADI
+       def_bool y
+       depends on (BF51x || BF52x || BF53x || BF538 || BF539 || BF561)
+
+config PINCTRL
+       def_bool y
+       depends on BF54x || BF60x
+
 config MEM_MT48LC64M4A2FB_7E
        bool
        depends on (BFIN533_STAMP)
index 98d0133346b5a57042baa2e494c3906b597fd608..99d338ca2ea420f5874e561fb96122271cf5e37d 100644 (file)
 
 #ifndef __ASSEMBLY__
 
+#ifndef CONFIG_PINCTRL
+
 #include <linux/compiler.h>
-#include <linux/gpio.h>
+#include <asm/blackfin.h>
+#include <asm/portmux.h>
+#include <asm/irq_handler.h>
 
 /***********************************************************
 *
@@ -45,7 +49,6 @@
 * MODIFICATION HISTORY :
 **************************************************************/
 
-#if !BFIN_GPIO_PINT
 void set_gpio_dir(unsigned, unsigned short);
 void set_gpio_inen(unsigned, unsigned short);
 void set_gpio_polar(unsigned, unsigned short);
@@ -115,7 +118,6 @@ struct gpio_port_t {
        unsigned short dummy16;
        unsigned short inen;
 };
-#endif
 
 #ifdef BFIN_SPECIAL_GPIO_BANKS
 void bfin_special_gpio_free(unsigned gpio);
@@ -127,25 +129,21 @@ void bfin_special_gpio_pm_hibernate_suspend(void);
 #endif
 
 #ifdef CONFIG_PM
-int bfin_pm_standby_ctrl(unsigned ctrl);
+void bfin_gpio_pm_hibernate_restore(void);
+void bfin_gpio_pm_hibernate_suspend(void);
+int bfin_gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl);
+int bfin_gpio_pm_standby_ctrl(unsigned ctrl);
 
 static inline int bfin_pm_standby_setup(void)
 {
-       return bfin_pm_standby_ctrl(1);
+       return bfin_gpio_pm_standby_ctrl(1);
 }
 
 static inline void bfin_pm_standby_restore(void)
 {
-       bfin_pm_standby_ctrl(0);
+       bfin_gpio_pm_standby_ctrl(0);
 }
 
-void bfin_gpio_pm_hibernate_restore(void);
-void bfin_gpio_pm_hibernate_suspend(void);
-void bfin_pint_suspend(void);
-void bfin_pint_resume(void);
-
-# if !BFIN_GPIO_PINT
-int gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl);
 
 struct gpio_port_s {
        unsigned short data;
@@ -161,7 +159,6 @@ struct gpio_port_s {
        unsigned short reserved;
        unsigned short mux;
 };
-# endif
 #endif /*CONFIG_PM*/
 
 /***********************************************************
@@ -178,36 +175,29 @@ struct gpio_port_s {
 *************************************************************
 * MODIFICATION HISTORY :
 **************************************************************/
-
-int bfin_gpio_request(unsigned gpio, const char *label);
-void bfin_gpio_free(unsigned gpio);
 int bfin_gpio_irq_request(unsigned gpio, const char *label);
 void bfin_gpio_irq_free(unsigned gpio);
-int bfin_gpio_direction_input(unsigned gpio);
-int bfin_gpio_direction_output(unsigned gpio, int value);
-int bfin_gpio_get_value(unsigned gpio);
-void bfin_gpio_set_value(unsigned gpio, int value);
+void bfin_gpio_irq_prepare(unsigned gpio);
+
+static inline int irq_to_gpio(unsigned irq)
+{
+       return irq - GPIO_IRQ_BASE;
+}
+#endif /* CONFIG_PINCTRL */
 
 #include <asm/irq.h>
 #include <asm/errno.h>
 
-#ifdef CONFIG_GPIOLIB
 #include <asm-generic/gpio.h>          /* cansleep wrappers */
 
 static inline int gpio_get_value(unsigned int gpio)
 {
-       if (gpio < MAX_BLACKFIN_GPIOS)
-               return bfin_gpio_get_value(gpio);
-       else
-               return __gpio_get_value(gpio);
+       return __gpio_get_value(gpio);
 }
 
 static inline void gpio_set_value(unsigned int gpio, int value)
 {
-       if (gpio < MAX_BLACKFIN_GPIOS)
-               bfin_gpio_set_value(gpio, value);
-       else
-               __gpio_set_value(gpio, value);
+       __gpio_set_value(gpio, value);
 }
 
 static inline int gpio_cansleep(unsigned int gpio)
@@ -219,113 +209,6 @@ static inline int gpio_to_irq(unsigned gpio)
 {
        return __gpio_to_irq(gpio);
 }
-
-#else /* !CONFIG_GPIOLIB */
-
-static inline int gpio_request(unsigned gpio, const char *label)
-{
-       return bfin_gpio_request(gpio, label);
-}
-
-static inline void gpio_free(unsigned gpio)
-{
-       return bfin_gpio_free(gpio);
-}
-
-static inline int gpio_direction_input(unsigned gpio)
-{
-       return bfin_gpio_direction_input(gpio);
-}
-
-static inline int gpio_direction_output(unsigned gpio, int value)
-{
-       return bfin_gpio_direction_output(gpio, value);
-}
-
-static inline int gpio_set_debounce(unsigned gpio, unsigned debounce)
-{
-       return -EINVAL;
-}
-
-static inline int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
-{
-       int err;
-
-       err = bfin_gpio_request(gpio, label);
-       if (err)
-               return err;
-
-       if (flags & GPIOF_DIR_IN)
-               err = bfin_gpio_direction_input(gpio);
-       else
-               err = bfin_gpio_direction_output(gpio,
-                       (flags & GPIOF_INIT_HIGH) ? 1 : 0);
-
-       if (err)
-               bfin_gpio_free(gpio);
-
-       return err;
-}
-
-static inline int gpio_request_array(const struct gpio *array, size_t num)
-{
-       int i, err;
-
-       for (i = 0; i < num; i++, array++) {
-               err = gpio_request_one(array->gpio, array->flags, array->label);
-               if (err)
-                       goto err_free;
-       }
-       return 0;
-
-err_free:
-       while (i--)
-               bfin_gpio_free((--array)->gpio);
-       return err;
-}
-
-static inline void gpio_free_array(const struct gpio *array, size_t num)
-{
-       while (num--)
-               bfin_gpio_free((array++)->gpio);
-}
-
-static inline int __gpio_get_value(unsigned gpio)
-{
-       return bfin_gpio_get_value(gpio);
-}
-
-static inline void __gpio_set_value(unsigned gpio, int value)
-{
-       return bfin_gpio_set_value(gpio, value);
-}
-
-static inline int gpio_get_value(unsigned gpio)
-{
-       return __gpio_get_value(gpio);
-}
-
-static inline void gpio_set_value(unsigned gpio, int value)
-{
-       return __gpio_set_value(gpio, value);
-}
-
-static inline int gpio_to_irq(unsigned gpio)
-{
-       if (likely(gpio < MAX_BLACKFIN_GPIOS))
-               return gpio + GPIO_IRQ_BASE;
-
-       return -EINVAL;
-}
-
-#include <asm-generic/gpio.h>          /* cansleep wrappers */
-#endif /* !CONFIG_GPIOLIB */
-
-static inline int irq_to_gpio(unsigned irq)
-{
-       return (irq - GPIO_IRQ_BASE);
-}
-
 #endif /* __ASSEMBLY__ */
 
 #endif /* __ARCH_BLACKFIN_GPIO_H__ */
index 9b1e2c37b324da406aa6587e65c5281deca522a6..7aa20436e7998a283a95e1a3a1a82351ce8ff9d6 100644 (file)
 #define P_MAYSHARE     0x2000
 #define P_DONTCARE     0x1000
 
-
+#ifdef CONFIG_PINCTRL
+#include <asm/irq_handler.h>
+
+#define gpio_pint_regs bfin_pint_regs
+#define adi_internal_set_wake bfin_internal_set_wake
+
+#define peripheral_request(per, label) 0
+#define peripheral_free(per)
+#define peripheral_request_list(per, label) \
+       (pdev ? (IS_ERR(devm_pinctrl_get_select_default(&pdev->dev)) \
+       ? -EINVAL : 0) : 0)
+#define peripheral_free_list(per)
+#else
 int peripheral_request(unsigned short per, const char *label);
 void peripheral_free(unsigned short per);
 int peripheral_request_list(const unsigned short per[], const char *label);
 void peripheral_free_list(const unsigned short per[]);
+#endif
 
-#include <asm/gpio.h>
+#include <linux/err.h>
+#include <linux/pinctrl/pinctrl.h>
 #include <mach/portmux.h>
+#include <linux/gpio.h>
 
 #ifndef P_SPORT2_TFS
 #define P_SPORT2_TFS P_UNDEF
index 735f24e074259b88c8cdd0005cf3ddddcd9175fe..703dc7cf2ecc38a71b5a98e0925c6688cf454eea 100644 (file)
@@ -7,7 +7,7 @@ extra-y := vmlinux.lds
 obj-y := \
        entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \
        sys_bfin.o traps.o irqchip.o dma-mapping.o flat.o \
-       fixed_code.o reboot.o bfin_gpio.o bfin_dma.o \
+       fixed_code.o reboot.o bfin_dma.o \
        exception.o dumpstack.o
 
 ifeq ($(CONFIG_GENERIC_CLOCKEVENTS),y)
@@ -16,6 +16,7 @@ else
     obj-y += time.o
 endif
 
+obj-$(CONFIG_GPIO_ADI)               += bfin_gpio.o
 obj-$(CONFIG_DYNAMIC_FTRACE)         += ftrace.o
 obj-$(CONFIG_FUNCTION_TRACER)        += ftrace-entry.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER)  += ftrace.o
index e22246202730b26e11f39910f4d387ab67c88c74..d9f8632d7d09dea4f4daaaae11910ba50f30a38a 100644 (file)
@@ -7,8 +7,6 @@
 #ifndef _MACH_PORTMUX_H_
 #define _MACH_PORTMUX_H_
 
-#define MAX_RESOURCES  MAX_BLACKFIN_GPIOS
-
 #define P_SPORT2_TFS   (P_DEFINED | P_IDENT(GPIO_PA0) | P_FUNCT(0))
 #define P_SPORT2_DTSEC (P_DEFINED | P_IDENT(GPIO_PA1) | P_FUNCT(0))
 #define P_SPORT2_DTPRI (P_DEFINED | P_IDENT(GPIO_PA2) | P_FUNCT(0))
index 2e1a51c2509829ac293d1df6ffe0d09a9f11e458..fe34191eef0bb00cfac8c9c9338144eb5bdbc804 100644 (file)
@@ -7,8 +7,6 @@
 #ifndef _MACH_PORTMUX_H_
 #define _MACH_PORTMUX_H_
 
-#define MAX_RESOURCES  MAX_BLACKFIN_GPIOS
-
 /* EMAC RMII Port Mux */
 #define P_MII0_MDC     (P_DEFINED | P_IDENT(GPIO_PC6) | P_FUNCT(0))
 #define P_MII0_MDIO    (P_DEFINED | P_IDENT(GPIO_PC7) | P_FUNCT(0))
index 0dfaf20e4dad4175fc7d5f49e6989d609876b123..e78760921bd72d9631ad89814f23fd15faf2331a 100644 (file)
@@ -190,10 +190,15 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
        struct of_phandle_args pinspec;
        struct pinctrl_dev *pctldev;
        int index = 0, ret;
+       const char *name;
+       static const char group_names_propname[] = "gpio-ranges-group-names";
+       struct property *group_names;
 
        if (!np)
                return;
 
+       group_names = of_find_property(np, group_names_propname, NULL);
+
        for (;; index++) {
                ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3,
                                index, &pinspec);
@@ -204,14 +209,56 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
                if (!pctldev)
                        break;
 
-               ret = gpiochip_add_pin_range(chip,
-                                            pinctrl_dev_get_devname(pctldev),
-                                            pinspec.args[0],
-                                            pinspec.args[1],
-                                            pinspec.args[2]);
-
-               if (ret)
-                       break;
+               if (pinspec.args[2]) {
+                       if (group_names) {
+                               ret = of_property_read_string_index(np,
+                                               group_names_propname,
+                                               index, &name);
+                               if (strlen(name)) {
+                                       pr_err("%s: Group name of numeric GPIO ranges must be the empty string.\n",
+                                               np->full_name);
+                                       break;
+                               }
+                       }
+                       /* npins != 0: linear range */
+                       ret = gpiochip_add_pin_range(chip,
+                                       pinctrl_dev_get_devname(pctldev),
+                                       pinspec.args[0],
+                                       pinspec.args[1],
+                                       pinspec.args[2]);
+                       if (ret)
+                               break;
+               } else {
+                       /* npins == 0: special range */
+                       if (pinspec.args[1]) {
+                               pr_err("%s: Illegal gpio-range format.\n",
+                                       np->full_name);
+                               break;
+                       }
+
+                       if (!group_names) {
+                               pr_err("%s: GPIO group range requested but no %s property.\n",
+                                       np->full_name, group_names_propname);
+                               break;
+                       }
+
+                       ret = of_property_read_string_index(np,
+                                               group_names_propname,
+                                               index, &name);
+                       if (ret)
+                               break;
+
+                       if (!strlen(name)) {
+                               pr_err("%s: Group name of GPIO group range cannot be the empty string.\n",
+                               np->full_name);
+                               break;
+                       }
+
+                       ret = gpiochip_add_pingroup_range(chip, pctldev,
+                                               pinspec.args[0], name);
+                       if (ret)
+                               break;
+               }
        }
 }
 
index dadbac2772676c842846944c7d21771e175885e2..4a34ca9c1768ea75fe7c8155bf8c07e2a7a11e7e 100644 (file)
@@ -1319,6 +1319,53 @@ EXPORT_SYMBOL_GPL(gpiochip_find);
 
 #ifdef CONFIG_PINCTRL
 
+/**
+ * gpiochip_add_pingroup_range() - add a range for GPIO <-> pin mapping
+ * @chip: the gpiochip to add the range for
+ * @pinctrl: the dev_name() of the pin controller to map to
+ * @gpio_offset: the start offset in the current gpio_chip number space
+ * @pin_group: name of the pin group inside the pin controller
+ */
+int gpiochip_add_pingroup_range(struct gpio_chip *chip,
+                       struct pinctrl_dev *pctldev,
+                       unsigned int gpio_offset, const char *pin_group)
+{
+       struct gpio_pin_range *pin_range;
+       int ret;
+
+       pin_range = kzalloc(sizeof(*pin_range), GFP_KERNEL);
+       if (!pin_range) {
+               pr_err("%s: GPIO chip: failed to allocate pin ranges\n",
+                               chip->label);
+               return -ENOMEM;
+       }
+
+       /* Use local offset as range ID */
+       pin_range->range.id = gpio_offset;
+       pin_range->range.gc = chip;
+       pin_range->range.name = chip->label;
+       pin_range->range.base = chip->base + gpio_offset;
+       pin_range->pctldev = pctldev;
+
+       ret = pinctrl_get_group_pins(pctldev, pin_group,
+                                       &pin_range->range.pins,
+                                       &pin_range->range.npins);
+       if (ret < 0)
+               return ret;
+
+       pinctrl_add_gpio_range(pctldev, &pin_range->range);
+
+       pr_debug("GPIO chip %s: created GPIO range %d->%d ==> %s PINGRP %s\n",
+                chip->label, gpio_offset,
+                gpio_offset + pin_range->range.npins - 1,
+                pinctrl_dev_get_devname(pctldev), pin_group);
+
+       list_add_tail(&pin_range->node, &chip->pin_ranges);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(gpiochip_add_pingroup_range);
+
 /**
  * gpiochip_add_pin_range() - add a range for GPIO <-> pin mapping
  * @chip: the gpiochip to add the range for
index b6e864e8c9e82df756fc6aa3d227a7e57627c1fa..e283c4970d1d4c822b83d86584f63c1b7fdbef47 100644 (file)
@@ -49,6 +49,35 @@ config PINCTRL_AB8505
        bool "AB8505 pin controller driver"
        depends on PINCTRL_ABX500 && ARCH_U8500
 
+config PINCTRL_ADI2
+       bool "ADI pin controller driver"
+       depends on BLACKFIN
+       select PINMUX
+       select IRQ_DOMAIN
+       help
+         This is the pin controller and gpio driver for ADI BF54x, BF60x and
+         future processors. This option is selected automatically when specific
+         machine and arch are selected to build.
+
+config PINCTRL_AS3722
+       bool "Pinctrl and GPIO driver for ams AS3722 PMIC"
+       depends on MFD_AS3722 && GPIOLIB
+       select PINMUX
+       select GENERIC_PINCONF
+       help
+         AS3722 device supports the configuration of GPIO pins for different
+         functionality. This driver supports the pinmux, push-pull and
+         open drain configuration for the GPIO pins of AS3722 devices. It also
+         supports the GPIO functionality through gpiolib.
+
+config PINCTRL_BF54x
+       def_bool y if BF54x
+       select PINCTRL_ADI2
+
+config PINCTRL_BF60x
+       def_bool y if BF60x
+       select PINCTRL_ADI2
+
 config PINCTRL_AT91
        bool "AT91 pinctrl driver"
        depends on OF
@@ -292,6 +321,10 @@ config PINCTRL_XWAY
        depends on SOC_TYPE_XWAY
        depends on PINCTRL_LANTIQ
 
+config PINCTRL_TB10X
+       bool
+       depends on ARC_PLAT_TB10X
+
 endmenu
 
 endif
index 496d9bf9e1b993cececd44c0513aef3ec77c095a..8476cd9020692c621cc539550aa2db453fd8dc8b 100644 (file)
@@ -14,6 +14,10 @@ obj-$(CONFIG_PINCTRL_AB8500) += pinctrl-ab8500.o
 obj-$(CONFIG_PINCTRL_AB8540)   += pinctrl-ab8540.o
 obj-$(CONFIG_PINCTRL_AB9540)   += pinctrl-ab9540.o
 obj-$(CONFIG_PINCTRL_AB8505)   += pinctrl-ab8505.o
+obj-$(CONFIG_PINCTRL_ADI2)     += pinctrl-adi2.o
+obj-$(CONFIG_PINCTRL_AS3722)   += pinctrl-as3722.o
+obj-$(CONFIG_PINCTRL_BF54x)    += pinctrl-adi2-bf54x.o
+obj-$(CONFIG_PINCTRL_BF60x)    += pinctrl-adi2-bf60x.o
 obj-$(CONFIG_PINCTRL_AT91)     += pinctrl-at91.o
 obj-$(CONFIG_PINCTRL_BCM2835)  += pinctrl-bcm2835.o
 obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o
@@ -52,6 +56,7 @@ obj-$(CONFIG_PINCTRL_S3C24XX) += pinctrl-s3c24xx.o
 obj-$(CONFIG_PINCTRL_S3C64XX)  += pinctrl-s3c64xx.o
 obj-$(CONFIG_PINCTRL_XWAY)     += pinctrl-xway.o
 obj-$(CONFIG_PINCTRL_LANTIQ)   += pinctrl-lantiq.o
+obj-$(CONFIG_PINCTRL_TB10X)    += pinctrl-tb10x.o
 obj-$(CONFIG_PINCTRL_ST)       += pinctrl-st.o
 obj-$(CONFIG_PINCTRL_VF610)    += pinctrl-vf610.o
 
index 92f86ab30a1385993ccaaf4b17018f9dad26f9ad..5ee61a470016fa8f2753cf21fc2e6ff0966d8d78 100644 (file)
@@ -462,6 +462,20 @@ struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname,
 }
 EXPORT_SYMBOL_GPL(pinctrl_find_and_add_gpio_range);
 
+int pinctrl_get_group_pins(struct pinctrl_dev *pctldev, const char *pin_group,
+                               const unsigned **pins, unsigned *num_pins)
+{
+       const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
+       int gs;
+
+       gs = pinctrl_get_group_selector(pctldev, pin_group);
+       if (gs < 0)
+               return gs;
+
+       return pctlops->get_group_pins(pctldev, gs, pins, num_pins);
+}
+EXPORT_SYMBOL_GPL(pinctrl_get_group_pins);
+
 /**
  * pinctrl_find_gpio_range_from_pin() - locate the GPIO range for a pin
  * @pctldev: the pin controller device to look in
index 48e21a2294830f4ad3379ae3f6973bb944e82962..ae1f760cbdd2b28cae4c0aa17f2fae0cba0fd50f 100644 (file)
@@ -408,7 +408,7 @@ static struct platform_driver armada_370_pinctrl_driver = {
        .driver = {
                .name = "armada-370-pinctrl",
                .owner = THIS_MODULE,
-               .of_match_table = of_match_ptr(armada_370_pinctrl_of_match),
+               .of_match_table = armada_370_pinctrl_of_match,
        },
        .probe = armada_370_pinctrl_probe,
        .remove = armada_370_pinctrl_remove,
index ab5dc04b3e8a1fc961a1766461f06c67e002cb2f..843a51f9d129c2d1ac6c95c202a06b07bcd24c06 100644 (file)
@@ -455,7 +455,7 @@ static struct platform_driver armada_xp_pinctrl_driver = {
        .driver = {
                .name = "armada-xp-pinctrl",
                .owner = THIS_MODULE,
-               .of_match_table = of_match_ptr(armada_xp_pinctrl_of_match),
+               .of_match_table = armada_xp_pinctrl_of_match,
        },
        .probe = armada_xp_pinctrl_probe,
        .remove = armada_xp_pinctrl_remove,
index 29f7e4fc7ca5a8e8e34281484f2caafbe476b74f..47268393af34689832fd189bde3c9da27eb6c090 100644 (file)
@@ -335,7 +335,7 @@ static int dove_twsi_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
        unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
 
        gcfg1 &= ~DOVE_TWSI_ENABLE_OPTION1;
-       gcfg2 &= ~(DOVE_TWSI_ENABLE_OPTION2 | DOVE_TWSI_ENABLE_OPTION2);
+       gcfg2 &= ~(DOVE_TWSI_ENABLE_OPTION2 | DOVE_TWSI_ENABLE_OPTION3);
 
        switch (config) {
        case 1:
@@ -806,7 +806,7 @@ static struct platform_driver dove_pinctrl_driver = {
        .driver = {
                .name = "dove-pinctrl",
                .owner = THIS_MODULE,
-               .of_match_table = of_match_ptr(dove_pinctrl_of_match),
+               .of_match_table = dove_pinctrl_of_match,
        },
        .probe = dove_pinctrl_probe,
        .remove = dove_pinctrl_remove,
index cdd483df673eaf5d38d522ba3e8f5ef26f835c3c..6b504b5935a5ec75ecff507a0717e82af4b72982 100644 (file)
@@ -471,7 +471,7 @@ static struct platform_driver kirkwood_pinctrl_driver = {
        .driver = {
                .name = "kirkwood-pinctrl",
                .owner = THIS_MODULE,
-               .of_match_table = of_match_ptr(kirkwood_pinctrl_of_match),
+               .of_match_table = kirkwood_pinctrl_of_match,
        },
        .probe = kirkwood_pinctrl_probe,
        .remove = kirkwood_pinctrl_remove,
diff --git a/drivers/pinctrl/pinctrl-adi2-bf54x.c b/drivers/pinctrl/pinctrl-adi2-bf54x.c
new file mode 100644 (file)
index 0000000..ea9d9ab
--- /dev/null
@@ -0,0 +1,592 @@
+/*
+ * Pinctrl Driver for ADI GPIO2 controller
+ *
+ * Copyright 2007-2013 Analog Devices Inc.
+ *
+ * Licensed under the GPLv2 or later
+ */
+
+#include <asm/portmux.h>
+#include "pinctrl-adi2.h"
+
+static const struct pinctrl_pin_desc adi_pads[] = {
+       PINCTRL_PIN(0, "PA0"),
+       PINCTRL_PIN(1, "PA1"),
+       PINCTRL_PIN(2, "PA2"),
+       PINCTRL_PIN(3, "PG3"),
+       PINCTRL_PIN(4, "PA4"),
+       PINCTRL_PIN(5, "PA5"),
+       PINCTRL_PIN(6, "PA6"),
+       PINCTRL_PIN(7, "PA7"),
+       PINCTRL_PIN(8, "PA8"),
+       PINCTRL_PIN(9, "PA9"),
+       PINCTRL_PIN(10, "PA10"),
+       PINCTRL_PIN(11, "PA11"),
+       PINCTRL_PIN(12, "PA12"),
+       PINCTRL_PIN(13, "PA13"),
+       PINCTRL_PIN(14, "PA14"),
+       PINCTRL_PIN(15, "PA15"),
+       PINCTRL_PIN(16, "PB0"),
+       PINCTRL_PIN(17, "PB1"),
+       PINCTRL_PIN(18, "PB2"),
+       PINCTRL_PIN(19, "PB3"),
+       PINCTRL_PIN(20, "PB4"),
+       PINCTRL_PIN(21, "PB5"),
+       PINCTRL_PIN(22, "PB6"),
+       PINCTRL_PIN(23, "PB7"),
+       PINCTRL_PIN(24, "PB8"),
+       PINCTRL_PIN(25, "PB9"),
+       PINCTRL_PIN(26, "PB10"),
+       PINCTRL_PIN(27, "PB11"),
+       PINCTRL_PIN(28, "PB12"),
+       PINCTRL_PIN(29, "PB13"),
+       PINCTRL_PIN(30, "PB14"),
+       PINCTRL_PIN(32, "PC0"),
+       PINCTRL_PIN(33, "PC1"),
+       PINCTRL_PIN(34, "PC2"),
+       PINCTRL_PIN(35, "PC3"),
+       PINCTRL_PIN(36, "PC4"),
+       PINCTRL_PIN(37, "PC5"),
+       PINCTRL_PIN(38, "PC6"),
+       PINCTRL_PIN(39, "PC7"),
+       PINCTRL_PIN(40, "PC8"),
+       PINCTRL_PIN(41, "PC9"),
+       PINCTRL_PIN(42, "PC10"),
+       PINCTRL_PIN(43, "PC11"),
+       PINCTRL_PIN(44, "PC12"),
+       PINCTRL_PIN(45, "PC13"),
+       PINCTRL_PIN(48, "PD0"),
+       PINCTRL_PIN(49, "PD1"),
+       PINCTRL_PIN(50, "PD2"),
+       PINCTRL_PIN(51, "PD3"),
+       PINCTRL_PIN(52, "PD4"),
+       PINCTRL_PIN(53, "PD5"),
+       PINCTRL_PIN(54, "PD6"),
+       PINCTRL_PIN(55, "PD7"),
+       PINCTRL_PIN(56, "PD8"),
+       PINCTRL_PIN(57, "PD9"),
+       PINCTRL_PIN(58, "PD10"),
+       PINCTRL_PIN(59, "PD11"),
+       PINCTRL_PIN(60, "PD12"),
+       PINCTRL_PIN(61, "PD13"),
+       PINCTRL_PIN(62, "PD14"),
+       PINCTRL_PIN(63, "PD15"),
+       PINCTRL_PIN(64, "PE0"),
+       PINCTRL_PIN(65, "PE1"),
+       PINCTRL_PIN(66, "PE2"),
+       PINCTRL_PIN(67, "PE3"),
+       PINCTRL_PIN(68, "PE4"),
+       PINCTRL_PIN(69, "PE5"),
+       PINCTRL_PIN(70, "PE6"),
+       PINCTRL_PIN(71, "PE7"),
+       PINCTRL_PIN(72, "PE8"),
+       PINCTRL_PIN(73, "PE9"),
+       PINCTRL_PIN(74, "PE10"),
+       PINCTRL_PIN(75, "PE11"),
+       PINCTRL_PIN(76, "PE12"),
+       PINCTRL_PIN(77, "PE13"),
+       PINCTRL_PIN(78, "PE14"),
+       PINCTRL_PIN(79, "PE15"),
+       PINCTRL_PIN(80, "PF0"),
+       PINCTRL_PIN(81, "PF1"),
+       PINCTRL_PIN(82, "PF2"),
+       PINCTRL_PIN(83, "PF3"),
+       PINCTRL_PIN(84, "PF4"),
+       PINCTRL_PIN(85, "PF5"),
+       PINCTRL_PIN(86, "PF6"),
+       PINCTRL_PIN(87, "PF7"),
+       PINCTRL_PIN(88, "PF8"),
+       PINCTRL_PIN(89, "PF9"),
+       PINCTRL_PIN(90, "PF10"),
+       PINCTRL_PIN(91, "PF11"),
+       PINCTRL_PIN(92, "PF12"),
+       PINCTRL_PIN(93, "PF13"),
+       PINCTRL_PIN(94, "PF14"),
+       PINCTRL_PIN(95, "PF15"),
+       PINCTRL_PIN(96, "PG0"),
+       PINCTRL_PIN(97, "PG1"),
+       PINCTRL_PIN(98, "PG2"),
+       PINCTRL_PIN(99, "PG3"),
+       PINCTRL_PIN(100, "PG4"),
+       PINCTRL_PIN(101, "PG5"),
+       PINCTRL_PIN(102, "PG6"),
+       PINCTRL_PIN(103, "PG7"),
+       PINCTRL_PIN(104, "PG8"),
+       PINCTRL_PIN(105, "PG9"),
+       PINCTRL_PIN(106, "PG10"),
+       PINCTRL_PIN(107, "PG11"),
+       PINCTRL_PIN(108, "PG12"),
+       PINCTRL_PIN(109, "PG13"),
+       PINCTRL_PIN(110, "PG14"),
+       PINCTRL_PIN(111, "PG15"),
+       PINCTRL_PIN(112, "PH0"),
+       PINCTRL_PIN(113, "PH1"),
+       PINCTRL_PIN(114, "PH2"),
+       PINCTRL_PIN(115, "PH3"),
+       PINCTRL_PIN(116, "PH4"),
+       PINCTRL_PIN(117, "PH5"),
+       PINCTRL_PIN(118, "PH6"),
+       PINCTRL_PIN(119, "PH7"),
+       PINCTRL_PIN(120, "PH8"),
+       PINCTRL_PIN(121, "PH9"),
+       PINCTRL_PIN(122, "PH10"),
+       PINCTRL_PIN(123, "PH11"),
+       PINCTRL_PIN(124, "PH12"),
+       PINCTRL_PIN(125, "PH13"),
+       PINCTRL_PIN(128, "PI0"),
+       PINCTRL_PIN(129, "PI1"),
+       PINCTRL_PIN(130, "PI2"),
+       PINCTRL_PIN(131, "PI3"),
+       PINCTRL_PIN(132, "PI4"),
+       PINCTRL_PIN(133, "PI5"),
+       PINCTRL_PIN(134, "PI6"),
+       PINCTRL_PIN(135, "PI7"),
+       PINCTRL_PIN(136, "PI8"),
+       PINCTRL_PIN(137, "PI9"),
+       PINCTRL_PIN(138, "PI10"),
+       PINCTRL_PIN(139, "PI11"),
+       PINCTRL_PIN(140, "PI12"),
+       PINCTRL_PIN(141, "PI13"),
+       PINCTRL_PIN(142, "PI14"),
+       PINCTRL_PIN(143, "PI15"),
+       PINCTRL_PIN(144, "PJ0"),
+       PINCTRL_PIN(145, "PJ1"),
+       PINCTRL_PIN(146, "PJ2"),
+       PINCTRL_PIN(147, "PJ3"),
+       PINCTRL_PIN(148, "PJ4"),
+       PINCTRL_PIN(149, "PJ5"),
+       PINCTRL_PIN(150, "PJ6"),
+       PINCTRL_PIN(151, "PJ7"),
+       PINCTRL_PIN(152, "PJ8"),
+       PINCTRL_PIN(153, "PJ9"),
+       PINCTRL_PIN(154, "PJ10"),
+       PINCTRL_PIN(155, "PJ11"),
+       PINCTRL_PIN(156, "PJ12"),
+       PINCTRL_PIN(157, "PJ13"),
+};
+
+static const unsigned uart0_pins[] = {
+       GPIO_PE7, GPIO_PE8,
+};
+
+static const unsigned uart1_pins[] = {
+       GPIO_PH0, GPIO_PH1,
+};
+
+static const unsigned uart1_ctsrts_pins[] = {
+       GPIO_PE9, GPIO_PE10,
+};
+
+static const unsigned uart2_pins[] = {
+       GPIO_PB4, GPIO_PB5,
+};
+
+static const unsigned uart3_pins[] = {
+       GPIO_PB6, GPIO_PB7,
+};
+
+static const unsigned uart3_ctsrts_pins[] = {
+       GPIO_PB2, GPIO_PB3,
+};
+
+static const unsigned rsi0_pins[] = {
+       GPIO_PC8, GPIO_PC9, GPIO_PC10, GPIO_PC11, GPIO_PC12, GPIO_PC13,
+};
+
+static const unsigned spi0_pins[] = {
+       GPIO_PE0, GPIO_PE1, GPIO_PE2,
+};
+
+static const unsigned spi1_pins[] = {
+       GPIO_PG8, GPIO_PG9, GPIO_PG10,
+};
+
+static const unsigned twi0_pins[] = {
+       GPIO_PE14, GPIO_PE15,
+};
+
+static const unsigned twi1_pins[] = {
+       GPIO_PB0, GPIO_PB1,
+};
+
+static const unsigned rotary_pins[] = {
+       GPIO_PH4, GPIO_PH3, GPIO_PH5,
+};
+
+static const unsigned can0_pins[] = {
+       GPIO_PG13, GPIO_PG12,
+};
+
+static const unsigned can1_pins[] = {
+       GPIO_PG14, GPIO_PG15,
+};
+
+static const unsigned smc0_pins[] = {
+       GPIO_PH8, GPIO_PH9, GPIO_PH10, GPIO_PH11, GPIO_PH12, GPIO_PH13,
+       GPIO_PI0, GPIO_PI1, GPIO_PI2, GPIO_PI3, GPIO_PI4, GPIO_PI5, GPIO_PI6,
+       GPIO_PI7, GPIO_PI8, GPIO_PI9, GPIO_PI10, GPIO_PI11,
+       GPIO_PI12, GPIO_PI13, GPIO_PI14, GPIO_PI15,
+};
+
+static const unsigned sport0_pins[] = {
+       GPIO_PC0, GPIO_PC2, GPIO_PC3, GPIO_PC4, GPIO_PC6, GPIO_PC7,
+};
+
+static const unsigned sport1_pins[] = {
+       GPIO_PD0, GPIO_PD2, GPIO_PD3, GPIO_PD4, GPIO_PD6, GPIO_PD7,
+};
+
+static const unsigned sport2_pins[] = {
+       GPIO_PA0, GPIO_PA2, GPIO_PA3, GPIO_PA4, GPIO_PA6, GPIO_PA7,
+};
+
+static const unsigned sport3_pins[] = {
+       GPIO_PA8, GPIO_PA10, GPIO_PA11, GPIO_PA12, GPIO_PA14, GPIO_PA15,
+};
+
+static const unsigned ppi0_8b_pins[] = {
+       GPIO_PF0, GPIO_PF1, GPIO_PF2, GPIO_PF3, GPIO_PF4, GPIO_PF5, GPIO_PF6,
+       GPIO_PF7, GPIO_PF13, GPIO_PG0, GPIO_PG1, GPIO_PG2,
+};
+
+static const unsigned ppi0_16b_pins[] = {
+       GPIO_PF0, GPIO_PF1, GPIO_PF2, GPIO_PF3, GPIO_PF4, GPIO_PF5, GPIO_PF6,
+       GPIO_PF7, GPIO_PF9, GPIO_PF10, GPIO_PF11, GPIO_PF12,
+       GPIO_PF13, GPIO_PF14, GPIO_PF15,
+       GPIO_PG0, GPIO_PG1, GPIO_PG2,
+};
+
+static const unsigned ppi0_24b_pins[] = {
+       GPIO_PF0, GPIO_PF1, GPIO_PF2, GPIO_PF3, GPIO_PF4, GPIO_PF5, GPIO_PF6,
+       GPIO_PF7, GPIO_PF8, GPIO_PF9, GPIO_PF10, GPIO_PF11, GPIO_PF12,
+       GPIO_PF13, GPIO_PF14, GPIO_PF15, GPIO_PD0, GPIO_PD1, GPIO_PD2,
+       GPIO_PD3, GPIO_PD4, GPIO_PD5, GPIO_PG3, GPIO_PG4,
+       GPIO_PG0, GPIO_PG1, GPIO_PG2,
+};
+
+static const unsigned ppi1_8b_pins[] = {
+       GPIO_PD0, GPIO_PD1, GPIO_PD2, GPIO_PD3, GPIO_PD4, GPIO_PD5, GPIO_PD6,
+       GPIO_PD7, GPIO_PE11, GPIO_PE12, GPIO_PE13,
+};
+
+static const unsigned ppi1_16b_pins[] = {
+       GPIO_PD0, GPIO_PD1, GPIO_PD2, GPIO_PD3, GPIO_PD4, GPIO_PD5, GPIO_PD6,
+       GPIO_PD7, GPIO_PD8, GPIO_PD9, GPIO_PD10, GPIO_PD11, GPIO_PD12,
+       GPIO_PD13, GPIO_PD14, GPIO_PD15,
+       GPIO_PE11, GPIO_PE12, GPIO_PE13,
+};
+
+static const unsigned ppi2_8b_pins[] = {
+       GPIO_PD8, GPIO_PD9, GPIO_PD10, GPIO_PD11, GPIO_PD12,
+       GPIO_PD13, GPIO_PD14, GPIO_PD15,
+       GPIO_PA7, GPIO_PB0, GPIO_PB1, GPIO_PB2, GPIO_PB3,
+};
+
+static const unsigned atapi_pins[] = {
+       GPIO_PH2, GPIO_PJ3, GPIO_PJ4, GPIO_PJ5, GPIO_PJ6,
+       GPIO_PJ7, GPIO_PJ8, GPIO_PJ9, GPIO_PJ10,
+};
+
+static const unsigned atapi_alter_pins[] = {
+       GPIO_PF0, GPIO_PF1, GPIO_PF2, GPIO_PF3, GPIO_PF4, GPIO_PF5, GPIO_PF6,
+       GPIO_PF7, GPIO_PF8, GPIO_PF9, GPIO_PF10, GPIO_PF11, GPIO_PF12,
+       GPIO_PF13, GPIO_PF14, GPIO_PF15, GPIO_PG2, GPIO_PG3, GPIO_PG4,
+};
+
+static const unsigned nfc0_pins[] = {
+       GPIO_PJ1, GPIO_PJ2,
+};
+
+static const unsigned keys_4x4_pins[] = {
+       GPIO_PD8, GPIO_PD9, GPIO_PD10, GPIO_PD11,
+       GPIO_PD12, GPIO_PD13, GPIO_PD14, GPIO_PD15,
+};
+
+static const unsigned keys_8x8_pins[] = {
+       GPIO_PD8, GPIO_PD9, GPIO_PD10, GPIO_PD11,
+       GPIO_PD12, GPIO_PD13, GPIO_PD14, GPIO_PD15,
+       GPIO_PE0, GPIO_PE1, GPIO_PE2, GPIO_PE3,
+       GPIO_PE4, GPIO_PE5, GPIO_PE6, GPIO_PE7,
+};
+
+static const struct adi_pin_group adi_pin_groups[] = {
+       ADI_PIN_GROUP("uart0grp", uart0_pins),
+       ADI_PIN_GROUP("uart1grp", uart1_pins),
+       ADI_PIN_GROUP("uart1ctsrtsgrp", uart1_ctsrts_pins),
+       ADI_PIN_GROUP("uart2grp", uart2_pins),
+       ADI_PIN_GROUP("uart3grp", uart3_pins),
+       ADI_PIN_GROUP("uart3ctsrtsgrp", uart3_ctsrts_pins),
+       ADI_PIN_GROUP("rsi0grp", rsi0_pins),
+       ADI_PIN_GROUP("spi0grp", spi0_pins),
+       ADI_PIN_GROUP("spi1grp", spi1_pins),
+       ADI_PIN_GROUP("twi0grp", twi0_pins),
+       ADI_PIN_GROUP("twi1grp", twi1_pins),
+       ADI_PIN_GROUP("rotarygrp", rotary_pins),
+       ADI_PIN_GROUP("can0grp", can0_pins),
+       ADI_PIN_GROUP("can1grp", can1_pins),
+       ADI_PIN_GROUP("smc0grp", smc0_pins),
+       ADI_PIN_GROUP("sport0grp", sport0_pins),
+       ADI_PIN_GROUP("sport1grp", sport1_pins),
+       ADI_PIN_GROUP("sport2grp", sport2_pins),
+       ADI_PIN_GROUP("sport3grp", sport3_pins),
+       ADI_PIN_GROUP("ppi0_8bgrp", ppi0_8b_pins),
+       ADI_PIN_GROUP("ppi0_16bgrp", ppi0_16b_pins),
+       ADI_PIN_GROUP("ppi0_24bgrp", ppi0_24b_pins),
+       ADI_PIN_GROUP("ppi1_8bgrp", ppi1_8b_pins),
+       ADI_PIN_GROUP("ppi1_16bgrp", ppi1_16b_pins),
+       ADI_PIN_GROUP("ppi2_8bgrp", ppi2_8b_pins),
+       ADI_PIN_GROUP("atapigrp", atapi_pins),
+       ADI_PIN_GROUP("atapialtergrp", atapi_alter_pins),
+       ADI_PIN_GROUP("nfc0grp", nfc0_pins),
+       ADI_PIN_GROUP("keys_4x4grp", keys_4x4_pins),
+       ADI_PIN_GROUP("keys_8x8grp", keys_8x8_pins),
+};
+
+static const unsigned short uart0_mux[] = {
+       P_UART0_TX, P_UART0_RX,
+       0
+};
+
+static const unsigned short uart1_mux[] = {
+       P_UART1_TX, P_UART1_RX,
+       0
+};
+
+static const unsigned short uart1_ctsrts_mux[] = {
+       P_UART1_RTS, P_UART1_CTS,
+       0
+};
+
+static const unsigned short uart2_mux[] = {
+       P_UART2_TX, P_UART2_RX,
+       0
+};
+
+static const unsigned short uart3_mux[] = {
+       P_UART3_TX, P_UART3_RX,
+       0
+};
+
+static const unsigned short uart3_ctsrts_mux[] = {
+       P_UART3_RTS, P_UART3_CTS,
+       0
+};
+
+static const unsigned short rsi0_mux[] = {
+       P_SD_D0, P_SD_D1, P_SD_D2, P_SD_D3, P_SD_CLK, P_SD_CMD,
+       0
+};
+
+static const unsigned short spi0_mux[] = {
+       P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0
+};
+
+static const unsigned short spi1_mux[] = {
+       P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0
+};
+
+static const unsigned short twi0_mux[] = {
+       P_TWI0_SCL, P_TWI0_SDA, 0
+};
+
+static const unsigned short twi1_mux[] = {
+       P_TWI1_SCL, P_TWI1_SDA, 0
+};
+
+static const unsigned short rotary_mux[] = {
+       P_CNT_CUD, P_CNT_CDG, P_CNT_CZM, 0
+};
+
+static const unsigned short sport0_mux[] = {
+       P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+       P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0
+};
+
+static const unsigned short sport1_mux[] = {
+       P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+       P_SPORT1_DRPRI, P_SPORT1_RSCLK, 0
+};
+
+static const unsigned short sport2_mux[] = {
+       P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, P_SPORT2_RFS,
+       P_SPORT2_DRPRI, P_SPORT2_RSCLK, 0
+};
+
+static const unsigned short sport3_mux[] = {
+       P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, P_SPORT3_RFS,
+       P_SPORT3_DRPRI, P_SPORT3_RSCLK, 0
+};
+
+static const unsigned short can0_mux[] = {
+       P_CAN0_RX, P_CAN0_TX, 0
+};
+
+static const unsigned short can1_mux[] = {
+       P_CAN1_RX, P_CAN1_TX, 0
+};
+
+static const unsigned short smc0_mux[] = {
+       P_A4, P_A5, P_A6, P_A7, P_A8, P_A9, P_A10, P_A11, P_A12,
+       P_A13, P_A14, P_A15, P_A16, P_A17, P_A18, P_A19, P_A20, P_A21,
+       P_A22, P_A23, P_A24, P_A25, P_NOR_CLK, 0,
+};
+
+static const unsigned short ppi0_8b_mux[] = {
+       P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, P_PPI0_D3,
+       P_PPI0_D4, P_PPI0_D5, P_PPI0_D6, P_PPI0_D7,
+       P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2,
+       0,
+};
+
+static const unsigned short ppi0_16b_mux[] = {
+       P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, P_PPI0_D3,
+       P_PPI0_D4, P_PPI0_D5, P_PPI0_D6, P_PPI0_D7,
+       P_PPI0_D8, P_PPI0_D9, P_PPI0_D10, P_PPI0_D11,
+       P_PPI0_D12, P_PPI0_D13, P_PPI0_D14, P_PPI0_D15,
+       P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2,
+       0,
+};
+
+static const unsigned short ppi0_24b_mux[] = {
+       P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, P_PPI0_D3,
+       P_PPI0_D4, P_PPI0_D5, P_PPI0_D6, P_PPI0_D7,
+       P_PPI0_D8, P_PPI0_D9, P_PPI0_D10, P_PPI0_D11,
+       P_PPI0_D12, P_PPI0_D13, P_PPI0_D14, P_PPI0_D15,
+       P_PPI0_D16, P_PPI0_D17, P_PPI0_D18, P_PPI0_D19,
+       P_PPI0_D20, P_PPI0_D21, P_PPI0_D22, P_PPI0_D23,
+       P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2,
+       0,
+};
+
+static const unsigned short ppi1_8b_mux[] = {
+       P_PPI1_D0, P_PPI1_D1, P_PPI1_D2, P_PPI1_D3,
+       P_PPI1_D4, P_PPI1_D5, P_PPI1_D6, P_PPI1_D7,
+       P_PPI1_CLK, P_PPI1_FS1, P_PPI1_FS2,
+       0,
+};
+
+static const unsigned short ppi1_16b_mux[] = {
+       P_PPI1_D0, P_PPI1_D1, P_PPI1_D2, P_PPI1_D3,
+       P_PPI1_D4, P_PPI1_D5, P_PPI1_D6, P_PPI1_D7,
+       P_PPI1_D8, P_PPI1_D9, P_PPI1_D10, P_PPI1_D11,
+       P_PPI1_D12, P_PPI1_D13, P_PPI1_D14, P_PPI1_D15,
+       P_PPI1_CLK, P_PPI1_FS1, P_PPI1_FS2,
+       0,
+};
+
+static const unsigned short ppi2_8b_mux[] = {
+       P_PPI2_D0, P_PPI2_D1, P_PPI2_D2, P_PPI2_D3,
+       P_PPI2_D4, P_PPI2_D5, P_PPI2_D6, P_PPI2_D7,
+       P_PPI2_CLK, P_PPI2_FS1, P_PPI2_FS2,
+       0,
+};
+
+static const unsigned short atapi_mux[] = {
+       P_ATAPI_RESET, P_ATAPI_DIOR, P_ATAPI_DIOW, P_ATAPI_CS0, P_ATAPI_CS1,
+       P_ATAPI_DMACK, P_ATAPI_DMARQ, P_ATAPI_INTRQ, P_ATAPI_IORDY,
+};
+
+static const unsigned short atapi_alter_mux[] = {
+       P_ATAPI_D0A, P_ATAPI_D1A, P_ATAPI_D2A, P_ATAPI_D3A, P_ATAPI_D4A,
+       P_ATAPI_D5A, P_ATAPI_D6A, P_ATAPI_D7A, P_ATAPI_D8A, P_ATAPI_D9A,
+       P_ATAPI_D10A, P_ATAPI_D11A, P_ATAPI_D12A, P_ATAPI_D13A, P_ATAPI_D14A,
+       P_ATAPI_D15A, P_ATAPI_A0A, P_ATAPI_A1A, P_ATAPI_A2A,
+       0
+};
+
+static const unsigned short nfc0_mux[] = {
+       P_NAND_CE, P_NAND_RB,
+       0
+};
+
+static const unsigned short keys_4x4_mux[] = {
+       P_KEY_ROW3, P_KEY_ROW2, P_KEY_ROW1, P_KEY_ROW0,
+       P_KEY_COL3, P_KEY_COL2, P_KEY_COL1, P_KEY_COL0,
+       0
+};
+
+static const unsigned short keys_8x8_mux[] = {
+       P_KEY_ROW7, P_KEY_ROW6, P_KEY_ROW5, P_KEY_ROW4,
+       P_KEY_ROW3, P_KEY_ROW2, P_KEY_ROW1, P_KEY_ROW0,
+       P_KEY_COL7, P_KEY_COL6, P_KEY_COL5, P_KEY_COL4,
+       P_KEY_COL3, P_KEY_COL2, P_KEY_COL1, P_KEY_COL0,
+       0
+};
+
+static const char * const uart0grp[] = { "uart0grp" };
+static const char * const uart1grp[] = { "uart1grp" };
+static const char * const uart1ctsrtsgrp[] = { "uart1ctsrtsgrp" };
+static const char * const uart2grp[] = { "uart2grp" };
+static const char * const uart3grp[] = { "uart3grp" };
+static const char * const uart3ctsrtsgrp[] = { "uart3ctsrtsgrp" };
+static const char * const rsi0grp[] = { "rsi0grp" };
+static const char * const spi0grp[] = { "spi0grp" };
+static const char * const spi1grp[] = { "spi1grp" };
+static const char * const twi0grp[] = { "twi0grp" };
+static const char * const twi1grp[] = { "twi1grp" };
+static const char * const rotarygrp[] = { "rotarygrp" };
+static const char * const can0grp[] = { "can0grp" };
+static const char * const can1grp[] = { "can1grp" };
+static const char * const smc0grp[] = { "smc0grp" };
+static const char * const sport0grp[] = { "sport0grp" };
+static const char * const sport1grp[] = { "sport1grp" };
+static const char * const sport2grp[] = { "sport2grp" };
+static const char * const sport3grp[] = { "sport3grp" };
+static const char * const ppi0_8bgrp[] = { "ppi0_8bgrp" };
+static const char * const ppi0_16bgrp[] = { "ppi0_16bgrp" };
+static const char * const ppi0_24bgrp[] = { "ppi0_24bgrp" };
+static const char * const ppi1_8bgrp[] = { "ppi1_8bgrp" };
+static const char * const ppi1_16bgrp[] = { "ppi1_16bgrp" };
+static const char * const ppi2_8bgrp[] = { "ppi2_8bgrp" };
+static const char * const atapigrp[] = { "atapigrp" };
+static const char * const atapialtergrp[] = { "atapialtergrp" };
+static const char * const nfc0grp[] = { "nfc0grp" };
+static const char * const keys_4x4grp[] = { "keys_4x4grp" };
+static const char * const keys_8x8grp[] = { "keys_8x8grp" };
+
+static const struct adi_pmx_func adi_pmx_functions[] = {
+       ADI_PMX_FUNCTION("uart0", uart0grp, uart0_mux),
+       ADI_PMX_FUNCTION("uart1", uart1grp, uart1_mux),
+       ADI_PMX_FUNCTION("uart1_ctsrts", uart1ctsrtsgrp, uart1_ctsrts_mux),
+       ADI_PMX_FUNCTION("uart2", uart2grp, uart2_mux),
+       ADI_PMX_FUNCTION("uart3", uart3grp, uart3_mux),
+       ADI_PMX_FUNCTION("uart3_ctsrts", uart3ctsrtsgrp, uart3_ctsrts_mux),
+       ADI_PMX_FUNCTION("rsi0", rsi0grp, rsi0_mux),
+       ADI_PMX_FUNCTION("spi0", spi0grp, spi0_mux),
+       ADI_PMX_FUNCTION("spi1", spi1grp, spi1_mux),
+       ADI_PMX_FUNCTION("twi0", twi0grp, twi0_mux),
+       ADI_PMX_FUNCTION("twi1", twi1grp, twi1_mux),
+       ADI_PMX_FUNCTION("rotary", rotarygrp, rotary_mux),
+       ADI_PMX_FUNCTION("can0", can0grp, can0_mux),
+       ADI_PMX_FUNCTION("can1", can1grp, can1_mux),
+       ADI_PMX_FUNCTION("smc0", smc0grp, smc0_mux),
+       ADI_PMX_FUNCTION("sport0", sport0grp, sport0_mux),
+       ADI_PMX_FUNCTION("sport1", sport1grp, sport1_mux),
+       ADI_PMX_FUNCTION("sport2", sport2grp, sport2_mux),
+       ADI_PMX_FUNCTION("sport3", sport3grp, sport3_mux),
+       ADI_PMX_FUNCTION("ppi0_8b", ppi0_8bgrp, ppi0_8b_mux),
+       ADI_PMX_FUNCTION("ppi0_16b", ppi0_16bgrp, ppi0_16b_mux),
+       ADI_PMX_FUNCTION("ppi0_24b", ppi0_24bgrp, ppi0_24b_mux),
+       ADI_PMX_FUNCTION("ppi1_8b", ppi1_8bgrp, ppi1_8b_mux),
+       ADI_PMX_FUNCTION("ppi1_16b", ppi1_16bgrp, ppi1_16b_mux),
+       ADI_PMX_FUNCTION("ppi2_8b", ppi2_8bgrp, ppi2_8b_mux),
+       ADI_PMX_FUNCTION("atapi", atapigrp, atapi_mux),
+       ADI_PMX_FUNCTION("atapi_alter", atapialtergrp, atapi_alter_mux),
+       ADI_PMX_FUNCTION("nfc0", nfc0grp, nfc0_mux),
+       ADI_PMX_FUNCTION("keys_4x4", keys_4x4grp, keys_4x4_mux),
+       ADI_PMX_FUNCTION("keys_8x8", keys_8x8grp, keys_8x8_mux),
+};
+
+static const struct adi_pinctrl_soc_data adi_bf54x_soc = {
+       .functions = adi_pmx_functions,
+       .nfunctions = ARRAY_SIZE(adi_pmx_functions),
+       .groups = adi_pin_groups,
+       .ngroups = ARRAY_SIZE(adi_pin_groups),
+       .pins = adi_pads,
+       .npins = ARRAY_SIZE(adi_pads),
+};
+
+void adi_pinctrl_soc_init(const struct adi_pinctrl_soc_data **soc)
+{
+       *soc = &adi_bf54x_soc;
+}
diff --git a/drivers/pinctrl/pinctrl-adi2-bf60x.c b/drivers/pinctrl/pinctrl-adi2-bf60x.c
new file mode 100644 (file)
index 0000000..bf57aea
--- /dev/null
@@ -0,0 +1,521 @@
+/*
+ * Pinctrl Driver for ADI GPIO2 controller
+ *
+ * Copyright 2007-2013 Analog Devices Inc.
+ *
+ * Licensed under the GPLv2 or later
+ */
+
+#include <asm/portmux.h>
+#include "pinctrl-adi2.h"
+
+static const struct pinctrl_pin_desc adi_pads[] = {
+       PINCTRL_PIN(0, "PA0"),
+       PINCTRL_PIN(1, "PA1"),
+       PINCTRL_PIN(2, "PA2"),
+       PINCTRL_PIN(3, "PG3"),
+       PINCTRL_PIN(4, "PA4"),
+       PINCTRL_PIN(5, "PA5"),
+       PINCTRL_PIN(6, "PA6"),
+       PINCTRL_PIN(7, "PA7"),
+       PINCTRL_PIN(8, "PA8"),
+       PINCTRL_PIN(9, "PA9"),
+       PINCTRL_PIN(10, "PA10"),
+       PINCTRL_PIN(11, "PA11"),
+       PINCTRL_PIN(12, "PA12"),
+       PINCTRL_PIN(13, "PA13"),
+       PINCTRL_PIN(14, "PA14"),
+       PINCTRL_PIN(15, "PA15"),
+       PINCTRL_PIN(16, "PB0"),
+       PINCTRL_PIN(17, "PB1"),
+       PINCTRL_PIN(18, "PB2"),
+       PINCTRL_PIN(19, "PB3"),
+       PINCTRL_PIN(20, "PB4"),
+       PINCTRL_PIN(21, "PB5"),
+       PINCTRL_PIN(22, "PB6"),
+       PINCTRL_PIN(23, "PB7"),
+       PINCTRL_PIN(24, "PB8"),
+       PINCTRL_PIN(25, "PB9"),
+       PINCTRL_PIN(26, "PB10"),
+       PINCTRL_PIN(27, "PB11"),
+       PINCTRL_PIN(28, "PB12"),
+       PINCTRL_PIN(29, "PB13"),
+       PINCTRL_PIN(30, "PB14"),
+       PINCTRL_PIN(31, "PB15"),
+       PINCTRL_PIN(32, "PC0"),
+       PINCTRL_PIN(33, "PC1"),
+       PINCTRL_PIN(34, "PC2"),
+       PINCTRL_PIN(35, "PC3"),
+       PINCTRL_PIN(36, "PC4"),
+       PINCTRL_PIN(37, "PC5"),
+       PINCTRL_PIN(38, "PC6"),
+       PINCTRL_PIN(39, "PC7"),
+       PINCTRL_PIN(40, "PC8"),
+       PINCTRL_PIN(41, "PC9"),
+       PINCTRL_PIN(42, "PC10"),
+       PINCTRL_PIN(43, "PC11"),
+       PINCTRL_PIN(44, "PC12"),
+       PINCTRL_PIN(45, "PC13"),
+       PINCTRL_PIN(46, "PC14"),
+       PINCTRL_PIN(47, "PC15"),
+       PINCTRL_PIN(48, "PD0"),
+       PINCTRL_PIN(49, "PD1"),
+       PINCTRL_PIN(50, "PD2"),
+       PINCTRL_PIN(51, "PD3"),
+       PINCTRL_PIN(52, "PD4"),
+       PINCTRL_PIN(53, "PD5"),
+       PINCTRL_PIN(54, "PD6"),
+       PINCTRL_PIN(55, "PD7"),
+       PINCTRL_PIN(56, "PD8"),
+       PINCTRL_PIN(57, "PD9"),
+       PINCTRL_PIN(58, "PD10"),
+       PINCTRL_PIN(59, "PD11"),
+       PINCTRL_PIN(60, "PD12"),
+       PINCTRL_PIN(61, "PD13"),
+       PINCTRL_PIN(62, "PD14"),
+       PINCTRL_PIN(63, "PD15"),
+       PINCTRL_PIN(64, "PE0"),
+       PINCTRL_PIN(65, "PE1"),
+       PINCTRL_PIN(66, "PE2"),
+       PINCTRL_PIN(67, "PE3"),
+       PINCTRL_PIN(68, "PE4"),
+       PINCTRL_PIN(69, "PE5"),
+       PINCTRL_PIN(70, "PE6"),
+       PINCTRL_PIN(71, "PE7"),
+       PINCTRL_PIN(72, "PE8"),
+       PINCTRL_PIN(73, "PE9"),
+       PINCTRL_PIN(74, "PE10"),
+       PINCTRL_PIN(75, "PE11"),
+       PINCTRL_PIN(76, "PE12"),
+       PINCTRL_PIN(77, "PE13"),
+       PINCTRL_PIN(78, "PE14"),
+       PINCTRL_PIN(79, "PE15"),
+       PINCTRL_PIN(80, "PF0"),
+       PINCTRL_PIN(81, "PF1"),
+       PINCTRL_PIN(82, "PF2"),
+       PINCTRL_PIN(83, "PF3"),
+       PINCTRL_PIN(84, "PF4"),
+       PINCTRL_PIN(85, "PF5"),
+       PINCTRL_PIN(86, "PF6"),
+       PINCTRL_PIN(87, "PF7"),
+       PINCTRL_PIN(88, "PF8"),
+       PINCTRL_PIN(89, "PF9"),
+       PINCTRL_PIN(90, "PF10"),
+       PINCTRL_PIN(91, "PF11"),
+       PINCTRL_PIN(92, "PF12"),
+       PINCTRL_PIN(93, "PF13"),
+       PINCTRL_PIN(94, "PF14"),
+       PINCTRL_PIN(95, "PF15"),
+       PINCTRL_PIN(96, "PG0"),
+       PINCTRL_PIN(97, "PG1"),
+       PINCTRL_PIN(98, "PG2"),
+       PINCTRL_PIN(99, "PG3"),
+       PINCTRL_PIN(100, "PG4"),
+       PINCTRL_PIN(101, "PG5"),
+       PINCTRL_PIN(102, "PG6"),
+       PINCTRL_PIN(103, "PG7"),
+       PINCTRL_PIN(104, "PG8"),
+       PINCTRL_PIN(105, "PG9"),
+       PINCTRL_PIN(106, "PG10"),
+       PINCTRL_PIN(107, "PG11"),
+       PINCTRL_PIN(108, "PG12"),
+       PINCTRL_PIN(109, "PG13"),
+       PINCTRL_PIN(110, "PG14"),
+       PINCTRL_PIN(111, "PG15"),
+};
+
+static const unsigned uart0_pins[] = {
+       GPIO_PD7, GPIO_PD8,
+};
+
+static const unsigned uart0_ctsrts_pins[] = {
+       GPIO_PD9, GPIO_PD10,
+};
+
+static const unsigned uart1_pins[] = {
+       GPIO_PG15, GPIO_PG14,
+};
+
+static const unsigned uart1_ctsrts_pins[] = {
+       GPIO_PG10, GPIO_PG13,
+};
+
+static const unsigned rsi0_pins[] = {
+       GPIO_PG3, GPIO_PG2, GPIO_PG0, GPIO_PE15, GPIO_PG5, GPIO_PG6,
+};
+
+static const unsigned eth0_pins[] = {
+       GPIO_PC6, GPIO_PC7, GPIO_PC2, GPIO_PC0, GPIO_PC3, GPIO_PC1,
+       GPIO_PB13, GPIO_PD6, GPIO_PC5, GPIO_PC4, GPIO_PB14, GPIO_PB15,
+};
+
+static const unsigned eth1_pins[] = {
+       GPIO_PE10, GPIO_PE11, GPIO_PG3, GPIO_PG0, GPIO_PG2, GPIO_PE15,
+       GPIO_PG5, GPIO_PE12, GPIO_PE13, GPIO_PE14, GPIO_PG6, GPIO_PC9,
+};
+
+static const unsigned spi0_pins[] = {
+       GPIO_PD4, GPIO_PD2, GPIO_PD3,
+};
+
+static const unsigned spi1_pins[] = {
+       GPIO_PD5, GPIO_PD14, GPIO_PD13,
+};
+
+static const unsigned twi0_pins[] = {
+};
+
+static const unsigned twi1_pins[] = {
+};
+
+static const unsigned rotary_pins[] = {
+       GPIO_PG7, GPIO_PG11, GPIO_PG12,
+};
+
+static const unsigned can0_pins[] = {
+       GPIO_PG1, GPIO_PG4,
+};
+
+static const unsigned smc0_pins[] = {
+       GPIO_PA0, GPIO_PA1, GPIO_PA2, GPIO_PA3, GPIO_PA4, GPIO_PA5, GPIO_PA6,
+       GPIO_PA7, GPIO_PA8, GPIO_PA9, GPIO_PB2, GPIO_PA10, GPIO_PA11,
+       GPIO_PB3, GPIO_PA12, GPIO_PA13, GPIO_PA14, GPIO_PA15, GPIO_PB6,
+       GPIO_PB7, GPIO_PB8, GPIO_PB10, GPIO_PB11, GPIO_PB0,
+};
+
+static const unsigned sport0_pins[] = {
+       GPIO_PB5, GPIO_PB4, GPIO_PB9, GPIO_PB8, GPIO_PB7, GPIO_PB11,
+};
+
+static const unsigned sport1_pins[] = {
+       GPIO_PE2, GPIO_PE5, GPIO_PD15, GPIO_PE4, GPIO_PE3, GPIO_PE1,
+};
+
+static const unsigned sport2_pins[] = {
+       GPIO_PG4, GPIO_PG1, GPIO_PG9, GPIO_PG10, GPIO_PG7, GPIO_PB12,
+};
+
+static const unsigned ppi0_8b_pins[] = {
+       GPIO_PF0, GPIO_PF1, GPIO_PF2, GPIO_PF3, GPIO_PF4, GPIO_PF5, GPIO_PF6,
+       GPIO_PF7, GPIO_PF13, GPIO_PF14, GPIO_PF15,
+       GPIO_PE6, GPIO_PE7, GPIO_PE8, GPIO_PE9,
+};
+
+static const unsigned ppi0_16b_pins[] = {
+       GPIO_PF0, GPIO_PF1, GPIO_PF2, GPIO_PF3, GPIO_PF4, GPIO_PF5, GPIO_PF6,
+       GPIO_PF7, GPIO_PF9, GPIO_PF10, GPIO_PF11, GPIO_PF12,
+       GPIO_PF13, GPIO_PF14, GPIO_PF15,
+       GPIO_PE6, GPIO_PE7, GPIO_PE8, GPIO_PE9,
+};
+
+static const unsigned ppi0_24b_pins[] = {
+       GPIO_PF0, GPIO_PF1, GPIO_PF2, GPIO_PF3, GPIO_PF4, GPIO_PF5, GPIO_PF6,
+       GPIO_PF7, GPIO_PF8, GPIO_PF9, GPIO_PF10, GPIO_PF11, GPIO_PF12,
+       GPIO_PF13, GPIO_PF14, GPIO_PF15, GPIO_PE0, GPIO_PE1, GPIO_PE2,
+       GPIO_PE3, GPIO_PE4, GPIO_PE5, GPIO_PE6, GPIO_PE7, GPIO_PE8,
+       GPIO_PE9, GPIO_PD12, GPIO_PD15,
+};
+
+static const unsigned ppi1_8b_pins[] = {
+       GPIO_PC0, GPIO_PC1, GPIO_PC2, GPIO_PC3, GPIO_PC4, GPIO_PC5, GPIO_PC6,
+       GPIO_PC7, GPIO_PC8, GPIO_PB13, GPIO_PB14, GPIO_PB15, GPIO_PD6,
+};
+
+static const unsigned ppi1_16b_pins[] = {
+       GPIO_PC0, GPIO_PC1, GPIO_PC2, GPIO_PC3, GPIO_PC4, GPIO_PC5, GPIO_PC6,
+       GPIO_PC7, GPIO_PC9, GPIO_PC10, GPIO_PC11, GPIO_PC12,
+       GPIO_PC13, GPIO_PC14, GPIO_PC15,
+       GPIO_PB13, GPIO_PB14, GPIO_PB15, GPIO_PD6,
+};
+
+static const unsigned ppi2_8b_pins[] = {
+       GPIO_PA0, GPIO_PA1, GPIO_PA2, GPIO_PA3, GPIO_PA4, GPIO_PA5, GPIO_PA6,
+       GPIO_PA7, GPIO_PB0, GPIO_PB1, GPIO_PB2, GPIO_PB3,
+};
+
+static const unsigned ppi2_16b_pins[] = {
+       GPIO_PA0, GPIO_PA1, GPIO_PA2, GPIO_PA3, GPIO_PA4, GPIO_PA5, GPIO_PA6,
+       GPIO_PA7, GPIO_PA8, GPIO_PA9, GPIO_PA10, GPIO_PA11, GPIO_PA12,
+       GPIO_PA13, GPIO_PA14, GPIO_PA15, GPIO_PB0, GPIO_PB1, GPIO_PB2,
+};
+
+static const unsigned lp0_pins[] = {
+       GPIO_PB0, GPIO_PB1, GPIO_PA0, GPIO_PA1, GPIO_PA2, GPIO_PA3,
+       GPIO_PA4, GPIO_PA5, GPIO_PA6, GPIO_PA7,
+};
+
+static const unsigned lp1_pins[] = {
+       GPIO_PB3, GPIO_PB2, GPIO_PA8, GPIO_PA9, GPIO_PA10, GPIO_PA11,
+       GPIO_PA12, GPIO_PA13, GPIO_PA14, GPIO_PA15,
+};
+
+static const unsigned lp2_pins[] = {
+       GPIO_PE6, GPIO_PE7, GPIO_PF0, GPIO_PF1, GPIO_PF2, GPIO_PF3,
+       GPIO_PF4, GPIO_PF5, GPIO_PF6, GPIO_PF7,
+};
+
+static const unsigned lp3_pins[] = {
+       GPIO_PE9, GPIO_PE8, GPIO_PF8, GPIO_PF9, GPIO_PF10, GPIO_PF11,
+       GPIO_PF12, GPIO_PF13, GPIO_PF14, GPIO_PF15,
+};
+
+static const struct adi_pin_group adi_pin_groups[] = {
+       ADI_PIN_GROUP("uart0grp", uart0_pins),
+       ADI_PIN_GROUP("uart0ctsrtsgrp", uart0_ctsrts_pins),
+       ADI_PIN_GROUP("uart1grp", uart1_pins),
+       ADI_PIN_GROUP("uart1ctsrtsgrp", uart1_ctsrts_pins),
+       ADI_PIN_GROUP("rsi0grp", rsi0_pins),
+       ADI_PIN_GROUP("eth0grp", eth0_pins),
+       ADI_PIN_GROUP("eth1grp", eth1_pins),
+       ADI_PIN_GROUP("spi0grp", spi0_pins),
+       ADI_PIN_GROUP("spi1grp", spi1_pins),
+       ADI_PIN_GROUP("twi0grp", twi0_pins),
+       ADI_PIN_GROUP("twi1grp", twi1_pins),
+       ADI_PIN_GROUP("rotarygrp", rotary_pins),
+       ADI_PIN_GROUP("can0grp", can0_pins),
+       ADI_PIN_GROUP("smc0grp", smc0_pins),
+       ADI_PIN_GROUP("sport0grp", sport0_pins),
+       ADI_PIN_GROUP("sport1grp", sport1_pins),
+       ADI_PIN_GROUP("sport2grp", sport2_pins),
+       ADI_PIN_GROUP("ppi0_8bgrp", ppi0_8b_pins),
+       ADI_PIN_GROUP("ppi0_16bgrp", ppi0_16b_pins),
+       ADI_PIN_GROUP("ppi0_24bgrp", ppi0_24b_pins),
+       ADI_PIN_GROUP("ppi1_8bgrp", ppi1_8b_pins),
+       ADI_PIN_GROUP("ppi1_16bgrp", ppi1_16b_pins),
+       ADI_PIN_GROUP("ppi2_8bgrp", ppi2_8b_pins),
+       ADI_PIN_GROUP("ppi2_16bgrp", ppi2_16b_pins),
+       ADI_PIN_GROUP("lp0grp", lp0_pins),
+       ADI_PIN_GROUP("lp1grp", lp1_pins),
+       ADI_PIN_GROUP("lp2grp", lp2_pins),
+       ADI_PIN_GROUP("lp3grp", lp3_pins),
+};
+
+static const unsigned short uart0_mux[] = {
+       P_UART0_TX, P_UART0_RX,
+       0
+};
+
+static const unsigned short uart0_ctsrts_mux[] = {
+       P_UART0_RTS, P_UART0_CTS,
+       0
+};
+
+static const unsigned short uart1_mux[] = {
+       P_UART1_TX, P_UART1_RX,
+       0
+};
+
+static const unsigned short uart1_ctsrts_mux[] = {
+       P_UART1_RTS, P_UART1_CTS,
+       0
+};
+
+static const unsigned short rsi0_mux[] = {
+       P_RSI_DATA0, P_RSI_DATA1, P_RSI_DATA2, P_RSI_DATA3,
+       P_RSI_CMD, P_RSI_CLK, 0
+};
+
+static const unsigned short eth0_mux[] = P_RMII0;
+static const unsigned short eth1_mux[] = P_RMII1;
+
+static const unsigned short spi0_mux[] = {
+       P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0
+};
+
+static const unsigned short spi1_mux[] = {
+       P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0
+};
+
+static const unsigned short twi0_mux[] = {
+       P_TWI0_SCL, P_TWI0_SDA, 0
+};
+
+static const unsigned short twi1_mux[] = {
+       P_TWI1_SCL, P_TWI1_SDA, 0
+};
+
+static const unsigned short rotary_mux[] = {
+       P_CNT_CUD, P_CNT_CDG, P_CNT_CZM, 0
+};
+
+static const unsigned short sport0_mux[] = {
+       P_SPORT0_ACLK, P_SPORT0_AFS, P_SPORT0_AD0, P_SPORT0_BCLK,
+       P_SPORT0_BFS, P_SPORT0_BD0, 0,
+};
+
+static const unsigned short sport1_mux[] = {
+       P_SPORT1_ACLK, P_SPORT1_AFS, P_SPORT1_AD0, P_SPORT1_BCLK,
+       P_SPORT1_BFS, P_SPORT1_BD0, 0,
+};
+
+static const unsigned short sport2_mux[] = {
+       P_SPORT2_ACLK, P_SPORT2_AFS, P_SPORT2_AD0, P_SPORT2_BCLK,
+       P_SPORT2_BFS, P_SPORT2_BD0, 0,
+};
+
+static const unsigned short can0_mux[] = {
+       P_CAN0_RX, P_CAN0_TX, 0
+};
+
+static const unsigned short smc0_mux[] = {
+       P_A3, P_A4, P_A5, P_A6, P_A7, P_A8, P_A9, P_A10, P_A11, P_A12,
+       P_A13, P_A14, P_A15, P_A16, P_A17, P_A18, P_A19, P_A20, P_A21,
+       P_A22, P_A23, P_A24, P_A25, P_NORCK, 0,
+};
+
+static const unsigned short ppi0_8b_mux[] = {
+       P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, P_PPI0_D3,
+       P_PPI0_D4, P_PPI0_D5, P_PPI0_D6, P_PPI0_D7,
+       P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2,
+       0,
+};
+
+static const unsigned short ppi0_16b_mux[] = {
+       P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, P_PPI0_D3,
+       P_PPI0_D4, P_PPI0_D5, P_PPI0_D6, P_PPI0_D7,
+       P_PPI0_D8, P_PPI0_D9, P_PPI0_D10, P_PPI0_D11,
+       P_PPI0_D12, P_PPI0_D13, P_PPI0_D14, P_PPI0_D15,
+       P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2,
+       0,
+};
+
+static const unsigned short ppi0_24b_mux[] = {
+       P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, P_PPI0_D3,
+       P_PPI0_D4, P_PPI0_D5, P_PPI0_D6, P_PPI0_D7,
+       P_PPI0_D8, P_PPI0_D9, P_PPI0_D10, P_PPI0_D11,
+       P_PPI0_D12, P_PPI0_D13, P_PPI0_D14, P_PPI0_D15,
+       P_PPI0_D16, P_PPI0_D17, P_PPI0_D18, P_PPI0_D19,
+       P_PPI0_D20, P_PPI0_D21, P_PPI0_D22, P_PPI0_D23,
+       P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2,
+       0,
+};
+
+static const unsigned short ppi1_8b_mux[] = {
+       P_PPI1_D0, P_PPI1_D1, P_PPI1_D2, P_PPI1_D3,
+       P_PPI1_D4, P_PPI1_D5, P_PPI1_D6, P_PPI1_D7,
+       P_PPI1_CLK, P_PPI1_FS1, P_PPI1_FS2,
+       0,
+};
+
+static const unsigned short ppi1_16b_mux[] = {
+       P_PPI1_D0, P_PPI1_D1, P_PPI1_D2, P_PPI1_D3,
+       P_PPI1_D4, P_PPI1_D5, P_PPI1_D6, P_PPI1_D7,
+       P_PPI1_D8, P_PPI1_D9, P_PPI1_D10, P_PPI1_D11,
+       P_PPI1_D12, P_PPI1_D13, P_PPI1_D14, P_PPI1_D15,
+       P_PPI1_CLK, P_PPI1_FS1, P_PPI1_FS2,
+       0,
+};
+
+static const unsigned short ppi2_8b_mux[] = {
+       P_PPI2_D0, P_PPI2_D1, P_PPI2_D2, P_PPI2_D3,
+       P_PPI2_D4, P_PPI2_D5, P_PPI2_D6, P_PPI2_D7,
+       P_PPI2_CLK, P_PPI2_FS1, P_PPI2_FS2,
+       0,
+};
+
+static const unsigned short ppi2_16b_mux[] = {
+       P_PPI2_D0, P_PPI2_D1, P_PPI2_D2, P_PPI2_D3,
+       P_PPI2_D4, P_PPI2_D5, P_PPI2_D6, P_PPI2_D7,
+       P_PPI2_D8, P_PPI2_D9, P_PPI2_D10, P_PPI2_D11,
+       P_PPI2_D12, P_PPI2_D13, P_PPI2_D14, P_PPI2_D15,
+       P_PPI2_CLK, P_PPI2_FS1, P_PPI2_FS2,
+       0,
+};
+
+static const unsigned short lp0_mux[] = {
+       P_LP0_CLK, P_LP0_ACK, P_LP0_D0, P_LP0_D1, P_LP0_D2,
+       P_LP0_D3, P_LP0_D4, P_LP0_D5, P_LP0_D6, P_LP0_D7,
+        0
+};
+
+static const unsigned short lp1_mux[] = {
+       P_LP1_CLK, P_LP1_ACK, P_LP1_D0, P_LP1_D1, P_LP1_D2,
+       P_LP1_D3, P_LP1_D4, P_LP1_D5, P_LP1_D6, P_LP1_D7,
+        0
+};
+
+static const unsigned short lp2_mux[] = {
+       P_LP2_CLK, P_LP2_ACK, P_LP2_D0, P_LP2_D1, P_LP2_D2,
+       P_LP2_D3, P_LP2_D4, P_LP2_D5, P_LP2_D6, P_LP2_D7,
+        0
+};
+
+static const unsigned short lp3_mux[] = {
+       P_LP3_CLK, P_LP3_ACK, P_LP3_D0, P_LP3_D1, P_LP3_D2,
+       P_LP3_D3, P_LP3_D4, P_LP3_D5, P_LP3_D6, P_LP3_D7,
+        0
+};
+
+static const char * const uart0grp[] = { "uart0grp" };
+static const char * const uart0ctsrtsgrp[] = { "uart0ctsrtsgrp" };
+static const char * const uart1grp[] = { "uart1grp" };
+static const char * const uart1ctsrtsgrp[] = { "uart1ctsrtsgrp" };
+static const char * const rsi0grp[] = { "rsi0grp" };
+static const char * const eth0grp[] = { "eth0grp" };
+static const char * const eth1grp[] = { "eth1grp" };
+static const char * const spi0grp[] = { "spi0grp" };
+static const char * const spi1grp[] = { "spi1grp" };
+static const char * const twi0grp[] = { "twi0grp" };
+static const char * const twi1grp[] = { "twi1grp" };
+static const char * const rotarygrp[] = { "rotarygrp" };
+static const char * const can0grp[] = { "can0grp" };
+static const char * const smc0grp[] = { "smc0grp" };
+static const char * const sport0grp[] = { "sport0grp" };
+static const char * const sport1grp[] = { "sport1grp" };
+static const char * const sport2grp[] = { "sport2grp" };
+static const char * const ppi0_8bgrp[] = { "ppi0_8bgrp" };
+static const char * const ppi0_16bgrp[] = { "ppi0_16bgrp" };
+static const char * const ppi0_24bgrp[] = { "ppi0_24bgrp" };
+static const char * const ppi1_8bgrp[] = { "ppi1_8bgrp" };
+static const char * const ppi1_16bgrp[] = { "ppi1_16bgrp" };
+static const char * const ppi2_8bgrp[] = { "ppi2_8bgrp" };
+static const char * const ppi2_16bgrp[] = { "ppi2_16bgrp" };
+static const char * const lp0grp[] = { "lp0grp" };
+static const char * const lp1grp[] = { "lp1grp" };
+static const char * const lp2grp[] = { "lp2grp" };
+static const char * const lp3grp[] = { "lp3grp" };
+
+static const struct adi_pmx_func adi_pmx_functions[] = {
+       ADI_PMX_FUNCTION("uart0", uart0grp, uart0_mux),
+       ADI_PMX_FUNCTION("uart0_ctsrts", uart0ctsrtsgrp, uart0_ctsrts_mux),
+       ADI_PMX_FUNCTION("uart1", uart1grp, uart1_mux),
+       ADI_PMX_FUNCTION("uart1_ctsrts", uart1ctsrtsgrp, uart1_ctsrts_mux),
+       ADI_PMX_FUNCTION("rsi0", rsi0grp, rsi0_mux),
+       ADI_PMX_FUNCTION("eth0", eth0grp, eth0_mux),
+       ADI_PMX_FUNCTION("eth1", eth1grp, eth1_mux),
+       ADI_PMX_FUNCTION("spi0", spi0grp, spi0_mux),
+       ADI_PMX_FUNCTION("spi1", spi1grp, spi1_mux),
+       ADI_PMX_FUNCTION("twi0", twi0grp, twi0_mux),
+       ADI_PMX_FUNCTION("twi1", twi1grp, twi1_mux),
+       ADI_PMX_FUNCTION("rotary", rotarygrp, rotary_mux),
+       ADI_PMX_FUNCTION("can0", can0grp, can0_mux),
+       ADI_PMX_FUNCTION("smc0", smc0grp, smc0_mux),
+       ADI_PMX_FUNCTION("sport0", sport0grp, sport0_mux),
+       ADI_PMX_FUNCTION("sport1", sport1grp, sport1_mux),
+       ADI_PMX_FUNCTION("sport2", sport2grp, sport2_mux),
+       ADI_PMX_FUNCTION("ppi0_8b", ppi0_8bgrp, ppi0_8b_mux),
+       ADI_PMX_FUNCTION("ppi0_16b", ppi0_16bgrp, ppi0_16b_mux),
+       ADI_PMX_FUNCTION("ppi0_24b", ppi0_24bgrp, ppi0_24b_mux),
+       ADI_PMX_FUNCTION("ppi1_8b", ppi1_8bgrp, ppi1_8b_mux),
+       ADI_PMX_FUNCTION("ppi1_16b", ppi1_16bgrp, ppi1_16b_mux),
+       ADI_PMX_FUNCTION("ppi2_8b", ppi2_8bgrp, ppi2_8b_mux),
+       ADI_PMX_FUNCTION("ppi2_16b", ppi2_16bgrp, ppi2_16b_mux),
+       ADI_PMX_FUNCTION("lp0", lp0grp, lp0_mux),
+       ADI_PMX_FUNCTION("lp1", lp1grp, lp1_mux),
+       ADI_PMX_FUNCTION("lp2", lp2grp, lp2_mux),
+       ADI_PMX_FUNCTION("lp3", lp3grp, lp3_mux),
+};
+
+static const struct adi_pinctrl_soc_data adi_bf60x_soc = {
+       .functions = adi_pmx_functions,
+       .nfunctions = ARRAY_SIZE(adi_pmx_functions),
+       .groups = adi_pin_groups,
+       .ngroups = ARRAY_SIZE(adi_pin_groups),
+       .pins = adi_pads,
+       .npins = ARRAY_SIZE(adi_pads),
+};
+
+void adi_pinctrl_soc_init(const struct adi_pinctrl_soc_data **soc)
+{
+       *soc = &adi_bf60x_soc;
+}
diff --git a/drivers/pinctrl/pinctrl-adi2.c b/drivers/pinctrl/pinctrl-adi2.c
new file mode 100644 (file)
index 0000000..7a39562
--- /dev/null
@@ -0,0 +1,1164 @@
+/*
+ * Pinctrl Driver for ADI GPIO2 controller
+ *
+ * Copyright 2007-2013 Analog Devices Inc.
+ *
+ * Licensed under the GPLv2 or later
+ */
+
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/irq.h>
+#include <linux/platform_data/pinctrl-adi2.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/syscore_ops.h>
+#include <linux/gpio.h>
+#include <asm/portmux.h>
+#include "pinctrl-adi2.h"
+#include "core.h"
+
+/*
+According to the BF54x HRM, pint means "pin interrupt".
+http://www.analog.com/static/imported-files/processor_manuals/ADSP-BF54x_hwr_rev1.2.pdf
+
+ADSP-BF54x processor Blackfin processors have four SIC interrupt chan-
+nels dedicated to pin interrupt purposes. These channels are managed by
+four hardware blocks, called PINT0, PINT1, PINT2, and PINT3. Every PINTx
+block can sense to up to 32 pins. While PINT0 and PINT1 can sense the
+pins of port A and port B, PINT2 and PINT3 manage all the pins from port
+C to port J as shown in Figure 9-2.
+
+n BF54x HRM:
+The ten GPIO ports are subdivided into 8-bit half ports, resulting in lower and
+upper half 8-bit units. The PINTx_ASSIGN registers control the 8-bit multi-
+plexers shown in Figure 9-3. Lower half units of eight pins can be
+forwarded to either byte 0 or byte 2 of either associated PINTx block.
+Upper half units can be forwarded to either byte 1 or byte 3 of the pin
+interrupt blocks, without further restrictions.
+
+All MMR registers in the pin interrupt module are 32 bits wide. To simply the
+mapping logic, this driver only maps a 16-bit gpio port to the upper or lower
+16 bits of a PINTx block. You can find the Figure 9-3 on page 583.
+
+Each IRQ domain is binding to a GPIO bank device. 2 GPIO bank devices can map
+to one PINT device. Two in "struct gpio_pint" are used to ease the PINT
+interrupt handler.
+
+The GPIO bank mapping to the lower 16 bits of the PINT device set its IRQ
+domain pointer in domain[0]. The IRQ domain pointer of the other bank is set
+to domain[1]. PINT interrupt handler adi_gpio_handle_pint_irq() finds out
+the current domain pointer according to whether the interrupt request mask
+is in lower 16 bits (domain[0]) or upper 16bits (domain[1]).
+
+A PINT device is not part of a GPIO port device in Blackfin. Multiple GPIO
+port devices can be mapped to the same PINT device.
+
+*/
+
+static LIST_HEAD(adi_pint_list);
+static LIST_HEAD(adi_gpio_port_list);
+
+#define DRIVER_NAME "pinctrl-adi2"
+
+#define PINT_HI_OFFSET         16
+
+/**
+ * struct gpio_port_saved - GPIO port registers that should be saved between
+ * power suspend and resume operations.
+ *
+ * @fer: PORTx_FER register
+ * @data: PORTx_DATA register
+ * @dir: PORTx_DIR register
+ * @inen: PORTx_INEN register
+ * @mux: PORTx_MUX register
+ */
+struct gpio_port_saved {
+       u16 fer;
+       u16 data;
+       u16 dir;
+       u16 inen;
+       u32 mux;
+};
+
+/**
+ * struct gpio_pint - Pin interrupt controller device. Multiple ADI GPIO
+ * banks can be mapped into one Pin interrupt controller.
+ *
+ * @node: All gpio_pint instances are added to a global list.
+ * @base: PINT device register base address
+ * @irq: IRQ of the PINT device, it is the parent IRQ of all
+ *       GPIO IRQs mapping to this device.
+ * @domain: [0] irq domain of the gpio port, whose hardware interrupts are
+ *             mapping to the low 16-bit of the pint registers.
+ *          [1] irq domain of the gpio port, whose hardware interrupts are
+ *             mapping to the high 16-bit of the pint registers.
+ * @regs: address pointer to the PINT device
+ * @map_count: No more than 2 GPIO banks can be mapped to this PINT device.
+ * @lock: This lock make sure the irq_chip operations to one PINT device
+ *        for different GPIO interrrupts are atomic.
+ * @pint_map_port: Set up the mapping between one PINT device and
+ *                 multiple GPIO banks.
+ */
+struct gpio_pint {
+       struct list_head node;
+       void __iomem *base;
+       int irq;
+       struct irq_domain *domain[2];
+       struct gpio_pint_regs *regs;
+       struct adi_pm_pint_save saved_data;
+       int map_count;
+       spinlock_t lock;
+
+       int (*pint_map_port)(struct gpio_pint *pint, bool assign,
+                               u8 map, struct irq_domain *domain);
+};
+
+/**
+ * ADI pin controller
+ *
+ * @dev: a pointer back to containing device
+ * @pctl: the pinctrl device
+ * @soc: SoC data for this specific chip
+ */
+struct adi_pinctrl {
+       struct device *dev;
+       struct pinctrl_dev *pctl;
+       const struct adi_pinctrl_soc_data *soc;
+};
+
+/**
+ * struct gpio_port - GPIO bank device. Multiple ADI GPIO banks can be mapped
+ * into one pin interrupt controller.
+ *
+ * @node: All gpio_port instances are added to a list.
+ * @base: GPIO bank device register base address
+ * @irq_base: base IRQ of the GPIO bank device
+ * @width: PIN number of the GPIO bank device
+ * @regs: address pointer to the GPIO bank device
+ * @saved_data: registers that should be saved between PM operations.
+ * @dev: device structure of this GPIO bank
+ * @pint: GPIO PINT device that this GPIO bank mapped to
+ * @pint_map: GIOP bank mapping code in PINT device
+ * @pint_assign: The 32-bit PINT registers can be divided into 2 parts. A
+ *               GPIO bank can be mapped into either low 16 bits[0] or high 16
+ *               bits[1] of each PINT register.
+ * @lock: This lock make sure the irq_chip operations to one PINT device
+ *        for different GPIO interrrupts are atomic.
+ * @chip: abstract a GPIO controller
+ * @domain: The irq domain owned by the GPIO port.
+ * @rsvmap: Reservation map array for each pin in the GPIO bank
+ */
+struct gpio_port {
+       struct list_head node;
+       void __iomem *base;
+       unsigned int irq_base;
+       unsigned int width;
+       struct gpio_port_t *regs;
+       struct gpio_port_saved saved_data;
+       struct device *dev;
+
+       struct gpio_pint *pint;
+       u8 pint_map;
+       bool pint_assign;
+
+       spinlock_t lock;
+       struct gpio_chip chip;
+       struct irq_domain *domain;
+};
+
+static inline u8 pin_to_offset(struct pinctrl_gpio_range *range, unsigned pin)
+{
+       return pin - range->pin_base;
+}
+
+static inline u32 hwirq_to_pintbit(struct gpio_port *port, int hwirq)
+{
+       return port->pint_assign ? BIT(hwirq) << PINT_HI_OFFSET : BIT(hwirq);
+}
+
+static struct gpio_pint *find_gpio_pint(unsigned id)
+{
+       struct gpio_pint *pint;
+       int i = 0;
+
+       list_for_each_entry(pint, &adi_pint_list, node) {
+               if (id == i)
+                       return pint;
+               i++;
+       }
+
+       return NULL;
+}
+
+static inline void port_setup(struct gpio_port *port, unsigned offset,
+       bool use_for_gpio)
+{
+       struct gpio_port_t *regs = port->regs;
+
+       if (use_for_gpio)
+               writew(readw(&regs->port_fer) & ~BIT(offset),
+                       &regs->port_fer);
+       else
+               writew(readw(&regs->port_fer) | BIT(offset), &regs->port_fer);
+}
+
+static inline void portmux_setup(struct gpio_port *port, unsigned offset,
+       unsigned short function)
+{
+       struct gpio_port_t *regs = port->regs;
+       u32 pmux;
+
+       pmux = readl(&regs->port_mux);
+
+       /* The function field of each pin has 2 consecutive bits in
+        * the mux register.
+        */
+       pmux &= ~(0x3 << (2 * offset));
+       pmux |= (function & 0x3) << (2 * offset);
+
+       writel(pmux, &regs->port_mux);
+}
+
+static inline u16 get_portmux(struct gpio_port *port, unsigned offset)
+{
+       struct gpio_port_t *regs = port->regs;
+       u32 pmux = readl(&regs->port_mux);
+
+       /* The function field of each pin has 2 consecutive bits in
+        * the mux register.
+        */
+       return pmux >> (2 * offset) & 0x3;
+}
+
+static void adi_gpio_ack_irq(struct irq_data *d)
+{
+       unsigned long flags;
+       struct gpio_port *port = irq_data_get_irq_chip_data(d);
+       struct gpio_pint_regs *regs = port->pint->regs;
+       unsigned pintbit = hwirq_to_pintbit(port, d->hwirq);
+
+       spin_lock_irqsave(&port->lock, flags);
+       spin_lock(&port->pint->lock);
+
+       if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) {
+               if (readl(&regs->invert_set) & pintbit)
+                       writel(pintbit, &regs->invert_clear);
+               else
+                       writel(pintbit, &regs->invert_set);
+       }
+
+       writel(pintbit, &regs->request);
+
+       spin_unlock(&port->pint->lock);
+       spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void adi_gpio_mask_ack_irq(struct irq_data *d)
+{
+       unsigned long flags;
+       struct gpio_port *port = irq_data_get_irq_chip_data(d);
+       struct gpio_pint_regs *regs = port->pint->regs;
+       unsigned pintbit = hwirq_to_pintbit(port, d->hwirq);
+
+       spin_lock_irqsave(&port->lock, flags);
+       spin_lock(&port->pint->lock);
+
+       if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) {
+               if (readl(&regs->invert_set) & pintbit)
+                       writel(pintbit, &regs->invert_clear);
+               else
+                       writel(pintbit, &regs->invert_set);
+       }
+
+       writel(pintbit, &regs->request);
+       writel(pintbit, &regs->mask_clear);
+
+       spin_unlock(&port->pint->lock);
+       spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void adi_gpio_mask_irq(struct irq_data *d)
+{
+       unsigned long flags;
+       struct gpio_port *port = irq_data_get_irq_chip_data(d);
+       struct gpio_pint_regs *regs = port->pint->regs;
+
+       spin_lock_irqsave(&port->lock, flags);
+       spin_lock(&port->pint->lock);
+
+       writel(hwirq_to_pintbit(port, d->hwirq), &regs->mask_clear);
+
+       spin_unlock(&port->pint->lock);
+       spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void adi_gpio_unmask_irq(struct irq_data *d)
+{
+       unsigned long flags;
+       struct gpio_port *port = irq_data_get_irq_chip_data(d);
+       struct gpio_pint_regs *regs = port->pint->regs;
+
+       spin_lock_irqsave(&port->lock, flags);
+       spin_lock(&port->pint->lock);
+
+       writel(hwirq_to_pintbit(port, d->hwirq), &regs->mask_set);
+
+       spin_unlock(&port->pint->lock);
+       spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static unsigned int adi_gpio_irq_startup(struct irq_data *d)
+{
+       unsigned long flags;
+       struct gpio_port *port = irq_data_get_irq_chip_data(d);
+       struct gpio_pint_regs *regs;
+
+       if (!port) {
+               pr_err("GPIO IRQ %d :Not exist\n", d->irq);
+               return -ENODEV;
+       }
+
+       regs = port->pint->regs;
+
+       spin_lock_irqsave(&port->lock, flags);
+       spin_lock(&port->pint->lock);
+
+       port_setup(port, d->hwirq, true);
+       writew(BIT(d->hwirq), &port->regs->dir_clear);
+       writew(readw(&port->regs->inen) | BIT(d->hwirq), &port->regs->inen);
+
+       writel(hwirq_to_pintbit(port, d->hwirq), &regs->mask_set);
+
+       spin_unlock(&port->pint->lock);
+       spin_unlock_irqrestore(&port->lock, flags);
+
+       return 0;
+}
+
+static void adi_gpio_irq_shutdown(struct irq_data *d)
+{
+       unsigned long flags;
+       struct gpio_port *port = irq_data_get_irq_chip_data(d);
+       struct gpio_pint_regs *regs = port->pint->regs;
+
+       spin_lock_irqsave(&port->lock, flags);
+       spin_lock(&port->pint->lock);
+
+       writel(hwirq_to_pintbit(port, d->hwirq), &regs->mask_clear);
+
+       spin_unlock(&port->pint->lock);
+       spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static int adi_gpio_irq_type(struct irq_data *d, unsigned int type)
+{
+       unsigned long flags;
+       struct gpio_port *port = irq_data_get_irq_chip_data(d);
+       struct gpio_pint_regs *pint_regs;
+       unsigned pintmask;
+       unsigned int irq = d->irq;
+       int ret = 0;
+       char buf[16];
+
+       if (!port) {
+               pr_err("GPIO IRQ %d :Not exist\n", d->irq);
+               return -ENODEV;
+       }
+
+       pint_regs = port->pint->regs;
+
+       pintmask = hwirq_to_pintbit(port, d->hwirq);
+
+       spin_lock_irqsave(&port->lock, flags);
+       spin_lock(&port->pint->lock);
+
+       /* In case of interrupt autodetect, set irq type to edge sensitive. */
+       if (type == IRQ_TYPE_PROBE)
+               type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+
+       if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
+                   IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
+               snprintf(buf, 16, "gpio-irq%d", irq);
+               port_setup(port, d->hwirq, true);
+       } else
+               goto out;
+
+       /* The GPIO interrupt is triggered only when its input value
+        * transfer from 0 to 1. So, invert the input value if the
+        * irq type is low or falling
+        */
+       if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW)))
+               writel(pintmask, &pint_regs->invert_set);
+       else
+               writel(pintmask, &pint_regs->invert_clear);
+
+       /* In edge sensitive case, if the input value of the requested irq
+        * is already 1, invert it.
+        */
+       if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
+               if (gpio_get_value(port->chip.base + d->hwirq))
+                       writel(pintmask, &pint_regs->invert_set);
+               else
+                       writel(pintmask, &pint_regs->invert_clear);
+       }
+
+       if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
+               writel(pintmask, &pint_regs->edge_set);
+               __irq_set_handler_locked(irq, handle_edge_irq);
+       } else {
+               writel(pintmask, &pint_regs->edge_clear);
+               __irq_set_handler_locked(irq, handle_level_irq);
+       }
+
+out:
+       spin_unlock(&port->pint->lock);
+       spin_unlock_irqrestore(&port->lock, flags);
+
+       return ret;
+}
+
+#ifdef CONFIG_PM
+static int adi_gpio_set_wake(struct irq_data *d, unsigned int state)
+{
+       struct gpio_port *port = irq_data_get_irq_chip_data(d);
+
+       if (!port || !port->pint || port->pint->irq != d->irq)
+               return -EINVAL;
+
+#ifndef SEC_GCTL
+       adi_internal_set_wake(port->pint->irq, state);
+#endif
+
+       return 0;
+}
+
+static int adi_pint_suspend(void)
+{
+       struct gpio_pint *pint;
+
+       list_for_each_entry(pint, &adi_pint_list, node) {
+               writel(0xffffffff, &pint->regs->mask_clear);
+               pint->saved_data.assign = readl(&pint->regs->assign);
+               pint->saved_data.edge_set = readl(&pint->regs->edge_set);
+               pint->saved_data.invert_set = readl(&pint->regs->invert_set);
+       }
+
+       return 0;
+}
+
+static void adi_pint_resume(void)
+{
+       struct gpio_pint *pint;
+
+       list_for_each_entry(pint, &adi_pint_list, node) {
+               writel(pint->saved_data.assign, &pint->regs->assign);
+               writel(pint->saved_data.edge_set, &pint->regs->edge_set);
+               writel(pint->saved_data.invert_set, &pint->regs->invert_set);
+       }
+}
+
+static int adi_gpio_suspend(void)
+{
+       struct gpio_port *port;
+
+       list_for_each_entry(port, &adi_gpio_port_list, node) {
+               port->saved_data.fer = readw(&port->regs->port_fer);
+               port->saved_data.mux = readl(&port->regs->port_mux);
+               port->saved_data.data = readw(&port->regs->data);
+               port->saved_data.inen = readw(&port->regs->inen);
+               port->saved_data.dir = readw(&port->regs->dir_set);
+       }
+
+       return adi_pint_suspend();
+}
+
+static void adi_gpio_resume(void)
+{
+       struct gpio_port *port;
+
+       adi_pint_resume();
+
+       list_for_each_entry(port, &adi_gpio_port_list, node) {
+               writel(port->saved_data.mux, &port->regs->port_mux);
+               writew(port->saved_data.fer, &port->regs->port_fer);
+               writew(port->saved_data.inen, &port->regs->inen);
+               writew(port->saved_data.data & port->saved_data.dir,
+                                       &port->regs->data_set);
+               writew(port->saved_data.dir, &port->regs->dir_set);
+       }
+
+}
+
+static struct syscore_ops gpio_pm_syscore_ops = {
+       .suspend = adi_gpio_suspend,
+       .resume = adi_gpio_resume,
+};
+#else /* CONFIG_PM */
+#define adi_gpio_set_wake NULL
+#endif /* CONFIG_PM */
+
+#ifdef CONFIG_IRQ_PREFLOW_FASTEOI
+static inline void preflow_handler(struct irq_desc *desc)
+{
+       if (desc->preflow_handler)
+               desc->preflow_handler(&desc->irq_data);
+}
+#else
+static inline void preflow_handler(struct irq_desc *desc) { }
+#endif
+
+static void adi_gpio_handle_pint_irq(unsigned int inta_irq,
+                       struct irq_desc *desc)
+{
+       u32 request;
+       u32 level_mask, hwirq;
+       bool umask = false;
+       struct gpio_pint *pint = irq_desc_get_handler_data(desc);
+       struct irq_chip *chip = irq_desc_get_chip(desc);
+       struct gpio_pint_regs *regs = pint->regs;
+       struct irq_domain *domain;
+
+       preflow_handler(desc);
+       chained_irq_enter(chip, desc);
+
+       request = readl(&regs->request);
+       level_mask = readl(&regs->edge_set) & request;
+
+       hwirq = 0;
+       domain = pint->domain[0];
+       while (request) {
+               /* domain pointer need to be changed only once at IRQ 16 when
+                * we go through IRQ requests from bit 0 to bit 31.
+                */
+               if (hwirq == PINT_HI_OFFSET)
+                       domain = pint->domain[1];
+
+               if (request & 1) {
+                       if (level_mask & BIT(hwirq)) {
+                               umask = true;
+                               chained_irq_exit(chip, desc);
+                       }
+                       generic_handle_irq(irq_find_mapping(domain,
+                                       hwirq % PINT_HI_OFFSET));
+               }
+
+               hwirq++;
+               request >>= 1;
+       }
+
+       if (!umask)
+               chained_irq_exit(chip, desc);
+}
+
+static struct irq_chip adi_gpio_irqchip = {
+       .name = "GPIO",
+       .irq_ack = adi_gpio_ack_irq,
+       .irq_mask = adi_gpio_mask_irq,
+       .irq_mask_ack = adi_gpio_mask_ack_irq,
+       .irq_unmask = adi_gpio_unmask_irq,
+       .irq_disable = adi_gpio_mask_irq,
+       .irq_enable = adi_gpio_unmask_irq,
+       .irq_set_type = adi_gpio_irq_type,
+       .irq_startup = adi_gpio_irq_startup,
+       .irq_shutdown = adi_gpio_irq_shutdown,
+       .irq_set_wake = adi_gpio_set_wake,
+};
+
+static int adi_get_groups_count(struct pinctrl_dev *pctldev)
+{
+       struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
+
+       return pinctrl->soc->ngroups;
+}
+
+static const char *adi_get_group_name(struct pinctrl_dev *pctldev,
+                                      unsigned selector)
+{
+       struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
+
+       return pinctrl->soc->groups[selector].name;
+}
+
+static int adi_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
+                              const unsigned **pins,
+                              unsigned *num_pins)
+{
+       struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
+
+       *pins = pinctrl->soc->groups[selector].pins;
+       *num_pins = pinctrl->soc->groups[selector].num;
+       return 0;
+}
+
+static struct pinctrl_ops adi_pctrl_ops = {
+       .get_groups_count = adi_get_groups_count,
+       .get_group_name = adi_get_group_name,
+       .get_group_pins = adi_get_group_pins,
+};
+
+static int adi_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector,
+       unsigned group)
+{
+       struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
+       struct gpio_port *port;
+       struct pinctrl_gpio_range *range;
+       unsigned long flags;
+       unsigned short *mux, pin;
+
+       mux = (unsigned short *)pinctrl->soc->functions[selector].mux;
+
+       while (*mux) {
+               pin = P_IDENT(*mux);
+
+               range = pinctrl_find_gpio_range_from_pin(pctldev, pin);
+               if (range == NULL) /* should not happen */
+                       return -ENODEV;
+
+               port = container_of(range->gc, struct gpio_port, chip);
+
+               spin_lock_irqsave(&port->lock, flags);
+
+               portmux_setup(port, pin_to_offset(range, pin),
+                                P_FUNCT2MUX(*mux));
+               port_setup(port, pin_to_offset(range, pin), false);
+               mux++;
+
+               spin_unlock_irqrestore(&port->lock, flags);
+       }
+
+       return 0;
+}
+
+static void adi_pinmux_disable(struct pinctrl_dev *pctldev, unsigned selector,
+       unsigned group)
+{
+       struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
+       struct gpio_port *port;
+       struct pinctrl_gpio_range *range;
+       unsigned long flags;
+       unsigned short *mux, pin;
+
+       mux = (unsigned short *)pinctrl->soc->functions[selector].mux;
+
+       while (*mux) {
+               pin = P_IDENT(*mux);
+
+               range = pinctrl_find_gpio_range_from_pin(pctldev, pin);
+               if (range == NULL) /* should not happen */
+                       return;
+
+               port = container_of(range->gc, struct gpio_port, chip);
+
+               spin_lock_irqsave(&port->lock, flags);
+
+               port_setup(port, pin_to_offset(range, pin), true);
+               mux++;
+
+               spin_unlock_irqrestore(&port->lock, flags);
+       }
+}
+
+static int adi_pinmux_get_funcs_count(struct pinctrl_dev *pctldev)
+{
+       struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
+
+       return pinctrl->soc->nfunctions;
+}
+
+static const char *adi_pinmux_get_func_name(struct pinctrl_dev *pctldev,
+                                         unsigned selector)
+{
+       struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
+
+       return pinctrl->soc->functions[selector].name;
+}
+
+static int adi_pinmux_get_groups(struct pinctrl_dev *pctldev, unsigned selector,
+                              const char * const **groups,
+                              unsigned * const num_groups)
+{
+       struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
+
+       *groups = pinctrl->soc->functions[selector].groups;
+       *num_groups = pinctrl->soc->functions[selector].num_groups;
+       return 0;
+}
+
+static int adi_pinmux_request_gpio(struct pinctrl_dev *pctldev,
+       struct pinctrl_gpio_range *range, unsigned pin)
+{
+       struct gpio_port *port;
+       unsigned long flags;
+       u8 offset;
+
+       port = container_of(range->gc, struct gpio_port, chip);
+       offset = pin_to_offset(range, pin);
+
+       spin_lock_irqsave(&port->lock, flags);
+
+       port_setup(port, offset, true);
+
+       spin_unlock_irqrestore(&port->lock, flags);
+
+       return 0;
+}
+
+static struct pinmux_ops adi_pinmux_ops = {
+       .enable = adi_pinmux_enable,
+       .disable = adi_pinmux_disable,
+       .get_functions_count = adi_pinmux_get_funcs_count,
+       .get_function_name = adi_pinmux_get_func_name,
+       .get_function_groups = adi_pinmux_get_groups,
+       .gpio_request_enable = adi_pinmux_request_gpio,
+};
+
+
+static struct pinctrl_desc adi_pinmux_desc = {
+       .name = DRIVER_NAME,
+       .pctlops = &adi_pctrl_ops,
+       .pmxops = &adi_pinmux_ops,
+       .owner = THIS_MODULE,
+};
+
+static int adi_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+       return pinctrl_request_gpio(chip->base + offset);
+}
+
+static void adi_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+       pinctrl_free_gpio(chip->base + offset);
+}
+
+static int adi_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+       struct gpio_port *port;
+       unsigned long flags;
+
+       port = container_of(chip, struct gpio_port, chip);
+
+       spin_lock_irqsave(&port->lock, flags);
+
+       writew(BIT(offset), &port->regs->dir_clear);
+       writew(readw(&port->regs->inen) | BIT(offset), &port->regs->inen);
+
+       spin_unlock_irqrestore(&port->lock, flags);
+
+       return 0;
+}
+
+static void adi_gpio_set_value(struct gpio_chip *chip, unsigned offset,
+       int value)
+{
+       struct gpio_port *port = container_of(chip, struct gpio_port, chip);
+       struct gpio_port_t *regs = port->regs;
+       unsigned long flags;
+
+       spin_lock_irqsave(&port->lock, flags);
+
+       if (value)
+               writew(BIT(offset), &regs->data_set);
+       else
+               writew(BIT(offset), &regs->data_clear);
+
+       spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static int adi_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+       int value)
+{
+       struct gpio_port *port = container_of(chip, struct gpio_port, chip);
+       struct gpio_port_t *regs = port->regs;
+       unsigned long flags;
+
+       spin_lock_irqsave(&port->lock, flags);
+
+       writew(readw(&regs->inen) & ~BIT(offset), &regs->inen);
+       if (value)
+               writew(BIT(offset), &regs->data_set);
+       else
+               writew(BIT(offset), &regs->data_clear);
+       writew(BIT(offset), &regs->dir_set);
+
+       spin_unlock_irqrestore(&port->lock, flags);
+
+       return 0;
+}
+
+static int adi_gpio_get_value(struct gpio_chip *chip, unsigned offset)
+{
+       struct gpio_port *port = container_of(chip, struct gpio_port, chip);
+       struct gpio_port_t *regs = port->regs;
+       unsigned long flags;
+       int ret;
+
+       spin_lock_irqsave(&port->lock, flags);
+
+       ret = !!(readw(&regs->data) & BIT(offset));
+
+       spin_unlock_irqrestore(&port->lock, flags);
+
+       return ret;
+}
+
+static int adi_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+       struct gpio_port *port = container_of(chip, struct gpio_port, chip);
+
+       if (port->irq_base >= 0)
+               return irq_find_mapping(port->domain, offset);
+       else
+               return irq_create_mapping(port->domain, offset);
+}
+
+static int adi_pint_map_port(struct gpio_pint *pint, bool assign, u8 map,
+       struct irq_domain *domain)
+{
+       struct gpio_pint_regs *regs = pint->regs;
+       u32 map_mask;
+
+       if (pint->map_count > 1)
+               return -EINVAL;
+
+       pint->map_count++;
+
+       /* The map_mask of each gpio port is a 16-bit duplicate
+        * of the 8-bit map. It can be set to either high 16 bits or low
+        * 16 bits of the pint assignment register.
+        */
+       map_mask = (map << 8) | map;
+       if (assign) {
+               map_mask <<= PINT_HI_OFFSET;
+               writel((readl(&regs->assign) & 0xFFFF) | map_mask,
+                       &regs->assign);
+       } else
+               writel((readl(&regs->assign) & 0xFFFF0000) | map_mask,
+                       &regs->assign);
+
+       pint->domain[assign] = domain;
+
+       return 0;
+}
+
+static int adi_gpio_pint_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct resource *res;
+       struct gpio_pint *pint;
+
+       pint = devm_kzalloc(dev, sizeof(struct gpio_pint), GFP_KERNEL);
+       if (!pint) {
+               dev_err(dev, "Memory alloc failed\n");
+               return -ENOMEM;
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       pint->base = devm_ioremap_resource(dev, res);
+       if (IS_ERR(pint->base))
+               return PTR_ERR(pint->base);
+
+       pint->regs = (struct gpio_pint_regs *)pint->base;
+
+       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (!res) {
+               dev_err(dev, "Invalid IRQ resource\n");
+               return -ENODEV;
+       }
+
+       spin_lock_init(&pint->lock);
+
+       pint->irq = res->start;
+       pint->pint_map_port = adi_pint_map_port;
+       platform_set_drvdata(pdev, pint);
+
+       irq_set_chained_handler(pint->irq, adi_gpio_handle_pint_irq);
+       irq_set_handler_data(pint->irq, pint);
+
+       list_add_tail(&pint->node, &adi_pint_list);
+
+       return 0;
+}
+
+static int adi_gpio_pint_remove(struct platform_device *pdev)
+{
+       struct gpio_pint *pint = platform_get_drvdata(pdev);
+
+       list_del(&pint->node);
+       irq_set_handler(pint->irq, handle_simple_irq);
+
+       return 0;
+}
+
+static int adi_gpio_irq_map(struct irq_domain *d, unsigned int irq,
+                               irq_hw_number_t hwirq)
+{
+       struct gpio_port *port = d->host_data;
+
+       if (!port)
+               return -EINVAL;
+
+       irq_set_chip_data(irq, port);
+       irq_set_chip_and_handler(irq, &adi_gpio_irqchip,
+                               handle_level_irq);
+
+       return 0;
+}
+
+const struct irq_domain_ops adi_gpio_irq_domain_ops = {
+       .map = adi_gpio_irq_map,
+       .xlate = irq_domain_xlate_onecell,
+};
+
+static int adi_gpio_init_int(struct gpio_port *port)
+{
+       struct device_node *node = port->dev->of_node;
+       struct gpio_pint *pint = port->pint;
+       int ret;
+
+       port->domain = irq_domain_add_linear(node, port->width,
+                               &adi_gpio_irq_domain_ops, port);
+       if (!port->domain) {
+               dev_err(port->dev, "Failed to create irqdomain\n");
+               return -ENOSYS;
+       }
+
+       /* According to BF54x and BF60x HRM, pin interrupt devices are not
+        * part of the GPIO port device. in GPIO interrupt mode, the GPIO
+        * pins of multiple port devices can be routed into one pin interrupt
+        * device. The mapping can be configured by setting pint assignment
+        * register with the mapping value of different GPIO port. This is
+        * done via function pint_map_port().
+        */
+       ret = pint->pint_map_port(port->pint, port->pint_assign,
+                       port->pint_map, port->domain);
+       if (ret)
+               return ret;
+
+       if (port->irq_base >= 0) {
+               ret = irq_create_strict_mappings(port->domain, port->irq_base,
+                                       0, port->width);
+               if (ret) {
+                       dev_err(port->dev, "Couldn't associate to domain\n");
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+#define DEVNAME_SIZE 16
+
+static int adi_gpio_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       const struct adi_pinctrl_gpio_platform_data *pdata;
+       struct resource *res;
+       struct gpio_port *port;
+       char pinctrl_devname[DEVNAME_SIZE];
+       static int gpio;
+       int ret = 0, ret1;
+
+       pdata = dev->platform_data;
+       if (!pdata)
+               return -EINVAL;
+
+       port = devm_kzalloc(dev, sizeof(struct gpio_port), GFP_KERNEL);
+       if (!port) {
+               dev_err(dev, "Memory alloc failed\n");
+               return -ENOMEM;
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       port->base = devm_ioremap_resource(dev, res);
+       if (IS_ERR(port->base))
+               return PTR_ERR(port->base);
+
+       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (!res)
+               port->irq_base = -1;
+       else
+               port->irq_base = res->start;
+
+       port->width = pdata->port_width;
+       port->dev = dev;
+       port->regs = (struct gpio_port_t *)port->base;
+       port->pint_assign = pdata->pint_assign;
+       port->pint_map = pdata->pint_map;
+
+       port->pint = find_gpio_pint(pdata->pint_id);
+       if (port->pint) {
+               ret = adi_gpio_init_int(port);
+               if (ret)
+                       return ret;
+       }
+
+       spin_lock_init(&port->lock);
+
+       platform_set_drvdata(pdev, port);
+
+       port->chip.label                = "adi-gpio";
+       port->chip.direction_input      = adi_gpio_direction_input;
+       port->chip.get                  = adi_gpio_get_value;
+       port->chip.direction_output     = adi_gpio_direction_output;
+       port->chip.set                  = adi_gpio_set_value;
+       port->chip.request              = adi_gpio_request;
+       port->chip.free                 = adi_gpio_free;
+       port->chip.to_irq               = adi_gpio_to_irq;
+       if (pdata->port_gpio_base > 0)
+               port->chip.base         = pdata->port_gpio_base;
+       else
+               port->chip.base         = gpio;
+       port->chip.ngpio                = port->width;
+       gpio = port->chip.base + port->width;
+
+       ret = gpiochip_add(&port->chip);
+       if (ret) {
+               dev_err(&pdev->dev, "Fail to add GPIO chip.\n");
+               goto out_remove_domain;
+       }
+
+       /* Add gpio pin range */
+       snprintf(pinctrl_devname, DEVNAME_SIZE, "pinctrl-adi2.%d",
+               pdata->pinctrl_id);
+       pinctrl_devname[DEVNAME_SIZE - 1] = 0;
+       ret = gpiochip_add_pin_range(&port->chip, pinctrl_devname,
+               0, pdata->port_pin_base, port->width);
+       if (ret) {
+               dev_err(&pdev->dev, "Fail to add pin range to %s.\n",
+                               pinctrl_devname);
+               goto out_remove_gpiochip;
+       }
+
+       list_add_tail(&port->node, &adi_gpio_port_list);
+
+       return 0;
+
+out_remove_gpiochip:
+       ret1 = gpiochip_remove(&port->chip);
+out_remove_domain:
+       if (port->pint)
+               irq_domain_remove(port->domain);
+
+       return ret;
+}
+
+static int adi_gpio_remove(struct platform_device *pdev)
+{
+       struct gpio_port *port = platform_get_drvdata(pdev);
+       int ret;
+       u8 offset;
+
+       list_del(&port->node);
+       gpiochip_remove_pin_ranges(&port->chip);
+       ret = gpiochip_remove(&port->chip);
+       if (port->pint) {
+               for (offset = 0; offset < port->width; offset++)
+                       irq_dispose_mapping(irq_find_mapping(port->domain,
+                               offset));
+               irq_domain_remove(port->domain);
+       }
+
+       return ret;
+}
+
+static int adi_pinctrl_probe(struct platform_device *pdev)
+{
+       struct adi_pinctrl *pinctrl;
+
+       pinctrl = devm_kzalloc(&pdev->dev, sizeof(*pinctrl), GFP_KERNEL);
+       if (!pinctrl)
+               return -ENOMEM;
+
+       pinctrl->dev = &pdev->dev;
+
+       adi_pinctrl_soc_init(&pinctrl->soc);
+
+       adi_pinmux_desc.pins = pinctrl->soc->pins;
+       adi_pinmux_desc.npins = pinctrl->soc->npins;
+
+       /* Now register the pin controller and all pins it handles */
+       pinctrl->pctl = pinctrl_register(&adi_pinmux_desc, &pdev->dev, pinctrl);
+       if (!pinctrl->pctl) {
+               dev_err(&pdev->dev, "could not register pinctrl ADI2 driver\n");
+               return -EINVAL;
+       }
+
+       platform_set_drvdata(pdev, pinctrl);
+
+       return 0;
+}
+
+static int adi_pinctrl_remove(struct platform_device *pdev)
+{
+       struct adi_pinctrl *pinctrl = platform_get_drvdata(pdev);
+
+       pinctrl_unregister(pinctrl->pctl);
+
+       return 0;
+}
+
+static struct platform_driver adi_pinctrl_driver = {
+       .probe          = adi_pinctrl_probe,
+       .remove         = adi_pinctrl_remove,
+       .driver         = {
+               .name   = DRIVER_NAME,
+       },
+};
+
+static struct platform_driver adi_gpio_pint_driver = {
+       .probe          = adi_gpio_pint_probe,
+       .remove         = adi_gpio_pint_remove,
+       .driver         = {
+               .name   = "adi-gpio-pint",
+       },
+};
+
+static struct platform_driver adi_gpio_driver = {
+       .probe          = adi_gpio_probe,
+       .remove         = adi_gpio_remove,
+       .driver         = {
+               .name   = "adi-gpio",
+       },
+};
+
+static int __init adi_pinctrl_setup(void)
+{
+       int ret;
+
+       ret = platform_driver_register(&adi_pinctrl_driver);
+       if (ret)
+               return ret;
+
+       ret = platform_driver_register(&adi_gpio_pint_driver);
+       if (ret)
+               goto pint_error;
+
+       ret = platform_driver_register(&adi_gpio_driver);
+       if (ret)
+               goto gpio_error;
+
+#ifdef CONFIG_PM
+       register_syscore_ops(&gpio_pm_syscore_ops);
+#endif
+       return ret;
+gpio_error:
+       platform_driver_unregister(&adi_gpio_pint_driver);
+pint_error:
+       platform_driver_unregister(&adi_pinctrl_driver);
+
+       return ret;
+}
+arch_initcall(adi_pinctrl_setup);
+
+MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
+MODULE_DESCRIPTION("ADI gpio2 pin control driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/pinctrl-adi2.h b/drivers/pinctrl/pinctrl-adi2.h
new file mode 100644 (file)
index 0000000..1f06f8d
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Pinctrl Driver for ADI GPIO2 controller
+ *
+ * Copyright 2007-2013 Analog Devices Inc.
+ *
+ * Licensed under the GPLv2 or later
+ */
+
+#ifndef PINCTRL_PINCTRL_ADI2_H
+#define PINCTRL_PINCTRL_ADI2_H
+
+#include <linux/pinctrl/pinctrl.h>
+
+ /**
+ * struct adi_pin_group - describes a pin group
+ * @name: the name of this pin group
+ * @pins: an array of pins
+ * @num: the number of pins in this array
+ */
+struct adi_pin_group {
+       const char *name;
+       const unsigned *pins;
+       const unsigned num;
+};
+
+#define ADI_PIN_GROUP(n, p)  \
+       {                       \
+               .name = n,      \
+               .pins = p,      \
+               .num = ARRAY_SIZE(p),   \
+       }
+
+ /**
+ * struct adi_pmx_func - describes function mux setting of pin groups
+ * @name: the name of this function mux setting
+ * @groups: an array of pin groups
+ * @num_groups: the number of pin groups in this array
+ * @mux: the function mux setting array, end by zero
+ */
+struct adi_pmx_func {
+       const char *name;
+       const char * const *groups;
+       const unsigned num_groups;
+       const unsigned short *mux;
+};
+
+#define ADI_PMX_FUNCTION(n, g, m)              \
+       {                                       \
+               .name = n,                      \
+               .groups = g,                    \
+               .num_groups = ARRAY_SIZE(g),    \
+               .mux = m,                       \
+       }
+
+/**
+ * struct adi_pinctrl_soc_data - ADI pin controller per-SoC configuration
+ * @functions:  The functions supported on this SoC.
+ * @nfunction:  The number of entries in @functions.
+ * @groups:     An array describing all pin groups the pin SoC supports.
+ * @ngroups:    The number of entries in @groups.
+ * @pins:       An array describing all pins the pin controller affects.
+ * @npins:      The number of entries in @pins.
+ */
+struct adi_pinctrl_soc_data {
+       const struct adi_pmx_func *functions;
+       int nfunctions;
+       const struct adi_pin_group *groups;
+       int ngroups;
+       const struct pinctrl_pin_desc *pins;
+       int npins;
+};
+
+void adi_pinctrl_soc_init(const struct adi_pinctrl_soc_data **soc);
+
+#endif /* PINCTRL_PINCTRL_ADI2_H */
diff --git a/drivers/pinctrl/pinctrl-as3722.c b/drivers/pinctrl/pinctrl-as3722.c
new file mode 100644 (file)
index 0000000..01bffc1
--- /dev/null
@@ -0,0 +1,630 @@
+/*
+ * ams AS3722 pin control and GPIO driver.
+ *
+ * Copyright (c) 2013, NVIDIA Corporation.
+ *
+ * Author: Laxman Dewangan <ldewangan@nvidia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
+ * whether express or implied; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mfd/as3722.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pm.h>
+#include <linux/slab.h>
+
+#include "core.h"
+#include "pinconf.h"
+#include "pinctrl-utils.h"
+
+#define AS3722_PIN_GPIO0               0
+#define AS3722_PIN_GPIO1               1
+#define AS3722_PIN_GPIO2               2
+#define AS3722_PIN_GPIO3               3
+#define AS3722_PIN_GPIO4               4
+#define AS3722_PIN_GPIO5               5
+#define AS3722_PIN_GPIO6               6
+#define AS3722_PIN_GPIO7               7
+#define AS3722_PIN_NUM                 (AS3722_PIN_GPIO7 + 1)
+
+#define AS3722_GPIO_MODE_PULL_UP           BIT(PIN_CONFIG_BIAS_PULL_UP)
+#define AS3722_GPIO_MODE_PULL_DOWN         BIT(PIN_CONFIG_BIAS_PULL_DOWN)
+#define AS3722_GPIO_MODE_HIGH_IMPED        BIT(PIN_CONFIG_BIAS_HIGH_IMPEDANCE)
+#define AS3722_GPIO_MODE_OPEN_DRAIN        BIT(PIN_CONFIG_DRIVE_OPEN_DRAIN)
+
+struct as3722_pin_function {
+       const char *name;
+       const char * const *groups;
+       unsigned ngroups;
+       int mux_option;
+};
+
+struct as3722_gpio_pin_control {
+       bool enable_gpio_invert;
+       unsigned mode_prop;
+       int io_function;
+};
+
+struct as3722_pingroup {
+       const char *name;
+       const unsigned pins[1];
+       unsigned npins;
+};
+
+struct as3722_pctrl_info {
+       struct device *dev;
+       struct pinctrl_dev *pctl;
+       struct as3722 *as3722;
+       struct gpio_chip gpio_chip;
+       int pins_current_opt[AS3722_PIN_NUM];
+       const struct as3722_pin_function *functions;
+       unsigned num_functions;
+       const struct as3722_pingroup *pin_groups;
+       int num_pin_groups;
+       const struct pinctrl_pin_desc *pins;
+       unsigned num_pins;
+       struct as3722_gpio_pin_control gpio_control[AS3722_PIN_NUM];
+};
+
+static const struct pinctrl_pin_desc as3722_pins_desc[] = {
+       PINCTRL_PIN(AS3722_PIN_GPIO0, "gpio0"),
+       PINCTRL_PIN(AS3722_PIN_GPIO1, "gpio1"),
+       PINCTRL_PIN(AS3722_PIN_GPIO2, "gpio2"),
+       PINCTRL_PIN(AS3722_PIN_GPIO3, "gpio3"),
+       PINCTRL_PIN(AS3722_PIN_GPIO4, "gpio4"),
+       PINCTRL_PIN(AS3722_PIN_GPIO5, "gpio5"),
+       PINCTRL_PIN(AS3722_PIN_GPIO6, "gpio6"),
+       PINCTRL_PIN(AS3722_PIN_GPIO7, "gpio7"),
+};
+
+static const char * const gpio_groups[] = {
+       "gpio0",
+       "gpio1",
+       "gpio2",
+       "gpio3",
+       "gpio4",
+       "gpio5",
+       "gpio6",
+       "gpio7",
+};
+
+enum as3722_pinmux_option {
+       AS3722_PINMUX_GPIO                      = 0,
+       AS3722_PINMUX_INTERRUPT_OUT             = 1,
+       AS3722_PINMUX_VSUB_VBAT_UNDEB_LOW_OUT   = 2,
+       AS3722_PINMUX_GPIO_INTERRUPT            = 3,
+       AS3722_PINMUX_PWM_INPUT                 = 4,
+       AS3722_PINMUX_VOLTAGE_IN_STBY           = 5,
+       AS3722_PINMUX_OC_PG_SD0                 = 6,
+       AS3722_PINMUX_PG_OUT                    = 7,
+       AS3722_PINMUX_CLK32K_OUT                = 8,
+       AS3722_PINMUX_WATCHDOG_INPUT            = 9,
+       AS3722_PINMUX_SOFT_RESET_IN             = 11,
+       AS3722_PINMUX_PWM_OUTPUT                = 12,
+       AS3722_PINMUX_VSUB_VBAT_LOW_DEB_OUT     = 13,
+       AS3722_PINMUX_OC_PG_SD6                 = 14,
+};
+
+#define FUNCTION_GROUP(fname, mux)                     \
+       {                                               \
+               .name = #fname,                         \
+               .groups = gpio_groups,                  \
+               .ngroups = ARRAY_SIZE(gpio_groups),     \
+               .mux_option = AS3722_PINMUX_##mux,      \
+       }
+
+static const struct as3722_pin_function as3722_pin_function[] = {
+       FUNCTION_GROUP(gpio, GPIO),
+       FUNCTION_GROUP(interrupt-out, INTERRUPT_OUT),
+       FUNCTION_GROUP(gpio-in-interrupt, GPIO_INTERRUPT),
+       FUNCTION_GROUP(vsup-vbat-low-undebounce-out, VSUB_VBAT_UNDEB_LOW_OUT),
+       FUNCTION_GROUP(vsup-vbat-low-debounce-out, VSUB_VBAT_LOW_DEB_OUT),
+       FUNCTION_GROUP(voltage-in-standby, VOLTAGE_IN_STBY),
+       FUNCTION_GROUP(oc-pg-sd0, OC_PG_SD0),
+       FUNCTION_GROUP(oc-pg-sd6, OC_PG_SD6),
+       FUNCTION_GROUP(powergood-out, PG_OUT),
+       FUNCTION_GROUP(pwm-in, PWM_INPUT),
+       FUNCTION_GROUP(pwm-out, PWM_OUTPUT),
+       FUNCTION_GROUP(clk32k-out, CLK32K_OUT),
+       FUNCTION_GROUP(watchdog-in, WATCHDOG_INPUT),
+       FUNCTION_GROUP(soft-reset-in, SOFT_RESET_IN),
+};
+
+#define AS3722_PINGROUP(pg_name, pin_id) \
+       {                                                               \
+               .name = #pg_name,                                       \
+               .pins = {AS3722_PIN_##pin_id},                          \
+               .npins = 1,                                             \
+       }
+
+static const struct as3722_pingroup as3722_pingroups[] = {
+       AS3722_PINGROUP(gpio0,  GPIO0),
+       AS3722_PINGROUP(gpio1,  GPIO1),
+       AS3722_PINGROUP(gpio2,  GPIO2),
+       AS3722_PINGROUP(gpio3,  GPIO3),
+       AS3722_PINGROUP(gpio4,  GPIO4),
+       AS3722_PINGROUP(gpio5,  GPIO5),
+       AS3722_PINGROUP(gpio6,  GPIO6),
+       AS3722_PINGROUP(gpio7,  GPIO7),
+};
+
+static int as3722_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+       struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
+
+       return as_pci->num_pin_groups;
+}
+
+static const char *as3722_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
+               unsigned group)
+{
+       struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
+
+       return as_pci->pin_groups[group].name;
+}
+
+static int as3722_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+               unsigned group, const unsigned **pins, unsigned *num_pins)
+{
+       struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
+
+       *pins = as_pci->pin_groups[group].pins;
+       *num_pins = as_pci->pin_groups[group].npins;
+       return 0;
+}
+
+static const struct pinctrl_ops as3722_pinctrl_ops = {
+       .get_groups_count = as3722_pinctrl_get_groups_count,
+       .get_group_name = as3722_pinctrl_get_group_name,
+       .get_group_pins = as3722_pinctrl_get_group_pins,
+       .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
+       .dt_free_map = pinctrl_utils_dt_free_map,
+};
+
+static int as3722_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
+{
+       struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
+
+       return as_pci->num_functions;
+}
+
+static const char *as3722_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
+                       unsigned function)
+{
+       struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
+
+       return as_pci->functions[function].name;
+}
+
+static int as3722_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
+               unsigned function, const char * const **groups,
+               unsigned * const num_groups)
+{
+       struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
+
+       *groups = as_pci->functions[function].groups;
+       *num_groups = as_pci->functions[function].ngroups;
+       return 0;
+}
+
+static int as3722_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function,
+               unsigned group)
+{
+       struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
+       int gpio_cntr_reg = AS3722_GPIOn_CONTROL_REG(group);
+       u8 val = AS3722_GPIO_IOSF_VAL(as_pci->functions[function].mux_option);
+       int ret;
+
+       dev_dbg(as_pci->dev, "%s(): GPIO %u pin to function %u and val %u\n",
+               __func__, group, function, val);
+
+       ret = as3722_update_bits(as_pci->as3722, gpio_cntr_reg,
+                       AS3722_GPIO_IOSF_MASK, val);
+       if (ret < 0) {
+               dev_err(as_pci->dev, "GPIO%d_CTRL_REG update failed %d\n",
+                       group, ret);
+               return ret;
+       }
+       as_pci->gpio_control[group].io_function = function;
+       return ret;
+}
+
+static int as3722_pinctrl_gpio_get_mode(unsigned gpio_mode_prop, bool input)
+{
+       if (gpio_mode_prop & AS3722_GPIO_MODE_HIGH_IMPED)
+               return -EINVAL;
+
+       if (gpio_mode_prop & AS3722_GPIO_MODE_OPEN_DRAIN) {
+               if (gpio_mode_prop & AS3722_GPIO_MODE_PULL_UP)
+                       return AS3722_GPIO_MODE_IO_OPEN_DRAIN_PULL_UP;
+               return AS3722_GPIO_MODE_IO_OPEN_DRAIN;
+       }
+       if (input) {
+               if (gpio_mode_prop & AS3722_GPIO_MODE_PULL_UP)
+                       return AS3722_GPIO_MODE_INPUT_PULL_UP;
+               else if (gpio_mode_prop & AS3722_GPIO_MODE_PULL_DOWN)
+                       return AS3722_GPIO_MODE_INPUT_PULL_DOWN;
+               return AS3722_GPIO_MODE_INPUT;
+       }
+       if (gpio_mode_prop & AS3722_GPIO_MODE_PULL_DOWN)
+               return AS3722_GPIO_MODE_OUTPUT_VDDL;
+       return AS3722_GPIO_MODE_OUTPUT_VDDH;
+}
+
+static int as3722_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev,
+               struct pinctrl_gpio_range *range, unsigned offset)
+{
+       struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
+
+       if (as_pci->gpio_control[offset].io_function)
+               return -EBUSY;
+       return 0;
+}
+
+static int as3722_pinctrl_gpio_set_direction(struct pinctrl_dev *pctldev,
+               struct pinctrl_gpio_range *range, unsigned offset, bool input)
+{
+       struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
+       struct as3722 *as3722 = as_pci->as3722;
+       int mode;
+
+       mode = as3722_pinctrl_gpio_get_mode(
+                       as_pci->gpio_control[offset].mode_prop, input);
+       if (mode < 0) {
+               dev_err(as_pci->dev, "%s direction for GPIO %d not supported\n",
+                       (input) ? "Input" : "Output", offset);
+               return mode;
+       }
+
+       if (as_pci->gpio_control[offset].enable_gpio_invert)
+               mode |= AS3722_GPIO_INV;
+
+       return as3722_write(as3722, AS3722_GPIOn_CONTROL_REG(offset), mode);
+}
+
+static const struct pinmux_ops as3722_pinmux_ops = {
+       .get_functions_count    = as3722_pinctrl_get_funcs_count,
+       .get_function_name      = as3722_pinctrl_get_func_name,
+       .get_function_groups    = as3722_pinctrl_get_func_groups,
+       .enable                 = as3722_pinctrl_enable,
+       .gpio_request_enable    = as3722_pinctrl_gpio_request_enable,
+       .gpio_set_direction     = as3722_pinctrl_gpio_set_direction,
+};
+
+static int as3722_pinconf_get(struct pinctrl_dev *pctldev,
+                       unsigned pin, unsigned long *config)
+{
+       struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
+       enum pin_config_param param = pinconf_to_config_param(*config);
+       int arg = 0;
+       u16 prop;
+
+       switch (param) {
+       case PIN_CONFIG_BIAS_DISABLE:
+               prop = AS3722_GPIO_MODE_PULL_UP |
+                               AS3722_GPIO_MODE_PULL_DOWN;
+               if (!(as_pci->gpio_control[pin].mode_prop & prop))
+                       arg = 1;
+               prop = 0;
+               break;
+
+       case PIN_CONFIG_BIAS_PULL_UP:
+               prop = AS3722_GPIO_MODE_PULL_UP;
+               break;
+
+       case PIN_CONFIG_BIAS_PULL_DOWN:
+               prop = AS3722_GPIO_MODE_PULL_DOWN;
+               break;
+
+       case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+               prop = AS3722_GPIO_MODE_OPEN_DRAIN;
+               break;
+
+       case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
+               prop = AS3722_GPIO_MODE_HIGH_IMPED;
+               break;
+
+       default:
+               dev_err(as_pci->dev, "Properties not supported\n");
+               return -ENOTSUPP;
+       }
+
+       if (as_pci->gpio_control[pin].mode_prop & prop)
+               arg = 1;
+
+       *config = pinconf_to_config_packed(param, (u16)arg);
+       return 0;
+}
+
+static int as3722_pinconf_set(struct pinctrl_dev *pctldev,
+                       unsigned pin, unsigned long *configs,
+                       unsigned num_configs)
+{
+       struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
+       enum pin_config_param param;
+       int mode_prop;
+       int i;
+
+       for (i = 0; i < num_configs; i++) {
+               param = pinconf_to_config_param(configs[i]);
+               mode_prop = as_pci->gpio_control[pin].mode_prop;
+
+               switch (param) {
+               case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
+                       break;
+
+               case PIN_CONFIG_BIAS_DISABLE:
+                       mode_prop &= ~(AS3722_GPIO_MODE_PULL_UP |
+                                       AS3722_GPIO_MODE_PULL_DOWN);
+                       break;
+               case PIN_CONFIG_BIAS_PULL_UP:
+                       mode_prop |= AS3722_GPIO_MODE_PULL_UP;
+                       break;
+
+               case PIN_CONFIG_BIAS_PULL_DOWN:
+                       mode_prop |= AS3722_GPIO_MODE_PULL_DOWN;
+                       break;
+
+               case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
+                       mode_prop |= AS3722_GPIO_MODE_HIGH_IMPED;
+                       break;
+
+               case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+                       mode_prop |= AS3722_GPIO_MODE_OPEN_DRAIN;
+                       break;
+
+               default:
+                       dev_err(as_pci->dev, "Properties not supported\n");
+                       return -ENOTSUPP;
+               }
+
+               as_pci->gpio_control[pin].mode_prop = mode_prop;
+       }
+       return 0;
+}
+
+static const struct pinconf_ops as3722_pinconf_ops = {
+       .pin_config_get = as3722_pinconf_get,
+       .pin_config_set = as3722_pinconf_set,
+};
+
+static struct pinctrl_desc as3722_pinctrl_desc = {
+       .pctlops = &as3722_pinctrl_ops,
+       .pmxops = &as3722_pinmux_ops,
+       .confops = &as3722_pinconf_ops,
+       .owner = THIS_MODULE,
+};
+
+static inline struct as3722_pctrl_info *to_as_pci(struct gpio_chip *chip)
+{
+       return container_of(chip, struct as3722_pctrl_info, gpio_chip);
+}
+
+static int as3722_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+       struct as3722_pctrl_info *as_pci = to_as_pci(chip);
+       struct as3722 *as3722 = as_pci->as3722;
+       int ret;
+       u32 reg;
+       u32 control;
+       u32 val;
+       int mode;
+       int invert_enable;
+
+       ret = as3722_read(as3722, AS3722_GPIOn_CONTROL_REG(offset), &control);
+       if (ret < 0) {
+               dev_err(as_pci->dev,
+                       "GPIO_CONTROL%d_REG read failed: %d\n", offset, ret);
+               return ret;
+       }
+
+       invert_enable = !!(control & AS3722_GPIO_INV);
+       mode = control & AS3722_GPIO_MODE_MASK;
+       switch (mode) {
+       case AS3722_GPIO_MODE_INPUT:
+       case AS3722_GPIO_MODE_INPUT_PULL_UP:
+       case AS3722_GPIO_MODE_INPUT_PULL_DOWN:
+       case AS3722_GPIO_MODE_IO_OPEN_DRAIN:
+       case AS3722_GPIO_MODE_IO_OPEN_DRAIN_PULL_UP:
+               reg = AS3722_GPIO_SIGNAL_IN_REG;
+               break;
+       case AS3722_GPIO_MODE_OUTPUT_VDDH:
+       case AS3722_GPIO_MODE_OUTPUT_VDDL:
+               reg = AS3722_GPIO_SIGNAL_OUT_REG;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       ret = as3722_read(as3722, reg, &val);
+       if (ret < 0) {
+               dev_err(as_pci->dev,
+                       "GPIO_SIGNAL_IN_REG read failed: %d\n", ret);
+               return ret;
+       }
+
+       val = !!(val & AS3722_GPIOn_SIGNAL(offset));
+       return (invert_enable) ? !val : val;
+}
+
+static void as3722_gpio_set(struct gpio_chip *chip, unsigned offset,
+               int value)
+{
+       struct as3722_pctrl_info *as_pci = to_as_pci(chip);
+       struct as3722 *as3722 = as_pci->as3722;
+       int en_invert = as_pci->gpio_control[offset].enable_gpio_invert;
+       u32 val;
+       int ret;
+
+       if (value)
+               val = (en_invert) ? 0 : AS3722_GPIOn_SIGNAL(offset);
+       else
+               val = (en_invert) ? AS3722_GPIOn_SIGNAL(offset) : 0;
+
+       ret = as3722_update_bits(as3722, AS3722_GPIO_SIGNAL_OUT_REG,
+                       AS3722_GPIOn_SIGNAL(offset), val);
+       if (ret < 0)
+               dev_err(as_pci->dev,
+                       "GPIO_SIGNAL_OUT_REG update failed: %d\n", ret);
+}
+
+static int as3722_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+       return pinctrl_gpio_direction_input(chip->base + offset);
+}
+
+static int as3722_gpio_direction_output(struct gpio_chip *chip,
+               unsigned offset, int value)
+{
+       as3722_gpio_set(chip, offset, value);
+       return pinctrl_gpio_direction_output(chip->base + offset);
+}
+
+static int as3722_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+       struct as3722_pctrl_info *as_pci = to_as_pci(chip);
+
+       return as3722_irq_get_virq(as_pci->as3722, offset);
+}
+
+static int as3722_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+       return pinctrl_request_gpio(chip->base + offset);
+}
+
+static void as3722_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+       pinctrl_free_gpio(chip->base + offset);
+}
+
+static const struct gpio_chip as3722_gpio_chip = {
+       .label                  = "as3722-gpio",
+       .owner                  = THIS_MODULE,
+       .request                = as3722_gpio_request,
+       .free                   = as3722_gpio_free,
+       .get                    = as3722_gpio_get,
+       .set                    = as3722_gpio_set,
+       .direction_input        = as3722_gpio_direction_input,
+       .direction_output       = as3722_gpio_direction_output,
+       .to_irq                 = as3722_gpio_to_irq,
+       .can_sleep              = 1,
+       .ngpio                  = AS3722_PIN_NUM,
+       .base                   = -1,
+};
+
+static int as3722_pinctrl_probe(struct platform_device *pdev)
+{
+       struct as3722_pctrl_info *as_pci;
+       int ret;
+       int tret;
+
+       as_pci = devm_kzalloc(&pdev->dev, sizeof(*as_pci), GFP_KERNEL);
+       if (!as_pci)
+               return -ENOMEM;
+
+       as_pci->dev = &pdev->dev;
+       as_pci->dev->of_node = pdev->dev.parent->of_node;
+       as_pci->as3722 = dev_get_drvdata(pdev->dev.parent);
+       platform_set_drvdata(pdev, as_pci);
+
+       as_pci->pins = as3722_pins_desc;
+       as_pci->num_pins = ARRAY_SIZE(as3722_pins_desc);
+       as_pci->functions = as3722_pin_function;
+       as_pci->num_functions = ARRAY_SIZE(as3722_pin_function);
+       as_pci->pin_groups = as3722_pingroups;
+       as_pci->num_pin_groups = ARRAY_SIZE(as3722_pingroups);
+       as3722_pinctrl_desc.name = dev_name(&pdev->dev);
+       as3722_pinctrl_desc.pins = as3722_pins_desc;
+       as3722_pinctrl_desc.npins = ARRAY_SIZE(as3722_pins_desc);
+       as_pci->pctl = pinctrl_register(&as3722_pinctrl_desc,
+                                       &pdev->dev, as_pci);
+       if (!as_pci->pctl) {
+               dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
+               return -EINVAL;
+       }
+
+       as_pci->gpio_chip = as3722_gpio_chip;
+       as_pci->gpio_chip.dev = &pdev->dev;
+       as_pci->gpio_chip.of_node = pdev->dev.parent->of_node;
+       ret = gpiochip_add(&as_pci->gpio_chip);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Couldn't register gpiochip, %d\n", ret);
+               goto fail_chip_add;
+       }
+
+       ret = gpiochip_add_pin_range(&as_pci->gpio_chip, dev_name(&pdev->dev),
+                               0, 0, AS3722_PIN_NUM);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Couldn't add pin range, %d\n", ret);
+               goto fail_range_add;
+       }
+
+       return 0;
+
+fail_range_add:
+       tret = gpiochip_remove(&as_pci->gpio_chip);
+       if (tret < 0)
+               dev_warn(&pdev->dev, "Couldn't remove gpio chip, %d\n", tret);
+
+fail_chip_add:
+       pinctrl_unregister(as_pci->pctl);
+       return ret;
+}
+
+static int as3722_pinctrl_remove(struct platform_device *pdev)
+{
+       struct as3722_pctrl_info *as_pci = platform_get_drvdata(pdev);
+       int ret;
+
+       ret = gpiochip_remove(&as_pci->gpio_chip);
+       if (ret < 0)
+               return ret;
+       pinctrl_unregister(as_pci->pctl);
+       return 0;
+}
+
+static struct of_device_id as3722_pinctrl_of_match[] = {
+       { .compatible = "ams,as3722-pinctrl", },
+       { },
+};
+MODULE_DEVICE_TABLE(of, as3722_pinctrl_of_match);
+
+static struct platform_driver as3722_pinctrl_driver = {
+       .driver = {
+               .name = "as3722-pinctrl",
+               .owner = THIS_MODULE,
+               .of_match_table = as3722_pinctrl_of_match,
+       },
+       .probe = as3722_pinctrl_probe,
+       .remove = as3722_pinctrl_remove,
+};
+module_platform_driver(as3722_pinctrl_driver);
+
+MODULE_ALIAS("platform:as3722-pinctrl");
+MODULE_DESCRIPTION("AS3722 pin control and GPIO driver");
+MODULE_AUTHOR("Laxman Dewangan<ldewangan@nvidia.com>");
+MODULE_LICENSE("GPL v2");
index f350fd2e170ef3b38ec765764bee32236ba287f4..c4598dcf333c3d6050e29dfce6f6893c9ab17785 100644 (file)
@@ -144,11 +144,11 @@ struct at91_pinctrl_mux_ops {
        void (*mux_C_periph)(void __iomem *pio, unsigned mask);
        void (*mux_D_periph)(void __iomem *pio, unsigned mask);
        bool (*get_deglitch)(void __iomem *pio, unsigned pin);
-       void (*set_deglitch)(void __iomem *pio, unsigned mask, bool in_on);
+       void (*set_deglitch)(void __iomem *pio, unsigned mask, bool is_on);
        bool (*get_debounce)(void __iomem *pio, unsigned pin, u32 *div);
-       void (*set_debounce)(void __iomem *pio, unsigned mask, bool in_on, u32 div);
+       void (*set_debounce)(void __iomem *pio, unsigned mask, bool is_on, u32 div);
        bool (*get_pulldown)(void __iomem *pio, unsigned pin);
-       void (*set_pulldown)(void __iomem *pio, unsigned mask, bool in_on);
+       void (*set_pulldown)(void __iomem *pio, unsigned mask, bool is_on);
        bool (*get_schmitt_trig)(void __iomem *pio, unsigned pin);
        void (*disable_schmitt_trig)(void __iomem *pio, unsigned mask);
        /* irq */
@@ -243,7 +243,7 @@ static int at91_dt_node_to_map(struct pinctrl_dev *pctldev,
        int i;
 
        /*
-        * first find the group of this node and check if we need create
+        * first find the group of this node and check if we need to create
         * config maps for pins
         */
        grp = at91_pinctrl_find_group_by_name(info, np->name);
@@ -417,6 +417,14 @@ static void at91_mux_set_deglitch(void __iomem *pio, unsigned mask, bool is_on)
        __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR));
 }
 
+static bool at91_mux_pio3_get_deglitch(void __iomem *pio, unsigned pin)
+{
+       if ((__raw_readl(pio + PIO_IFSR) >> pin) & 0x1)
+               return !((__raw_readl(pio + PIO_IFSCSR) >> pin) & 0x1);
+
+       return false;
+}
+
 static void at91_mux_pio3_set_deglitch(void __iomem *pio, unsigned mask, bool is_on)
 {
        if (is_on)
@@ -428,7 +436,8 @@ static bool at91_mux_pio3_get_debounce(void __iomem *pio, unsigned pin, u32 *div
 {
        *div = __raw_readl(pio + PIO_SCDR);
 
-       return (__raw_readl(pio + PIO_IFSCSR) >> pin) & 0x1;
+       return ((__raw_readl(pio + PIO_IFSR) >> pin) & 0x1) &&
+              ((__raw_readl(pio + PIO_IFSCSR) >> pin) & 0x1);
 }
 
 static void at91_mux_pio3_set_debounce(void __iomem *pio, unsigned mask,
@@ -438,9 +447,8 @@ static void at91_mux_pio3_set_debounce(void __iomem *pio, unsigned mask,
                __raw_writel(mask, pio + PIO_IFSCER);
                __raw_writel(div & PIO_SCDR_DIV, pio + PIO_SCDR);
                __raw_writel(mask, pio + PIO_IFER);
-       } else {
-               __raw_writel(mask, pio + PIO_IFDR);
-       }
+       } else
+               __raw_writel(mask, pio + PIO_IFSCDR);
 }
 
 static bool at91_mux_pio3_get_pulldown(void __iomem *pio, unsigned pin)
@@ -478,7 +486,7 @@ static struct at91_pinctrl_mux_ops at91sam9x5_ops = {
        .mux_B_periph   = at91_mux_pio3_set_B_periph,
        .mux_C_periph   = at91_mux_pio3_set_C_periph,
        .mux_D_periph   = at91_mux_pio3_set_D_periph,
-       .get_deglitch   = at91_mux_get_deglitch,
+       .get_deglitch   = at91_mux_pio3_get_deglitch,
        .set_deglitch   = at91_mux_pio3_set_deglitch,
        .get_debounce   = at91_mux_pio3_get_debounce,
        .set_debounce   = at91_mux_pio3_set_debounce,
@@ -564,7 +572,7 @@ static int at91_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
                info->functions[selector].name, info->groups[group].name);
 
        /* first check that all the pins of the group are valid with a valid
-        * paramter */
+        * parameter */
        for (i = 0; i < npins; i++) {
                pin = &pins_conf[i];
                ret = pin_check_config(info, info->groups[group].name, i, pin);
@@ -958,7 +966,7 @@ static int at91_pinctrl_probe_dt(struct platform_device *pdev,
        at91_pinctrl_child_count(info, np);
 
        if (info->nbanks < 1) {
-               dev_err(&pdev->dev, "you need to specify atleast one gpio-controller\n");
+               dev_err(&pdev->dev, "you need to specify at least one gpio-controller\n");
                return -EINVAL;
        }
 
@@ -1495,7 +1503,7 @@ static int at91_gpio_of_irq_setup(struct device_node *node,
        if (at91_gpio->pioc_idx)
                prev = gpio_chips[at91_gpio->pioc_idx - 1];
 
-       /* The toplevel handler handles one bank of GPIOs, except
+       /* The top level handler handles one bank of GPIOs, except
         * on some SoC it can handles up to three...
         * We only set up the handler for the first of the list.
         */
@@ -1671,7 +1679,7 @@ static struct platform_driver at91_gpio_driver = {
        .driver = {
                .name = "gpio-at91",
                .owner = THIS_MODULE,
-               .of_match_table = of_match_ptr(at91_gpio_of_match),
+               .of_match_table = at91_gpio_of_match,
        },
        .probe = at91_gpio_probe,
 };
@@ -1680,7 +1688,7 @@ static struct platform_driver at91_pinctrl_driver = {
        .driver = {
                .name = "pinctrl-at91",
                .owner = THIS_MODULE,
-               .of_match_table = of_match_ptr(at91_pinctrl_of_match),
+               .of_match_table = at91_pinctrl_of_match,
        },
        .probe = at91_pinctrl_probe,
        .remove = at91_pinctrl_remove,
index 544d469c5a7b4dfae349e14503600e22e03b8017..8fe2ab0a769812ddf1af7737b126c68525de5057 100644 (file)
@@ -1048,7 +1048,7 @@ static struct platform_driver exynos5440_pinctrl_driver = {
        .driver = {
                .name   = "exynos5440-pinctrl",
                .owner  = THIS_MODULE,
-               .of_match_table = of_match_ptr(exynos5440_pinctrl_dt_match),
+               .of_match_table = exynos5440_pinctrl_dt_match,
        },
 };
 
index c4549829fc47311accd57592d86ed65c5bfc70d8..278a04ae8940acd4b1abc09b70b2d1cd57dbb534 100644 (file)
@@ -1019,7 +1019,7 @@ static struct platform_driver imx35_pinctrl_driver = {
        .driver = {
                .name = "imx35-pinctrl",
                .owner = THIS_MODULE,
-               .of_match_table = of_match_ptr(imx35_pinctrl_of_match),
+               .of_match_table = imx35_pinctrl_of_match,
        },
        .probe = imx35_pinctrl_probe,
        .remove = imx_pinctrl_remove,
index db268b9200792de47485f38f629c750086600d54..19ab182bef6172ba41ac10b13bf8c11e06fdcc95 100644 (file)
@@ -782,7 +782,7 @@ static struct platform_driver imx51_pinctrl_driver = {
        .driver = {
                .name = "imx51-pinctrl",
                .owner = THIS_MODULE,
-               .of_match_table = of_match_ptr(imx51_pinctrl_of_match),
+               .of_match_table = imx51_pinctrl_of_match,
        },
        .probe = imx51_pinctrl_probe,
        .remove = imx_pinctrl_remove,
index 17562ae9005ce3488f7cc088297d9ef81f402bbd..f8d45c4cfde756f6ae60e543989752e3033666ab 100644 (file)
@@ -468,7 +468,7 @@ static struct platform_driver imx53_pinctrl_driver = {
        .driver = {
                .name = "imx53-pinctrl",
                .owner = THIS_MODULE,
-               .of_match_table = of_match_ptr(imx53_pinctrl_of_match),
+               .of_match_table = imx53_pinctrl_of_match,
        },
        .probe = imx53_pinctrl_probe,
        .remove = imx_pinctrl_remove,
index a76b724279364b00b42c585e77dd29beb8282eda..db2a1489bd995c7cf93503a4eeda681355b8fcec 100644 (file)
@@ -474,7 +474,7 @@ static struct platform_driver imx6dl_pinctrl_driver = {
        .driver = {
                .name = "imx6dl-pinctrl",
                .owner = THIS_MODULE,
-               .of_match_table = of_match_ptr(imx6dl_pinctrl_of_match),
+               .of_match_table = imx6dl_pinctrl_of_match,
        },
        .probe = imx6dl_pinctrl_probe,
        .remove = imx_pinctrl_remove,
index 76dd9c4949f4ce4665c51a6b025799b639fa9d96..8eb5ac1bd5f695016a0f52576cf36a10ad4b5986 100644 (file)
@@ -480,7 +480,7 @@ static struct platform_driver imx6q_pinctrl_driver = {
        .driver = {
                .name = "imx6q-pinctrl",
                .owner = THIS_MODULE,
-               .of_match_table = of_match_ptr(imx6q_pinctrl_of_match),
+               .of_match_table = imx6q_pinctrl_of_match,
        },
        .probe = imx6q_pinctrl_probe,
        .remove = imx_pinctrl_remove,
index 4eb7ccab5f2d1806f17012da9b38b9467db472c7..f21b7389df3c2771127e381030151d124782de36 100644 (file)
@@ -380,7 +380,7 @@ static struct platform_driver imx6sl_pinctrl_driver = {
        .driver = {
                .name = "imx6sl-pinctrl",
                .owner = THIS_MODULE,
-               .of_match_table = of_match_ptr(imx6sl_pinctrl_of_match),
+               .of_match_table = imx6sl_pinctrl_of_match,
        },
        .probe = imx6sl_pinctrl_probe,
        .remove = imx_pinctrl_remove,
index 30c4d356cb33510a550aec1d467ac40936552a60..f13d0e78a41ca649583911c1cc90fc78c6490e4c 100644 (file)
@@ -891,9 +891,6 @@ static int palmas_pinconf_set(struct pinctrl_dev *pctldev,
                param = pinconf_to_config_param(configs[i]);
                param_val = pinconf_to_config_argument(configs[i]);
 
-               if (param == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
-                       continue;
-
                switch (param) {
                case PIN_CONFIG_BIAS_DISABLE:
                case PIN_CONFIG_BIAS_PULL_UP:
@@ -962,26 +959,9 @@ static int palmas_pinconf_set(struct pinctrl_dev *pctldev,
        return 0;
 }
 
-static int palmas_pinconf_group_get(struct pinctrl_dev *pctldev,
-                               unsigned group, unsigned long *config)
-{
-       dev_err(pctldev->dev, "palmas_pinconf_group_get op not supported\n");
-       return -ENOTSUPP;
-}
-
-static int palmas_pinconf_group_set(struct pinctrl_dev *pctldev,
-                               unsigned group, unsigned long *configs,
-                               unsigned num_configs)
-{
-       dev_err(pctldev->dev, "palmas_pinconf_group_set op not supported\n");
-       return -ENOTSUPP;
-}
-
 static const struct pinconf_ops palmas_pinconf_ops = {
        .pin_config_get = palmas_pinconf_get,
        .pin_config_set = palmas_pinconf_set,
-       .pin_config_group_get = palmas_pinconf_group_get,
-       .pin_config_group_set = palmas_pinconf_group_set,
 };
 
 static struct pinctrl_desc palmas_pinctrl_desc = {
index e0718b7c4abc347ff359bfa526060e663a6a811b..e939c28cbf1fe13573f7538a2e9d01071b094aa1 100644 (file)
 #define GPIO_EXT_PORT          0x50
 #define GPIO_LS_SYNC           0x60
 
+enum rockchip_pinctrl_type {
+       RK2928,
+       RK3066B,
+       RK3188,
+};
+
+enum rockchip_pin_bank_type {
+       COMMON_BANK,
+       RK3188_BANK0,
+};
+
 /**
  * @reg_base: register base of the gpio bank
+ * @reg_pull: optional separate register for additional pull settings
  * @clk: clock of the gpio bank
  * @irq: interrupt of the gpio bank
  * @pin_base: first pin number
  */
 struct rockchip_pin_bank {
        void __iomem                    *reg_base;
+       void __iomem                    *reg_pull;
        struct clk                      *clk;
        int                             irq;
        u32                             pin_base;
        u8                              nr_pins;
        char                            *name;
        u8                              bank_num;
+       enum rockchip_pin_bank_type     bank_type;
        bool                            valid;
        struct device_node              *of_node;
        struct rockchip_pinctrl         *drvdata;
@@ -87,7 +101,7 @@ struct rockchip_pin_bank {
        struct gpio_chip                gpio_chip;
        struct pinctrl_gpio_range       grange;
        spinlock_t                      slock;
-
+       u32                             toggle_edge_mode;
 };
 
 #define PIN_BANK(id, pins, label)                      \
@@ -98,18 +112,16 @@ struct rockchip_pin_bank {
        }
 
 /**
- * @pull_auto: some SoCs don't allow pulls to be specified as up or down, but
- *            instead decide this automatically based on the pad-type.
  */
 struct rockchip_pin_ctrl {
        struct rockchip_pin_bank        *pin_banks;
        u32                             nr_banks;
        u32                             nr_pins;
        char                            *label;
+       enum rockchip_pinctrl_type      type;
        int                             mux_offset;
-       int                             pull_offset;
-       bool                            pull_auto;
-       int                             pull_bank_stride;
+       void    (*pull_calc_reg)(struct rockchip_pin_bank *bank, int pin_num,
+                                void __iomem **reg, u8 *bit);
 };
 
 struct rockchip_pin_config {
@@ -148,6 +160,7 @@ struct rockchip_pmx_func {
 
 struct rockchip_pinctrl {
        void __iomem                    *reg_base;
+       void __iomem                    *reg_pull;
        struct device                   *dev;
        struct rockchip_pin_ctrl        *ctrl;
        struct pinctrl_desc             pctl;
@@ -354,31 +367,92 @@ static void rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
        spin_unlock_irqrestore(&bank->slock, flags);
 }
 
+#define RK2928_PULL_OFFSET             0x118
+#define RK2928_PULL_PINS_PER_REG       16
+#define RK2928_PULL_BANK_STRIDE                8
+
+static void rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+                                   int pin_num, void __iomem **reg, u8 *bit)
+{
+       struct rockchip_pinctrl *info = bank->drvdata;
+
+       *reg = info->reg_base + RK2928_PULL_OFFSET;
+       *reg += bank->bank_num * RK2928_PULL_BANK_STRIDE;
+       *reg += (pin_num / RK2928_PULL_PINS_PER_REG) * 4;
+
+       *bit = pin_num % RK2928_PULL_PINS_PER_REG;
+};
+
+#define RK3188_PULL_BITS_PER_PIN       2
+#define RK3188_PULL_PINS_PER_REG       8
+#define RK3188_PULL_BANK_STRIDE                16
+
+static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+                                   int pin_num, void __iomem **reg, u8 *bit)
+{
+       struct rockchip_pinctrl *info = bank->drvdata;
+
+       /* The first 12 pins of the first bank are located elsewhere */
+       if (bank->bank_type == RK3188_BANK0 && pin_num < 12) {
+               *reg = bank->reg_pull +
+                               ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
+               *bit = pin_num % RK3188_PULL_PINS_PER_REG;
+               *bit *= RK3188_PULL_BITS_PER_PIN;
+       } else {
+               *reg = info->reg_pull - 4;
+               *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
+               *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
+
+               /*
+                * The bits in these registers have an inverse ordering
+                * with the lowest pin being in bits 15:14 and the highest
+                * pin in bits 1:0
+                */
+               *bit = 7 - (pin_num % RK3188_PULL_PINS_PER_REG);
+               *bit *= RK3188_PULL_BITS_PER_PIN;
+       }
+}
+
 static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
 {
        struct rockchip_pinctrl *info = bank->drvdata;
        struct rockchip_pin_ctrl *ctrl = info->ctrl;
        void __iomem *reg;
        u8 bit;
+       u32 data;
 
        /* rk3066b does support any pulls */
-       if (!ctrl->pull_offset)
+       if (ctrl->type == RK3066B)
                return PIN_CONFIG_BIAS_DISABLE;
 
-       reg = info->reg_base + ctrl->pull_offset;
-
-       if (ctrl->pull_auto) {
-               reg += bank->bank_num * ctrl->pull_bank_stride;
-               reg += (pin_num / 16) * 4;
-               bit = pin_num % 16;
+       ctrl->pull_calc_reg(bank, pin_num, &reg, &bit);
 
+       switch (ctrl->type) {
+       case RK2928:
                return !(readl_relaxed(reg) & BIT(bit))
                                ? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT
                                : PIN_CONFIG_BIAS_DISABLE;
-       } else {
-               dev_err(info->dev, "pull support for rk31xx not implemented\n");
+       case RK3188:
+               data = readl_relaxed(reg) >> bit;
+               data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1;
+
+               switch (data) {
+               case 0:
+                       return PIN_CONFIG_BIAS_DISABLE;
+               case 1:
+                       return PIN_CONFIG_BIAS_PULL_UP;
+               case 2:
+                       return PIN_CONFIG_BIAS_PULL_DOWN;
+               case 3:
+                       return PIN_CONFIG_BIAS_BUS_HOLD;
+               }
+
+               dev_err(info->dev, "unknown pull setting\n");
                return -EIO;
-       }
+       default:
+               dev_err(info->dev, "unsupported pinctrl type\n");
+               return -EINVAL;
+       };
 }
 
 static int rockchip_set_pull(struct rockchip_pin_bank *bank,
@@ -395,22 +469,13 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
                 bank->bank_num, pin_num, pull);
 
        /* rk3066b does support any pulls */
-       if (!ctrl->pull_offset)
+       if (ctrl->type == RK3066B)
                return pull ? -EINVAL : 0;
 
-       reg = info->reg_base + ctrl->pull_offset;
-
-       if (ctrl->pull_auto) {
-               if (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT &&
-                                       pull != PIN_CONFIG_BIAS_DISABLE) {
-                       dev_err(info->dev, "only PIN_DEFAULT and DISABLE allowed\n");
-                       return -EINVAL;
-               }
-
-               reg += bank->bank_num * ctrl->pull_bank_stride;
-               reg += (pin_num / 16) * 4;
-               bit = pin_num % 16;
+       ctrl->pull_calc_reg(bank, pin_num, &reg, &bit);
 
+       switch (ctrl->type) {
+       case RK2928:
                spin_lock_irqsave(&bank->slock, flags);
 
                data = BIT(bit + 16);
@@ -419,14 +484,38 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
                writel(data, reg);
 
                spin_unlock_irqrestore(&bank->slock, flags);
-       } else {
-               if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) {
-                       dev_err(info->dev, "pull direction (up/down) needs to be specified\n");
+               break;
+       case RK3188:
+               spin_lock_irqsave(&bank->slock, flags);
+
+               /* enable the write to the equivalent lower bits */
+               data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16);
+
+               switch (pull) {
+               case PIN_CONFIG_BIAS_DISABLE:
+                       break;
+               case PIN_CONFIG_BIAS_PULL_UP:
+                       data |= (1 << bit);
+                       break;
+               case PIN_CONFIG_BIAS_PULL_DOWN:
+                       data |= (2 << bit);
+                       break;
+               case PIN_CONFIG_BIAS_BUS_HOLD:
+                       data |= (3 << bit);
+                       break;
+               default:
+                       dev_err(info->dev, "unsupported pull setting %d\n",
+                               pull);
                        return -EINVAL;
                }
 
-               dev_err(info->dev, "pull support for rk31xx not implemented\n");
-               return -EIO;
+               writel(data, reg);
+
+               spin_unlock_irqrestore(&bank->slock, flags);
+               break;
+       default:
+               dev_err(info->dev, "unsupported pinctrl type\n");
+               return -EINVAL;
        }
 
        return 0;
@@ -556,20 +645,17 @@ static const struct pinmux_ops rockchip_pmx_ops = {
 static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
                                        enum pin_config_param pull)
 {
-       /* rk3066b does support any pulls */
-       if (!ctrl->pull_offset)
+       switch (ctrl->type) {
+       case RK2928:
+               return (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT ||
+                                       pull == PIN_CONFIG_BIAS_DISABLE);
+       case RK3066B:
                return pull ? false : true;
-
-       if (ctrl->pull_auto) {
-               if (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT &&
-                                       pull != PIN_CONFIG_BIAS_DISABLE)
-                       return false;
-       } else {
-               if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
-                       return false;
+       case RK3188:
+               return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT);
        }
 
-       return true;
+       return false;
 }
 
 /* set the pin config settings for a specified pin */
@@ -597,6 +683,7 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
                case PIN_CONFIG_BIAS_PULL_UP:
                case PIN_CONFIG_BIAS_PULL_DOWN:
                case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
+               case PIN_CONFIG_BIAS_BUS_HOLD:
                        if (!rockchip_pinconf_pull_valid(info->ctrl, param))
                                return -ENOTSUPP;
 
@@ -635,6 +722,7 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
        case PIN_CONFIG_BIAS_PULL_UP:
        case PIN_CONFIG_BIAS_PULL_DOWN:
        case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
+       case PIN_CONFIG_BIAS_BUS_HOLD:
                if (!rockchip_pinconf_pull_valid(info->ctrl, param))
                        return -ENOTSUPP;
 
@@ -656,7 +744,11 @@ static const struct pinconf_ops rockchip_pinconf_ops = {
        .pin_config_set                 = rockchip_pinconf_set,
 };
 
-static const char *gpio_compat = "rockchip,gpio-bank";
+static const struct of_device_id rockchip_bank_match[] = {
+       { .compatible = "rockchip,gpio-bank" },
+       { .compatible = "rockchip,rk3188-gpio-bank0" },
+       {},
+};
 
 static void rockchip_pinctrl_child_count(struct rockchip_pinctrl *info,
                                                struct device_node *np)
@@ -664,7 +756,7 @@ static void rockchip_pinctrl_child_count(struct rockchip_pinctrl *info,
        struct device_node *child;
 
        for_each_child_of_node(np, child) {
-               if (of_device_is_compatible(child, gpio_compat))
+               if (of_match_node(rockchip_bank_match, child))
                        continue;
 
                info->nfunctions++;
@@ -807,8 +899,9 @@ static int rockchip_pinctrl_parse_dt(struct platform_device *pdev,
        i = 0;
 
        for_each_child_of_node(np, child) {
-               if (of_device_is_compatible(child, gpio_compat))
+               if (of_match_node(rockchip_bank_match, child))
                        continue;
+
                ret = rockchip_pinctrl_parse_functions(child, info, i++);
                if (ret) {
                        dev_err(&pdev->dev, "failed to parse function\n");
@@ -985,7 +1078,9 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc)
 {
        struct irq_chip *chip = irq_get_chip(irq);
        struct rockchip_pin_bank *bank = irq_get_handler_data(irq);
+       u32 polarity = 0, data = 0;
        u32 pend;
+       bool edge_changed = false;
 
        dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name);
 
@@ -993,6 +1088,12 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc)
 
        pend = readl_relaxed(bank->reg_base + GPIO_INT_STATUS);
 
+       if (bank->toggle_edge_mode) {
+               polarity = readl_relaxed(bank->reg_base +
+                                        GPIO_INT_POLARITY);
+               data = readl_relaxed(bank->reg_base + GPIO_EXT_PORT);
+       }
+
        while (pend) {
                unsigned int virq;
 
@@ -1007,9 +1108,30 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc)
 
                dev_dbg(bank->drvdata->dev, "handling irq %d\n", irq);
 
+               /*
+                * Triggering IRQ on both rising and falling edge
+                * needs manual intervention.
+                */
+               if (bank->toggle_edge_mode & BIT(irq)) {
+                       if (data & BIT(irq))
+                               polarity &= ~BIT(irq);
+                       else
+                               polarity |= BIT(irq);
+
+                       edge_changed = true;
+               }
+
                generic_handle_irq(virq);
        }
 
+       if (bank->toggle_edge_mode && edge_changed) {
+               /* Interrupt params should only be set with ints disabled */
+               data = readl_relaxed(bank->reg_base + GPIO_INTEN);
+               writel_relaxed(0, bank->reg_base + GPIO_INTEN);
+               writel(polarity, bank->reg_base + GPIO_INT_POLARITY);
+               writel(data, bank->reg_base + GPIO_INTEN);
+       }
+
        chained_irq_exit(chip, desc);
 }
 
@@ -1022,6 +1144,12 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
        u32 level;
        u32 data;
 
+       /* make sure the pin is configured as gpio input */
+       rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO);
+       data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
+       data &= ~mask;
+       writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
+
        if (type & IRQ_TYPE_EDGE_BOTH)
                __irq_set_handler_locked(d->irq, handle_edge_irq);
        else
@@ -1033,19 +1161,37 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
        polarity = readl_relaxed(gc->reg_base + GPIO_INT_POLARITY);
 
        switch (type) {
+       case IRQ_TYPE_EDGE_BOTH:
+               bank->toggle_edge_mode |= mask;
+               level |= mask;
+
+               /*
+                * Determine gpio state. If 1 next interrupt should be falling
+                * otherwise rising.
+                */
+               data = readl(bank->reg_base + GPIO_EXT_PORT);
+               if (data & mask)
+                       polarity &= ~mask;
+               else
+                       polarity |= mask;
+               break;
        case IRQ_TYPE_EDGE_RISING:
+               bank->toggle_edge_mode &= ~mask;
                level |= mask;
                polarity |= mask;
                break;
        case IRQ_TYPE_EDGE_FALLING:
+               bank->toggle_edge_mode &= ~mask;
                level |= mask;
                polarity &= ~mask;
                break;
        case IRQ_TYPE_LEVEL_HIGH:
+               bank->toggle_edge_mode &= ~mask;
                level &= ~mask;
                polarity |= mask;
                break;
        case IRQ_TYPE_LEVEL_LOW:
+               bank->toggle_edge_mode &= ~mask;
                level &= ~mask;
                polarity &= ~mask;
                break;
@@ -1059,12 +1205,6 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
 
        irq_gc_unlock(gc);
 
-       /* make sure the pin is configured as gpio input */
-       rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO);
-       data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
-       data &= ~mask;
-       writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
-
        return 0;
 }
 
@@ -1205,6 +1345,26 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank,
        if (IS_ERR(bank->reg_base))
                return PTR_ERR(bank->reg_base);
 
+       /*
+        * special case, where parts of the pull setting-registers are
+        * part of the PMU register space
+        */
+       if (of_device_is_compatible(bank->of_node,
+                                   "rockchip,rk3188-gpio-bank0")) {
+               bank->bank_type = RK3188_BANK0;
+
+               if (of_address_to_resource(bank->of_node, 1, &res)) {
+                       dev_err(dev, "cannot find IO resource for bank\n");
+                       return -ENOENT;
+               }
+
+               bank->reg_pull = devm_ioremap_resource(dev, &res);
+               if (IS_ERR(bank->reg_pull))
+                       return PTR_ERR(bank->reg_pull);
+       } else {
+               bank->bank_type = COMMON_BANK;
+       }
+
        bank->irq = irq_of_parse_and_map(bank->of_node, 0);
 
        bank->clk = of_clk_get(bank->of_node, 0);
@@ -1289,6 +1449,14 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
        if (IS_ERR(info->reg_base))
                return PTR_ERR(info->reg_base);
 
+       /* The RK3188 has its pull registers in a separate place */
+       if (ctrl->type == RK3188) {
+               res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+               info->reg_pull = devm_ioremap_resource(&pdev->dev, res);
+               if (IS_ERR(info->reg_base))
+                       return PTR_ERR(info->reg_base);
+       }
+
        ret = rockchip_gpiolib_register(pdev, info);
        if (ret)
                return ret;
@@ -1315,10 +1483,9 @@ static struct rockchip_pin_ctrl rk2928_pin_ctrl = {
                .pin_banks              = rk2928_pin_banks,
                .nr_banks               = ARRAY_SIZE(rk2928_pin_banks),
                .label                  = "RK2928-GPIO",
+               .type                   = RK2928,
                .mux_offset             = 0xa8,
-               .pull_offset            = 0x118,
-               .pull_auto              = 1,
-               .pull_bank_stride       = 8,
+               .pull_calc_reg          = rk2928_calc_pull_reg_and_bit,
 };
 
 static struct rockchip_pin_bank rk3066a_pin_banks[] = {
@@ -1334,10 +1501,9 @@ static struct rockchip_pin_ctrl rk3066a_pin_ctrl = {
                .pin_banks              = rk3066a_pin_banks,
                .nr_banks               = ARRAY_SIZE(rk3066a_pin_banks),
                .label                  = "RK3066a-GPIO",
+               .type                   = RK2928,
                .mux_offset             = 0xa8,
-               .pull_offset            = 0x118,
-               .pull_auto              = 1,
-               .pull_bank_stride       = 8,
+               .pull_calc_reg          = rk2928_calc_pull_reg_and_bit,
 };
 
 static struct rockchip_pin_bank rk3066b_pin_banks[] = {
@@ -1351,8 +1517,8 @@ static struct rockchip_pin_ctrl rk3066b_pin_ctrl = {
                .pin_banks      = rk3066b_pin_banks,
                .nr_banks       = ARRAY_SIZE(rk3066b_pin_banks),
                .label          = "RK3066b-GPIO",
+               .type           = RK3066B,
                .mux_offset     = 0x60,
-               .pull_offset    = -EINVAL,
 };
 
 static struct rockchip_pin_bank rk3188_pin_banks[] = {
@@ -1366,9 +1532,9 @@ static struct rockchip_pin_ctrl rk3188_pin_ctrl = {
                .pin_banks              = rk3188_pin_banks,
                .nr_banks               = ARRAY_SIZE(rk3188_pin_banks),
                .label                  = "RK3188-GPIO",
+               .type                   = RK3188,
                .mux_offset             = 0x68,
-               .pull_offset            = 0x164,
-               .pull_bank_stride       = 16,
+               .pull_calc_reg          = rk3188_calc_pull_reg_and_bit,
 };
 
 static const struct of_device_id rockchip_pinctrl_dt_match[] = {
index 92a9d6c8db0a3ad5d5ff14aeca0f4d5e12676889..47ec2e8741e4221ba3dc03a4d1ce6cdba5184bb2 100644 (file)
@@ -1148,7 +1148,7 @@ static struct platform_driver samsung_pinctrl_driver = {
        .driver = {
                .name   = "samsung-pinctrl",
                .owner  = THIS_MODULE,
-               .of_match_table = of_match_ptr(samsung_pinctrl_dt_match),
+               .of_match_table = samsung_pinctrl_dt_match,
        },
 };
 
diff --git a/drivers/pinctrl/pinctrl-tb10x.c b/drivers/pinctrl/pinctrl-tb10x.c
new file mode 100644 (file)
index 0000000..c5e0f69
--- /dev/null
@@ -0,0 +1,875 @@
+/*
+ * Abilis Systems TB10x pin control driver
+ *
+ * Copyright (C) Abilis Systems 2012
+ *
+ * Author: Christian Ruppert <christian.ruppert@abilis.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <linux/stringify.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+
+#include "pinctrl-utils.h"
+
+#define TB10X_PORT1 (0)
+#define TB10X_PORT2 (16)
+#define TB10X_PORT3 (32)
+#define TB10X_PORT4 (48)
+#define TB10X_PORT5 (128)
+#define TB10X_PORT6 (64)
+#define TB10X_PORT7 (80)
+#define TB10X_PORT8 (96)
+#define TB10X_PORT9 (112)
+#define TB10X_GPIOS (256)
+
+#define PCFG_PORT_BITWIDTH (2)
+#define PCFG_PORT_MASK(PORT) \
+       (((1 << PCFG_PORT_BITWIDTH) - 1) << (PCFG_PORT_BITWIDTH * (PORT)))
+
+static const struct pinctrl_pin_desc tb10x_pins[] = {
+       /* Port 1 */
+       PINCTRL_PIN(TB10X_PORT1 +  0, "MICLK_S0"),
+       PINCTRL_PIN(TB10X_PORT1 +  1, "MISTRT_S0"),
+       PINCTRL_PIN(TB10X_PORT1 +  2, "MIVAL_S0"),
+       PINCTRL_PIN(TB10X_PORT1 +  3, "MDI_S0"),
+       PINCTRL_PIN(TB10X_PORT1 +  4, "GPIOA0"),
+       PINCTRL_PIN(TB10X_PORT1 +  5, "GPIOA1"),
+       PINCTRL_PIN(TB10X_PORT1 +  6, "GPIOA2"),
+       PINCTRL_PIN(TB10X_PORT1 +  7, "MDI_S1"),
+       PINCTRL_PIN(TB10X_PORT1 +  8, "MIVAL_S1"),
+       PINCTRL_PIN(TB10X_PORT1 +  9, "MISTRT_S1"),
+       PINCTRL_PIN(TB10X_PORT1 + 10, "MICLK_S1"),
+       /* Port 2 */
+       PINCTRL_PIN(TB10X_PORT2 +  0, "MICLK_S2"),
+       PINCTRL_PIN(TB10X_PORT2 +  1, "MISTRT_S2"),
+       PINCTRL_PIN(TB10X_PORT2 +  2, "MIVAL_S2"),
+       PINCTRL_PIN(TB10X_PORT2 +  3, "MDI_S2"),
+       PINCTRL_PIN(TB10X_PORT2 +  4, "GPIOC0"),
+       PINCTRL_PIN(TB10X_PORT2 +  5, "GPIOC1"),
+       PINCTRL_PIN(TB10X_PORT2 +  6, "GPIOC2"),
+       PINCTRL_PIN(TB10X_PORT2 +  7, "MDI_S3"),
+       PINCTRL_PIN(TB10X_PORT2 +  8, "MIVAL_S3"),
+       PINCTRL_PIN(TB10X_PORT2 +  9, "MISTRT_S3"),
+       PINCTRL_PIN(TB10X_PORT2 + 10, "MICLK_S3"),
+       /* Port 3 */
+       PINCTRL_PIN(TB10X_PORT3 +  0, "MICLK_S4"),
+       PINCTRL_PIN(TB10X_PORT3 +  1, "MISTRT_S4"),
+       PINCTRL_PIN(TB10X_PORT3 +  2, "MIVAL_S4"),
+       PINCTRL_PIN(TB10X_PORT3 +  3, "MDI_S4"),
+       PINCTRL_PIN(TB10X_PORT3 +  4, "GPIOE0"),
+       PINCTRL_PIN(TB10X_PORT3 +  5, "GPIOE1"),
+       PINCTRL_PIN(TB10X_PORT3 +  6, "GPIOE2"),
+       PINCTRL_PIN(TB10X_PORT3 +  7, "MDI_S5"),
+       PINCTRL_PIN(TB10X_PORT3 +  8, "MIVAL_S5"),
+       PINCTRL_PIN(TB10X_PORT3 +  9, "MISTRT_S5"),
+       PINCTRL_PIN(TB10X_PORT3 + 10, "MICLK_S5"),
+       /* Port 4 */
+       PINCTRL_PIN(TB10X_PORT4 +  0, "MICLK_S6"),
+       PINCTRL_PIN(TB10X_PORT4 +  1, "MISTRT_S6"),
+       PINCTRL_PIN(TB10X_PORT4 +  2, "MIVAL_S6"),
+       PINCTRL_PIN(TB10X_PORT4 +  3, "MDI_S6"),
+       PINCTRL_PIN(TB10X_PORT4 +  4, "GPIOG0"),
+       PINCTRL_PIN(TB10X_PORT4 +  5, "GPIOG1"),
+       PINCTRL_PIN(TB10X_PORT4 +  6, "GPIOG2"),
+       PINCTRL_PIN(TB10X_PORT4 +  7, "MDI_S7"),
+       PINCTRL_PIN(TB10X_PORT4 +  8, "MIVAL_S7"),
+       PINCTRL_PIN(TB10X_PORT4 +  9, "MISTRT_S7"),
+       PINCTRL_PIN(TB10X_PORT4 + 10, "MICLK_S7"),
+       /* Port 5 */
+       PINCTRL_PIN(TB10X_PORT5 +  0, "PC_CE1N"),
+       PINCTRL_PIN(TB10X_PORT5 +  1, "PC_CE2N"),
+       PINCTRL_PIN(TB10X_PORT5 +  2, "PC_REGN"),
+       PINCTRL_PIN(TB10X_PORT5 +  3, "PC_INPACKN"),
+       PINCTRL_PIN(TB10X_PORT5 +  4, "PC_OEN"),
+       PINCTRL_PIN(TB10X_PORT5 +  5, "PC_WEN"),
+       PINCTRL_PIN(TB10X_PORT5 +  6, "PC_IORDN"),
+       PINCTRL_PIN(TB10X_PORT5 +  7, "PC_IOWRN"),
+       PINCTRL_PIN(TB10X_PORT5 +  8, "PC_RDYIRQN"),
+       PINCTRL_PIN(TB10X_PORT5 +  9, "PC_WAITN"),
+       PINCTRL_PIN(TB10X_PORT5 + 10, "PC_A0"),
+       PINCTRL_PIN(TB10X_PORT5 + 11, "PC_A1"),
+       PINCTRL_PIN(TB10X_PORT5 + 12, "PC_A2"),
+       PINCTRL_PIN(TB10X_PORT5 + 13, "PC_A3"),
+       PINCTRL_PIN(TB10X_PORT5 + 14, "PC_A4"),
+       PINCTRL_PIN(TB10X_PORT5 + 15, "PC_A5"),
+       PINCTRL_PIN(TB10X_PORT5 + 16, "PC_A6"),
+       PINCTRL_PIN(TB10X_PORT5 + 17, "PC_A7"),
+       PINCTRL_PIN(TB10X_PORT5 + 18, "PC_A8"),
+       PINCTRL_PIN(TB10X_PORT5 + 19, "PC_A9"),
+       PINCTRL_PIN(TB10X_PORT5 + 20, "PC_A10"),
+       PINCTRL_PIN(TB10X_PORT5 + 21, "PC_A11"),
+       PINCTRL_PIN(TB10X_PORT5 + 22, "PC_A12"),
+       PINCTRL_PIN(TB10X_PORT5 + 23, "PC_A13"),
+       PINCTRL_PIN(TB10X_PORT5 + 24, "PC_A14"),
+       PINCTRL_PIN(TB10X_PORT5 + 25, "PC_D0"),
+       PINCTRL_PIN(TB10X_PORT5 + 26, "PC_D1"),
+       PINCTRL_PIN(TB10X_PORT5 + 27, "PC_D2"),
+       PINCTRL_PIN(TB10X_PORT5 + 28, "PC_D3"),
+       PINCTRL_PIN(TB10X_PORT5 + 29, "PC_D4"),
+       PINCTRL_PIN(TB10X_PORT5 + 30, "PC_D5"),
+       PINCTRL_PIN(TB10X_PORT5 + 31, "PC_D6"),
+       PINCTRL_PIN(TB10X_PORT5 + 32, "PC_D7"),
+       PINCTRL_PIN(TB10X_PORT5 + 33, "PC_MOSTRT"),
+       PINCTRL_PIN(TB10X_PORT5 + 34, "PC_MOVAL"),
+       PINCTRL_PIN(TB10X_PORT5 + 35, "PC_MDO0"),
+       PINCTRL_PIN(TB10X_PORT5 + 36, "PC_MDO1"),
+       PINCTRL_PIN(TB10X_PORT5 + 37, "PC_MDO2"),
+       PINCTRL_PIN(TB10X_PORT5 + 38, "PC_MDO3"),
+       PINCTRL_PIN(TB10X_PORT5 + 39, "PC_MDO4"),
+       PINCTRL_PIN(TB10X_PORT5 + 40, "PC_MDO5"),
+       PINCTRL_PIN(TB10X_PORT5 + 41, "PC_MDO6"),
+       PINCTRL_PIN(TB10X_PORT5 + 42, "PC_MDO7"),
+       PINCTRL_PIN(TB10X_PORT5 + 43, "PC_MISTRT"),
+       PINCTRL_PIN(TB10X_PORT5 + 44, "PC_MIVAL"),
+       PINCTRL_PIN(TB10X_PORT5 + 45, "PC_MDI0"),
+       PINCTRL_PIN(TB10X_PORT5 + 46, "PC_MDI1"),
+       PINCTRL_PIN(TB10X_PORT5 + 47, "PC_MDI2"),
+       PINCTRL_PIN(TB10X_PORT5 + 48, "PC_MDI3"),
+       PINCTRL_PIN(TB10X_PORT5 + 49, "PC_MDI4"),
+       PINCTRL_PIN(TB10X_PORT5 + 50, "PC_MDI5"),
+       PINCTRL_PIN(TB10X_PORT5 + 51, "PC_MDI6"),
+       PINCTRL_PIN(TB10X_PORT5 + 52, "PC_MDI7"),
+       PINCTRL_PIN(TB10X_PORT5 + 53, "PC_MICLK"),
+       /* Port 6 */
+       PINCTRL_PIN(TB10X_PORT6 + 0, "T_MOSTRT_S0"),
+       PINCTRL_PIN(TB10X_PORT6 + 1, "T_MOVAL_S0"),
+       PINCTRL_PIN(TB10X_PORT6 + 2, "T_MDO_S0"),
+       PINCTRL_PIN(TB10X_PORT6 + 3, "T_MOSTRT_S1"),
+       PINCTRL_PIN(TB10X_PORT6 + 4, "T_MOVAL_S1"),
+       PINCTRL_PIN(TB10X_PORT6 + 5, "T_MDO_S1"),
+       PINCTRL_PIN(TB10X_PORT6 + 6, "T_MOSTRT_S2"),
+       PINCTRL_PIN(TB10X_PORT6 + 7, "T_MOVAL_S2"),
+       PINCTRL_PIN(TB10X_PORT6 + 8, "T_MDO_S2"),
+       PINCTRL_PIN(TB10X_PORT6 + 9, "T_MOSTRT_S3"),
+       /* Port 7 */
+       PINCTRL_PIN(TB10X_PORT7 + 0, "UART0_TXD"),
+       PINCTRL_PIN(TB10X_PORT7 + 1, "UART0_RXD"),
+       PINCTRL_PIN(TB10X_PORT7 + 2, "UART0_CTS"),
+       PINCTRL_PIN(TB10X_PORT7 + 3, "UART0_RTS"),
+       PINCTRL_PIN(TB10X_PORT7 + 4, "UART1_TXD"),
+       PINCTRL_PIN(TB10X_PORT7 + 5, "UART1_RXD"),
+       PINCTRL_PIN(TB10X_PORT7 + 6, "UART1_CTS"),
+       PINCTRL_PIN(TB10X_PORT7 + 7, "UART1_RTS"),
+       /* Port 8 */
+       PINCTRL_PIN(TB10X_PORT8 + 0, "SPI3_CLK"),
+       PINCTRL_PIN(TB10X_PORT8 + 1, "SPI3_MISO"),
+       PINCTRL_PIN(TB10X_PORT8 + 2, "SPI3_MOSI"),
+       PINCTRL_PIN(TB10X_PORT8 + 3, "SPI3_SSN"),
+       /* Port 9 */
+       PINCTRL_PIN(TB10X_PORT9 + 0, "SPI1_CLK"),
+       PINCTRL_PIN(TB10X_PORT9 + 1, "SPI1_MISO"),
+       PINCTRL_PIN(TB10X_PORT9 + 2, "SPI1_MOSI"),
+       PINCTRL_PIN(TB10X_PORT9 + 3, "SPI1_SSN0"),
+       PINCTRL_PIN(TB10X_PORT9 + 4, "SPI1_SSN1"),
+       /* Unmuxed GPIOs */
+       PINCTRL_PIN(TB10X_GPIOS +  0, "GPIOB0"),
+       PINCTRL_PIN(TB10X_GPIOS +  1, "GPIOB1"),
+
+       PINCTRL_PIN(TB10X_GPIOS +  2, "GPIOD0"),
+       PINCTRL_PIN(TB10X_GPIOS +  3, "GPIOD1"),
+
+       PINCTRL_PIN(TB10X_GPIOS +  4, "GPIOF0"),
+       PINCTRL_PIN(TB10X_GPIOS +  5, "GPIOF1"),
+
+       PINCTRL_PIN(TB10X_GPIOS +  6, "GPIOH0"),
+       PINCTRL_PIN(TB10X_GPIOS +  7, "GPIOH1"),
+
+       PINCTRL_PIN(TB10X_GPIOS +  8, "GPIOI0"),
+       PINCTRL_PIN(TB10X_GPIOS +  9, "GPIOI1"),
+       PINCTRL_PIN(TB10X_GPIOS + 10, "GPIOI2"),
+       PINCTRL_PIN(TB10X_GPIOS + 11, "GPIOI3"),
+       PINCTRL_PIN(TB10X_GPIOS + 12, "GPIOI4"),
+       PINCTRL_PIN(TB10X_GPIOS + 13, "GPIOI5"),
+       PINCTRL_PIN(TB10X_GPIOS + 14, "GPIOI6"),
+       PINCTRL_PIN(TB10X_GPIOS + 15, "GPIOI7"),
+       PINCTRL_PIN(TB10X_GPIOS + 16, "GPIOI8"),
+       PINCTRL_PIN(TB10X_GPIOS + 17, "GPIOI9"),
+       PINCTRL_PIN(TB10X_GPIOS + 18, "GPIOI10"),
+       PINCTRL_PIN(TB10X_GPIOS + 19, "GPIOI11"),
+
+       PINCTRL_PIN(TB10X_GPIOS + 20, "GPION0"),
+       PINCTRL_PIN(TB10X_GPIOS + 21, "GPION1"),
+       PINCTRL_PIN(TB10X_GPIOS + 22, "GPION2"),
+       PINCTRL_PIN(TB10X_GPIOS + 23, "GPION3"),
+#define MAX_PIN (TB10X_GPIOS + 24)
+       PINCTRL_PIN(MAX_PIN,  "GPION4"),
+};
+
+
+/* Port 1 */
+static const unsigned mis0_pins[]  = { TB10X_PORT1 + 0, TB10X_PORT1 + 1,
+                                       TB10X_PORT1 + 2, TB10X_PORT1 + 3};
+static const unsigned gpioa_pins[] = { TB10X_PORT1 + 4, TB10X_PORT1 + 5,
+                                       TB10X_PORT1 + 6};
+static const unsigned mis1_pins[]  = { TB10X_PORT1 + 7, TB10X_PORT1 + 8,
+                                       TB10X_PORT1 + 9, TB10X_PORT1 + 10};
+static const unsigned mip1_pins[]  = { TB10X_PORT1 + 0, TB10X_PORT1 + 1,
+                                       TB10X_PORT1 + 2, TB10X_PORT1 + 3,
+                                       TB10X_PORT1 + 4, TB10X_PORT1 + 5,
+                                       TB10X_PORT1 + 6, TB10X_PORT1 + 7,
+                                       TB10X_PORT1 + 8, TB10X_PORT1 + 9,
+                                       TB10X_PORT1 + 10};
+
+/* Port 2 */
+static const unsigned mis2_pins[]  = { TB10X_PORT2 + 0, TB10X_PORT2 + 1,
+                                       TB10X_PORT2 + 2, TB10X_PORT2 + 3};
+static const unsigned gpioc_pins[] = { TB10X_PORT2 + 4, TB10X_PORT2 + 5,
+                                       TB10X_PORT2 + 6};
+static const unsigned mis3_pins[]  = { TB10X_PORT2 + 7, TB10X_PORT2 + 8,
+                                       TB10X_PORT2 + 9, TB10X_PORT2 + 10};
+static const unsigned mip3_pins[]  = { TB10X_PORT2 + 0, TB10X_PORT2 + 1,
+                                       TB10X_PORT2 + 2, TB10X_PORT2 + 3,
+                                       TB10X_PORT2 + 4, TB10X_PORT2 + 5,
+                                       TB10X_PORT2 + 6, TB10X_PORT2 + 7,
+                                       TB10X_PORT2 + 8, TB10X_PORT2 + 9,
+                                       TB10X_PORT2 + 10};
+
+/* Port 3 */
+static const unsigned mis4_pins[]  = { TB10X_PORT3 + 0, TB10X_PORT3 + 1,
+                                       TB10X_PORT3 + 2, TB10X_PORT3 + 3};
+static const unsigned gpioe_pins[] = { TB10X_PORT3 + 4, TB10X_PORT3 + 5,
+                                       TB10X_PORT3 + 6};
+static const unsigned mis5_pins[]  = { TB10X_PORT3 + 7, TB10X_PORT3 + 8,
+                                       TB10X_PORT3 + 9, TB10X_PORT3 + 10};
+static const unsigned mip5_pins[]  = { TB10X_PORT3 + 0, TB10X_PORT3 + 1,
+                                       TB10X_PORT3 + 2, TB10X_PORT3 + 3,
+                                       TB10X_PORT3 + 4, TB10X_PORT3 + 5,
+                                       TB10X_PORT3 + 6, TB10X_PORT3 + 7,
+                                       TB10X_PORT3 + 8, TB10X_PORT3 + 9,
+                                       TB10X_PORT3 + 10};
+
+/* Port 4 */
+static const unsigned mis6_pins[]  = { TB10X_PORT4 + 0, TB10X_PORT4 + 1,
+                                       TB10X_PORT4 + 2, TB10X_PORT4 + 3};
+static const unsigned gpiog_pins[] = { TB10X_PORT4 + 4, TB10X_PORT4 + 5,
+                                       TB10X_PORT4 + 6};
+static const unsigned mis7_pins[]  = { TB10X_PORT4 + 7, TB10X_PORT4 + 8,
+                                       TB10X_PORT4 + 9, TB10X_PORT4 + 10};
+static const unsigned mip7_pins[]  = { TB10X_PORT4 + 0, TB10X_PORT4 + 1,
+                                       TB10X_PORT4 + 2, TB10X_PORT4 + 3,
+                                       TB10X_PORT4 + 4, TB10X_PORT4 + 5,
+                                       TB10X_PORT4 + 6, TB10X_PORT4 + 7,
+                                       TB10X_PORT4 + 8, TB10X_PORT4 + 9,
+                                       TB10X_PORT4 + 10};
+
+/* Port 6 */
+static const unsigned mop_pins[] = {   TB10X_PORT6 + 0, TB10X_PORT6 + 1,
+                                       TB10X_PORT6 + 2, TB10X_PORT6 + 3,
+                                       TB10X_PORT6 + 4, TB10X_PORT6 + 5,
+                                       TB10X_PORT6 + 6, TB10X_PORT6 + 7,
+                                       TB10X_PORT6 + 8, TB10X_PORT6 + 9};
+static const unsigned mos0_pins[] = {  TB10X_PORT6 + 0, TB10X_PORT6 + 1,
+                                       TB10X_PORT6 + 2};
+static const unsigned mos1_pins[] = {  TB10X_PORT6 + 3, TB10X_PORT6 + 4,
+                                       TB10X_PORT6 + 5};
+static const unsigned mos2_pins[] = {  TB10X_PORT6 + 6, TB10X_PORT6 + 7,
+                                       TB10X_PORT6 + 8};
+static const unsigned mos3_pins[] = {  TB10X_PORT6 + 9};
+
+/* Port 7 */
+static const unsigned uart0_pins[] = { TB10X_PORT7 + 0, TB10X_PORT7 + 1,
+                                       TB10X_PORT7 + 2, TB10X_PORT7 + 3};
+static const unsigned uart1_pins[] = { TB10X_PORT7 + 4, TB10X_PORT7 + 5,
+                                       TB10X_PORT7 + 6, TB10X_PORT7 + 7};
+static const unsigned gpiol_pins[] = { TB10X_PORT7 + 0, TB10X_PORT7 + 1,
+                                       TB10X_PORT7 + 2, TB10X_PORT7 + 3};
+static const unsigned gpiom_pins[] = { TB10X_PORT7 + 4, TB10X_PORT7 + 5,
+                                       TB10X_PORT7 + 6, TB10X_PORT7 + 7};
+
+/* Port 8 */
+static const unsigned spi3_pins[] = {  TB10X_PORT8 + 0, TB10X_PORT8 + 1,
+                                       TB10X_PORT8 + 2, TB10X_PORT8 + 3};
+static const unsigned jtag_pins[] = {  TB10X_PORT8 + 0, TB10X_PORT8 + 1,
+                                       TB10X_PORT8 + 2, TB10X_PORT8 + 3};
+
+/* Port 9 */
+static const unsigned spi1_pins[] = {  TB10X_PORT9 + 0, TB10X_PORT9 + 1,
+                                       TB10X_PORT9 + 2, TB10X_PORT9 + 3,
+                                       TB10X_PORT9 + 4};
+static const unsigned gpion_pins[] = { TB10X_PORT9 + 0, TB10X_PORT9 + 1,
+                                       TB10X_PORT9 + 2, TB10X_PORT9 + 3,
+                                       TB10X_PORT9 + 4};
+
+/* Port 5 */
+static const unsigned gpioj_pins[] = { TB10X_PORT5 + 0, TB10X_PORT5 + 1,
+                                       TB10X_PORT5 + 2, TB10X_PORT5 + 3,
+                                       TB10X_PORT5 + 4, TB10X_PORT5 + 5,
+                                       TB10X_PORT5 + 6, TB10X_PORT5 + 7,
+                                       TB10X_PORT5 + 8, TB10X_PORT5 + 9,
+                                       TB10X_PORT5 + 10, TB10X_PORT5 + 11,
+                                       TB10X_PORT5 + 12, TB10X_PORT5 + 13,
+                                       TB10X_PORT5 + 14, TB10X_PORT5 + 15,
+                                       TB10X_PORT5 + 16, TB10X_PORT5 + 17,
+                                       TB10X_PORT5 + 18, TB10X_PORT5 + 19,
+                                       TB10X_PORT5 + 20, TB10X_PORT5 + 21,
+                                       TB10X_PORT5 + 22, TB10X_PORT5 + 23,
+                                       TB10X_PORT5 + 24, TB10X_PORT5 + 25,
+                                       TB10X_PORT5 + 26, TB10X_PORT5 + 27,
+                                       TB10X_PORT5 + 28, TB10X_PORT5 + 29,
+                                       TB10X_PORT5 + 30, TB10X_PORT5 + 31};
+static const unsigned gpiok_pins[] = { TB10X_PORT5 + 32, TB10X_PORT5 + 33,
+                                       TB10X_PORT5 + 34, TB10X_PORT5 + 35,
+                                       TB10X_PORT5 + 36, TB10X_PORT5 + 37,
+                                       TB10X_PORT5 + 38, TB10X_PORT5 + 39,
+                                       TB10X_PORT5 + 40, TB10X_PORT5 + 41,
+                                       TB10X_PORT5 + 42, TB10X_PORT5 + 43,
+                                       TB10X_PORT5 + 44, TB10X_PORT5 + 45,
+                                       TB10X_PORT5 + 46, TB10X_PORT5 + 47,
+                                       TB10X_PORT5 + 48, TB10X_PORT5 + 49,
+                                       TB10X_PORT5 + 50, TB10X_PORT5 + 51,
+                                       TB10X_PORT5 + 52, TB10X_PORT5 + 53};
+static const unsigned ciplus_pins[] = {        TB10X_PORT5 + 0, TB10X_PORT5 + 1,
+                                       TB10X_PORT5 + 2, TB10X_PORT5 + 3,
+                                       TB10X_PORT5 + 4, TB10X_PORT5 + 5,
+                                       TB10X_PORT5 + 6, TB10X_PORT5 + 7,
+                                       TB10X_PORT5 + 8, TB10X_PORT5 + 9,
+                                       TB10X_PORT5 + 10, TB10X_PORT5 + 11,
+                                       TB10X_PORT5 + 12, TB10X_PORT5 + 13,
+                                       TB10X_PORT5 + 14, TB10X_PORT5 + 15,
+                                       TB10X_PORT5 + 16, TB10X_PORT5 + 17,
+                                       TB10X_PORT5 + 18, TB10X_PORT5 + 19,
+                                       TB10X_PORT5 + 20, TB10X_PORT5 + 21,
+                                       TB10X_PORT5 + 22, TB10X_PORT5 + 23,
+                                       TB10X_PORT5 + 24, TB10X_PORT5 + 25,
+                                       TB10X_PORT5 + 26, TB10X_PORT5 + 27,
+                                       TB10X_PORT5 + 28, TB10X_PORT5 + 29,
+                                       TB10X_PORT5 + 30, TB10X_PORT5 + 31,
+                                       TB10X_PORT5 + 32, TB10X_PORT5 + 33,
+                                       TB10X_PORT5 + 34, TB10X_PORT5 + 35,
+                                       TB10X_PORT5 + 36, TB10X_PORT5 + 37,
+                                       TB10X_PORT5 + 38, TB10X_PORT5 + 39,
+                                       TB10X_PORT5 + 40, TB10X_PORT5 + 41,
+                                       TB10X_PORT5 + 42, TB10X_PORT5 + 43,
+                                       TB10X_PORT5 + 44, TB10X_PORT5 + 45,
+                                       TB10X_PORT5 + 46, TB10X_PORT5 + 47,
+                                       TB10X_PORT5 + 48, TB10X_PORT5 + 49,
+                                       TB10X_PORT5 + 50, TB10X_PORT5 + 51,
+                                       TB10X_PORT5 + 52, TB10X_PORT5 + 53};
+static const unsigned mcard_pins[] = { TB10X_PORT5 + 3, TB10X_PORT5 + 10,
+                                       TB10X_PORT5 + 11, TB10X_PORT5 + 12,
+                                       TB10X_PORT5 + 22, TB10X_PORT5 + 23,
+                                       TB10X_PORT5 + 33, TB10X_PORT5 + 35,
+                                       TB10X_PORT5 + 36, TB10X_PORT5 + 37,
+                                       TB10X_PORT5 + 38, TB10X_PORT5 + 39,
+                                       TB10X_PORT5 + 40, TB10X_PORT5 + 41,
+                                       TB10X_PORT5 + 42, TB10X_PORT5 + 43,
+                                       TB10X_PORT5 + 45, TB10X_PORT5 + 46,
+                                       TB10X_PORT5 + 47, TB10X_PORT5 + 48,
+                                       TB10X_PORT5 + 49, TB10X_PORT5 + 50,
+                                       TB10X_PORT5 + 51, TB10X_PORT5 + 52,
+                                       TB10X_PORT5 + 53};
+static const unsigned stc0_pins[] = {  TB10X_PORT5 + 34, TB10X_PORT5 + 35,
+                                       TB10X_PORT5 + 36, TB10X_PORT5 + 37,
+                                       TB10X_PORT5 + 38, TB10X_PORT5 + 39,
+                                       TB10X_PORT5 + 40};
+static const unsigned stc1_pins[] = {  TB10X_PORT5 + 25, TB10X_PORT5 + 26,
+                                       TB10X_PORT5 + 27, TB10X_PORT5 + 28,
+                                       TB10X_PORT5 + 29, TB10X_PORT5 + 30,
+                                       TB10X_PORT5 + 44};
+
+/* Unmuxed GPIOs */
+static const unsigned gpiob_pins[] = { TB10X_GPIOS + 0, TB10X_GPIOS + 1};
+static const unsigned gpiod_pins[] = { TB10X_GPIOS + 2, TB10X_GPIOS + 3};
+static const unsigned gpiof_pins[] = { TB10X_GPIOS + 4, TB10X_GPIOS + 5};
+static const unsigned gpioh_pins[] = { TB10X_GPIOS + 6, TB10X_GPIOS + 7};
+static const unsigned gpioi_pins[] = { TB10X_GPIOS + 8, TB10X_GPIOS + 9,
+                                       TB10X_GPIOS + 10, TB10X_GPIOS + 11,
+                                       TB10X_GPIOS + 12, TB10X_GPIOS + 13,
+                                       TB10X_GPIOS + 14, TB10X_GPIOS + 15,
+                                       TB10X_GPIOS + 16, TB10X_GPIOS + 17,
+                                       TB10X_GPIOS + 18, TB10X_GPIOS + 19};
+
+struct tb10x_pinfuncgrp {
+       const char *name;
+       const unsigned int *pins;
+       const unsigned int pincnt;
+       const int port;
+       const unsigned int mode;
+       const int isgpio;
+};
+#define DEFPINFUNCGRP(NAME, PORT, MODE, ISGPIO) { \
+               .name = __stringify(NAME), \
+               .pins = NAME##_pins, .pincnt = ARRAY_SIZE(NAME##_pins), \
+               .port = (PORT), .mode = (MODE), \
+               .isgpio = (ISGPIO), \
+       }
+static const struct tb10x_pinfuncgrp tb10x_pingroups[] = {
+       DEFPINFUNCGRP(mis0,   0, 0, 0),
+       DEFPINFUNCGRP(gpioa,  0, 0, 1),
+       DEFPINFUNCGRP(mis1,   0, 0, 0),
+       DEFPINFUNCGRP(mip1,   0, 1, 0),
+       DEFPINFUNCGRP(mis2,   1, 0, 0),
+       DEFPINFUNCGRP(gpioc,  1, 0, 1),
+       DEFPINFUNCGRP(mis3,   1, 0, 0),
+       DEFPINFUNCGRP(mip3,   1, 1, 0),
+       DEFPINFUNCGRP(mis4,   2, 0, 0),
+       DEFPINFUNCGRP(gpioe,  2, 0, 1),
+       DEFPINFUNCGRP(mis5,   2, 0, 0),
+       DEFPINFUNCGRP(mip5,   2, 1, 0),
+       DEFPINFUNCGRP(mis6,   3, 0, 0),
+       DEFPINFUNCGRP(gpiog,  3, 0, 1),
+       DEFPINFUNCGRP(mis7,   3, 0, 0),
+       DEFPINFUNCGRP(mip7,   3, 1, 0),
+       DEFPINFUNCGRP(gpioj,  4, 0, 1),
+       DEFPINFUNCGRP(gpiok,  4, 0, 1),
+       DEFPINFUNCGRP(ciplus, 4, 1, 0),
+       DEFPINFUNCGRP(mcard,  4, 2, 0),
+       DEFPINFUNCGRP(stc0,   4, 3, 0),
+       DEFPINFUNCGRP(stc1,   4, 3, 0),
+       DEFPINFUNCGRP(mop,    5, 0, 0),
+       DEFPINFUNCGRP(mos0,   5, 1, 0),
+       DEFPINFUNCGRP(mos1,   5, 1, 0),
+       DEFPINFUNCGRP(mos2,   5, 1, 0),
+       DEFPINFUNCGRP(mos3,   5, 1, 0),
+       DEFPINFUNCGRP(uart0,  6, 0, 0),
+       DEFPINFUNCGRP(uart1,  6, 0, 0),
+       DEFPINFUNCGRP(gpiol,  6, 1, 1),
+       DEFPINFUNCGRP(gpiom,  6, 1, 1),
+       DEFPINFUNCGRP(spi3,   7, 0, 0),
+       DEFPINFUNCGRP(jtag,   7, 1, 0),
+       DEFPINFUNCGRP(spi1,   8, 0, 0),
+       DEFPINFUNCGRP(gpion,  8, 1, 1),
+       DEFPINFUNCGRP(gpiob, -1, 0, 1),
+       DEFPINFUNCGRP(gpiod, -1, 0, 1),
+       DEFPINFUNCGRP(gpiof, -1, 0, 1),
+       DEFPINFUNCGRP(gpioh, -1, 0, 1),
+       DEFPINFUNCGRP(gpioi, -1, 0, 1),
+};
+#undef DEFPINFUNCGRP
+
+struct tb10x_of_pinfunc {
+       const char *name;
+       const char *group;
+};
+
+#define TB10X_PORTS (9)
+
+/**
+ * struct tb10x_port - state of an I/O port
+ * @mode: Node this port is currently in.
+ * @count: Number of enabled functions which require this port to be
+ *         configured in @mode.
+ */
+struct tb10x_port {
+       unsigned int mode;
+       unsigned int count;
+};
+
+/**
+ * struct tb10x_pinctrl - TB10x pin controller internal state
+ * @pctl: pointer to the pinctrl_dev structure of this pin controller.
+ * @base: register set base address.
+ * @pingroups: pointer to an array of the pin groups this driver manages.
+ * @pinfuncgrpcnt: number of pingroups in @pingroups.
+ * @pinfuncs: pointer to an array of pin functions this driver manages.
+ * @pinfuncnt: number of pin functions in @pinfuncs.
+ * @mutex: mutex for exclusive access to a pin controller's state.
+ * @ports: current state of each port.
+ * @gpios: Indicates if a given pin is currently used as GPIO (1) or not (0).
+ */
+struct tb10x_pinctrl {
+       struct pinctrl_dev *pctl;
+       void *base;
+       const struct tb10x_pinfuncgrp *pingroups;
+       unsigned int pinfuncgrpcnt;
+       struct tb10x_of_pinfunc *pinfuncs;
+       unsigned int pinfuncnt;
+       struct mutex mutex;
+       struct tb10x_port ports[TB10X_PORTS];
+       DECLARE_BITMAP(gpios, MAX_PIN + 1);
+};
+
+static inline void tb10x_pinctrl_set_config(struct tb10x_pinctrl *state,
+                               unsigned int port, unsigned int mode)
+{
+       u32 pcfg;
+
+       if (state->ports[port].count)
+               return;
+
+       state->ports[port].mode = mode;
+
+       pcfg = ioread32(state->base) & ~(PCFG_PORT_MASK(port));
+       pcfg |= (mode << (PCFG_PORT_BITWIDTH * port)) & PCFG_PORT_MASK(port);
+       iowrite32(pcfg, state->base);
+}
+
+static inline unsigned int tb10x_pinctrl_get_config(
+                               struct tb10x_pinctrl *state,
+                               unsigned int port)
+{
+       return (ioread32(state->base) & PCFG_PORT_MASK(port))
+               >> (PCFG_PORT_BITWIDTH * port);
+}
+
+static int tb10x_get_groups_count(struct pinctrl_dev *pctl)
+{
+       struct tb10x_pinctrl *state = pinctrl_dev_get_drvdata(pctl);
+       return state->pinfuncgrpcnt;
+}
+
+static const char *tb10x_get_group_name(struct pinctrl_dev *pctl, unsigned n)
+{
+       struct tb10x_pinctrl *state = pinctrl_dev_get_drvdata(pctl);
+       return state->pingroups[n].name;
+}
+
+static int tb10x_get_group_pins(struct pinctrl_dev *pctl, unsigned n,
+                               unsigned const **pins,
+                               unsigned * const num_pins)
+{
+       struct tb10x_pinctrl *state = pinctrl_dev_get_drvdata(pctl);
+
+       *pins = state->pingroups[n].pins;
+       *num_pins = state->pingroups[n].pincnt;
+
+       return 0;
+}
+
+static int tb10x_dt_node_to_map(struct pinctrl_dev *pctl,
+                               struct device_node *np_config,
+                               struct pinctrl_map **map, unsigned *num_maps)
+{
+       const char *string;
+       unsigned reserved_maps = 0;
+       int ret = 0;
+
+       if (of_property_read_string(np_config, "abilis,function", &string)) {
+               pr_err("%s: No abilis,function property in device tree.\n",
+                       np_config->full_name);
+               return -EINVAL;
+       }
+
+       *map = NULL;
+       *num_maps = 0;
+
+       ret = pinctrl_utils_reserve_map(pctl, map, &reserved_maps,
+                                       num_maps, 1);
+       if (ret)
+               goto out;
+
+       ret = pinctrl_utils_add_map_mux(pctl, map, &reserved_maps,
+                                       num_maps, string, np_config->name);
+
+out:
+       return ret;
+}
+
+static struct pinctrl_ops tb10x_pinctrl_ops = {
+       .get_groups_count = tb10x_get_groups_count,
+       .get_group_name   = tb10x_get_group_name,
+       .get_group_pins   = tb10x_get_group_pins,
+       .dt_node_to_map   = tb10x_dt_node_to_map,
+       .dt_free_map      = pinctrl_utils_dt_free_map,
+};
+
+static int tb10x_get_functions_count(struct pinctrl_dev *pctl)
+{
+       struct tb10x_pinctrl *state = pinctrl_dev_get_drvdata(pctl);
+       return state->pinfuncnt;
+}
+
+static const char *tb10x_get_function_name(struct pinctrl_dev *pctl,
+                                       unsigned n)
+{
+       struct tb10x_pinctrl *state = pinctrl_dev_get_drvdata(pctl);
+       return state->pinfuncs[n].name;
+}
+
+static int tb10x_get_function_groups(struct pinctrl_dev *pctl,
+                               unsigned n, const char * const **groups,
+                               unsigned * const num_groups)
+{
+       struct tb10x_pinctrl *state = pinctrl_dev_get_drvdata(pctl);
+
+       *groups = &state->pinfuncs[n].group;
+       *num_groups = 1;
+
+       return 0;
+}
+
+static int tb10x_gpio_request_enable(struct pinctrl_dev *pctl,
+                                       struct pinctrl_gpio_range *range,
+                                       unsigned pin)
+{
+       struct tb10x_pinctrl *state = pinctrl_dev_get_drvdata(pctl);
+       int muxport = -1;
+       int muxmode = -1;
+       int i;
+
+       mutex_lock(&state->mutex);
+
+       /*
+        * Figure out to which port the requested GPIO belongs and how to
+        * configure that port.
+        * This loop also checks for pin conflicts between GPIOs and other
+        * functions.
+        */
+       for (i = 0; i < state->pinfuncgrpcnt; i++) {
+               const struct tb10x_pinfuncgrp *pfg = &state->pingroups[i];
+               unsigned int port = pfg->port;
+               unsigned int mode = pfg->mode;
+               int j;
+
+               /*
+                * Skip pin groups which are always mapped and don't need
+                * to be configured.
+                */
+               if (port < 0)
+                       continue;
+
+               for (j = 0; j < pfg->pincnt; j++) {
+                       if (pin == pfg->pins[j]) {
+                               if (pfg->isgpio) {
+                                       /*
+                                        * Remember the GPIO-only setting of
+                                        * the port this pin belongs to.
+                                        */
+                                       muxport = port;
+                                       muxmode = mode;
+                               } else if (state->ports[port].count
+                                       && (state->ports[port].mode == mode)) {
+                                       /*
+                                        * Error: The requested pin is already
+                                        * used for something else.
+                                        */
+                                       mutex_unlock(&state->mutex);
+                                       return -EBUSY;
+                               }
+                               break;
+                       }
+               }
+       }
+
+       /*
+        * If we haven't returned an error at this point, the GPIO pin is not
+        * used by another function and the GPIO request can be granted:
+        * Register pin as being used as GPIO so we don't allocate it to
+        * another function later.
+        */
+       set_bit(pin, state->gpios);
+
+       /*
+        * Potential conflicts between GPIOs and pin functions were caught
+        * earlier in this function and tb10x_pinctrl_set_config will do the
+        * Right Thing, either configure the port in GPIO only mode or leave
+        * another mode compatible with this GPIO request untouched.
+        */
+       if (muxport >= 0)
+               tb10x_pinctrl_set_config(state, muxport, muxmode);
+
+       mutex_unlock(&state->mutex);
+
+       return 0;
+}
+
+static void tb10x_gpio_disable_free(struct pinctrl_dev *pctl,
+                                       struct pinctrl_gpio_range *range,
+                                       unsigned pin)
+{
+       struct tb10x_pinctrl *state = pinctrl_dev_get_drvdata(pctl);
+
+       mutex_lock(&state->mutex);
+
+       clear_bit(pin, state->gpios);
+
+       mutex_unlock(&state->mutex);
+}
+
+static int tb10x_pctl_enable(struct pinctrl_dev *pctl,
+                       unsigned func_selector, unsigned group_selector)
+{
+       struct tb10x_pinctrl *state = pinctrl_dev_get_drvdata(pctl);
+       const struct tb10x_pinfuncgrp *grp = &state->pingroups[group_selector];
+       int i;
+
+       if (grp->port < 0)
+               return 0;
+
+       mutex_lock(&state->mutex);
+
+       /*
+        * Check if the requested function is compatible with previously
+        * requested functions.
+        */
+       if (state->ports[grp->port].count
+                       && (state->ports[grp->port].mode != grp->mode)) {
+               mutex_unlock(&state->mutex);
+               return -EBUSY;
+       }
+
+       /*
+        * Check if the requested function is compatible with previously
+        * requested GPIOs.
+        */
+       for (i = 0; i < grp->pincnt; i++)
+               if (test_bit(grp->pins[i], state->gpios)) {
+                       mutex_unlock(&state->mutex);
+                       return -EBUSY;
+               }
+
+       tb10x_pinctrl_set_config(state, grp->port, grp->mode);
+
+       state->ports[grp->port].count++;
+
+       mutex_unlock(&state->mutex);
+
+       return 0;
+}
+
+static void tb10x_pctl_disable(struct pinctrl_dev *pctl,
+                       unsigned func_selector, unsigned group_selector)
+{
+       struct tb10x_pinctrl *state = pinctrl_dev_get_drvdata(pctl);
+       const struct tb10x_pinfuncgrp *grp = &state->pingroups[group_selector];
+
+       if (grp->port < 0)
+               return;
+
+       mutex_lock(&state->mutex);
+
+       state->ports[grp->port].count--;
+
+       mutex_unlock(&state->mutex);
+}
+
+static struct pinmux_ops tb10x_pinmux_ops = {
+       .get_functions_count = tb10x_get_functions_count,
+       .get_function_name = tb10x_get_function_name,
+       .get_function_groups = tb10x_get_function_groups,
+       .gpio_request_enable = tb10x_gpio_request_enable,
+       .gpio_disable_free = tb10x_gpio_disable_free,
+       .enable = tb10x_pctl_enable,
+       .disable = tb10x_pctl_disable,
+};
+
+static struct pinctrl_desc tb10x_pindesc = {
+       .name = "TB10x",
+       .pins = tb10x_pins,
+       .npins = ARRAY_SIZE(tb10x_pins),
+       .owner = THIS_MODULE,
+       .pctlops = &tb10x_pinctrl_ops,
+       .pmxops  = &tb10x_pinmux_ops,
+};
+
+static int tb10x_pinctrl_probe(struct platform_device *pdev)
+{
+       int ret = -EINVAL;
+       struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       struct device *dev = &pdev->dev;
+       struct device_node *of_node = dev->of_node;
+       struct device_node *child;
+       struct tb10x_pinctrl *state;
+       int i;
+
+       if (!of_node) {
+               dev_err(dev, "No device tree node found.\n");
+               return -EINVAL;
+       }
+
+       if (!mem) {
+               dev_err(dev, "No memory resource defined.\n");
+               return -EINVAL;
+       }
+
+       state = devm_kzalloc(dev, sizeof(struct tb10x_pinctrl) +
+                                       of_get_child_count(of_node)
+                                       * sizeof(struct tb10x_of_pinfunc),
+                               GFP_KERNEL);
+       if (!state)
+               return -ENOMEM;
+
+       platform_set_drvdata(pdev, state);
+       state->pinfuncs = (struct tb10x_of_pinfunc *)(state + 1);
+       mutex_init(&state->mutex);
+
+       state->base = devm_ioremap_resource(dev, mem);
+       if (IS_ERR(state->base)) {
+               ret = PTR_ERR(state->base);
+               goto fail;
+       }
+
+       state->pingroups = tb10x_pingroups;
+       state->pinfuncgrpcnt = ARRAY_SIZE(tb10x_pingroups);
+
+       for (i = 0; i < TB10X_PORTS; i++)
+               state->ports[i].mode = tb10x_pinctrl_get_config(state, i);
+
+       for_each_child_of_node(of_node, child) {
+               const char *name;
+
+               if (!of_property_read_string(child, "abilis,function",
+                                               &name)) {
+                       state->pinfuncs[state->pinfuncnt].name = child->name;
+                       state->pinfuncs[state->pinfuncnt].group = name;
+                       state->pinfuncnt++;
+               }
+       }
+
+       state->pctl = pinctrl_register(&tb10x_pindesc, dev, state);
+       if (!state->pctl) {
+               dev_err(dev, "could not register TB10x pin driver\n");
+               ret = -EINVAL;
+               goto fail;
+       }
+
+       return 0;
+
+fail:
+       mutex_destroy(&state->mutex);
+       return ret;
+}
+
+static int tb10x_pinctrl_remove(struct platform_device *pdev)
+{
+       struct tb10x_pinctrl *state = platform_get_drvdata(pdev);
+
+       pinctrl_unregister(state->pctl);
+       mutex_destroy(&state->mutex);
+
+       return 0;
+}
+
+
+static const struct of_device_id tb10x_pinctrl_dt_ids[] = {
+       { .compatible = "abilis,tb10x-iomux" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, tb10x_pinctrl_dt_ids);
+
+static struct platform_driver tb10x_pinctrl_pdrv = {
+       .probe   = tb10x_pinctrl_probe,
+       .remove  = tb10x_pinctrl_remove,
+       .driver  = {
+               .name  = "tb10x_pinctrl",
+               .of_match_table = of_match_ptr(tb10x_pinctrl_dt_ids),
+               .owner = THIS_MODULE
+       }
+};
+
+module_platform_driver(tb10x_pinctrl_pdrv);
+
+MODULE_AUTHOR("Christian Ruppert <christian.ruppert@abilis.com>");
+MODULE_LICENSE("GPL");
index 68a970b1dbcfbf8d822503a0123d12a9b465304b..bddd913d28ba0734f5bb88bc98afd574889d1f3f 100644 (file)
@@ -316,7 +316,7 @@ static struct platform_driver vf610_pinctrl_driver = {
        .driver = {
                .name = "vf610-pinctrl",
                .owner = THIS_MODULE,
-               .of_match_table = of_match_ptr(vf610_pinctrl_of_match),
+               .of_match_table = vf610_pinctrl_of_match,
        },
        .probe = vf610_pinctrl_probe,
        .remove = imx_pinctrl_remove,
index 428d2a6857efd4123258dde53819c61ce914bdc8..20b1d0d671a3b29a6154e31d0d826b5a334789fe 100644 (file)
@@ -1288,6 +1288,22 @@ static struct sh_pfc_pin pinmux_pins[] = {
                                                     arg5##_MARK, arg6##_MARK, \
                                                     arg7##_MARK, arg8##_MARK, }
 
+/* - AUDIO macro -------------------------------------------------------------*/
+#define AUDIO_PFC_PIN(name, pin)       SH_PFC_PINS(name, pin)
+#define AUDIO_PFC_DAT(name, pin)       SH_PFC_MUX1(name, pin)
+
+/* - AUDIO clock -------------------------------------------------------------*/
+AUDIO_PFC_PIN(audio_clk_a,     RCAR_GP_PIN(2, 22));
+AUDIO_PFC_DAT(audio_clk_a,     AUDIO_CLKA);
+AUDIO_PFC_PIN(audio_clk_b,     RCAR_GP_PIN(2, 23));
+AUDIO_PFC_DAT(audio_clk_b,     AUDIO_CLKB);
+AUDIO_PFC_PIN(audio_clk_c,     RCAR_GP_PIN(2, 7));
+AUDIO_PFC_DAT(audio_clk_c,     AUDIO_CLKC);
+AUDIO_PFC_PIN(audio_clkout_a,  RCAR_GP_PIN(2, 16));
+AUDIO_PFC_DAT(audio_clkout_a,  AUDIO_CLKOUT_A);
+AUDIO_PFC_PIN(audio_clkout_b,  RCAR_GP_PIN(1, 16));
+AUDIO_PFC_DAT(audio_clkout_b,  AUDIO_CLKOUT_B);
+
 /* - Ether ------------------------------------------------------------------ */
 SH_PFC_PINS(ether_rmii,                RCAR_GP_PIN(4, 10),     RCAR_GP_PIN(4, 11),
                                RCAR_GP_PIN(4, 13),     RCAR_GP_PIN(4, 9),
@@ -1577,6 +1593,59 @@ SDHI_PFC_WPPN(sdhi2_wp_a,        SD2_WP_A);
 SDHI_PFC_PINS(sdhi2_wp_b,      RCAR_GP_PIN(3, 28));
 SDHI_PFC_WPPN(sdhi2_wp_b,      SD2_WP_B);
 
+/* - SSI macro -------------------------------------------------------------- */
+#define SSI_PFC_PINS(name, args...)            SH_PFC_PINS(name, args)
+#define SSI_PFC_CTRL(name, sck, ws)            SH_PFC_MUX2(name, sck, ws)
+#define SSI_PFC_DATA(name, d)                  SH_PFC_MUX1(name, d)
+
+/* - SSI 0/1/2 -------------------------------------------------------------- */
+SSI_PFC_PINS(ssi012_ctrl,      RCAR_GP_PIN(3, 6),      RCAR_GP_PIN(3, 7));
+SSI_PFC_CTRL(ssi012_ctrl,      SSI_SCK012,             SSI_WS012);
+SSI_PFC_PINS(ssi0_data,                RCAR_GP_PIN(3, 10));
+SSI_PFC_DATA(ssi0_data,                SSI_SDATA0);
+SSI_PFC_PINS(ssi1_a_ctrl,      RCAR_GP_PIN(2, 20),     RCAR_GP_PIN(2, 21));
+SSI_PFC_CTRL(ssi1_a_ctrl,      SSI_SCK1_A,             SSI_WS1_A);
+SSI_PFC_PINS(ssi1_b_ctrl,      PIN_NUMBER(3, 20),      RCAR_GP_PIN(1, 3));
+SSI_PFC_CTRL(ssi1_b_ctrl,      SSI_SCK1_B,             SSI_WS1_B);
+SSI_PFC_PINS(ssi1_data,                RCAR_GP_PIN(3, 9));
+SSI_PFC_DATA(ssi1_data,                SSI_SDATA1);
+SSI_PFC_PINS(ssi2_a_ctrl,      RCAR_GP_PIN(2, 26),     RCAR_GP_PIN(3, 4));
+SSI_PFC_CTRL(ssi2_a_ctrl,      SSI_SCK2_A,             SSI_WS2_A);
+SSI_PFC_PINS(ssi2_b_ctrl,      RCAR_GP_PIN(2, 6),      RCAR_GP_PIN(2, 17));
+SSI_PFC_CTRL(ssi2_b_ctrl,      SSI_SCK2_B,             SSI_WS2_B);
+SSI_PFC_PINS(ssi2_data,                RCAR_GP_PIN(3, 8));
+SSI_PFC_DATA(ssi2_data,                SSI_SDATA2);
+
+/* - SSI 3/4 ---------------------------------------------------------------- */
+SSI_PFC_PINS(ssi34_ctrl,       RCAR_GP_PIN(3, 2),      RCAR_GP_PIN(3, 3));
+SSI_PFC_CTRL(ssi34_ctrl,       SSI_SCK34,              SSI_WS34);
+SSI_PFC_PINS(ssi3_data,                RCAR_GP_PIN(3, 5));
+SSI_PFC_DATA(ssi3_data,                SSI_SDATA3);
+SSI_PFC_PINS(ssi4_ctrl,                RCAR_GP_PIN(1, 22),     RCAR_GP_PIN(1, 23));
+SSI_PFC_CTRL(ssi4_ctrl,                SSI_SCK4,               SSI_WS4);
+SSI_PFC_PINS(ssi4_data,                RCAR_GP_PIN(3, 4));
+SSI_PFC_DATA(ssi4_data,                SSI_SDATA4);
+
+/* - SSI 5 ------------------------------------------------------------------ */
+SSI_PFC_PINS(ssi5_ctrl,                RCAR_GP_PIN(2, 31),     RCAR_GP_PIN(3, 0));
+SSI_PFC_CTRL(ssi5_ctrl,                SSI_SCK5,               SSI_WS5);
+SSI_PFC_PINS(ssi5_data,                RCAR_GP_PIN(3, 1));
+SSI_PFC_DATA(ssi5_data,                SSI_SDATA5);
+
+/* - SSI 6 ------------------------------------------------------------------ */
+SSI_PFC_PINS(ssi6_ctrl,                RCAR_GP_PIN(2, 28),     RCAR_GP_PIN(2, 29));
+SSI_PFC_CTRL(ssi6_ctrl,                SSI_SCK6,               SSI_WS6);
+SSI_PFC_PINS(ssi6_data,                RCAR_GP_PIN(2, 30));
+SSI_PFC_DATA(ssi6_data,                SSI_SDATA6);
+
+/* - SSI 7/8  --------------------------------------------------------------- */
+SSI_PFC_PINS(ssi78_ctrl,       RCAR_GP_PIN(2, 24),     RCAR_GP_PIN(2, 25));
+SSI_PFC_CTRL(ssi78_ctrl,       SSI_SCK78,              SSI_WS78);
+SSI_PFC_PINS(ssi7_data,                RCAR_GP_PIN(2, 27));
+SSI_PFC_DATA(ssi7_data,                SSI_SDATA7);
+SSI_PFC_PINS(ssi8_data,                RCAR_GP_PIN(2, 26));
+SSI_PFC_DATA(ssi8_data,                SSI_SDATA8);
+
 /* - USB0 ------------------------------------------------------------------- */
 SH_PFC_PINS(usb0,              RCAR_GP_PIN(0, 1));
 SH_PFC_MUX1(usb0,              PENC0);
@@ -1624,6 +1693,11 @@ VIN_PFC_PINS(vin1_sync,          RCAR_GP_PIN(3, 21),     RCAR_GP_PIN(3, 22));
 VIN_PFC_SYNC(vin1_sync,                VI1_HSYNC,              VI1_VSYNC);
 
 static const struct sh_pfc_pin_group pinmux_groups[] = {
+       SH_PFC_PIN_GROUP(audio_clk_a),
+       SH_PFC_PIN_GROUP(audio_clk_b),
+       SH_PFC_PIN_GROUP(audio_clk_c),
+       SH_PFC_PIN_GROUP(audio_clkout_a),
+       SH_PFC_PIN_GROUP(audio_clkout_b),
        SH_PFC_PIN_GROUP(ether_rmii),
        SH_PFC_PIN_GROUP(ether_link),
        SH_PFC_PIN_GROUP(ether_magic),
@@ -1713,6 +1787,25 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
        SH_PFC_PIN_GROUP(sdhi2_data4_b),
        SH_PFC_PIN_GROUP(sdhi2_wp_a),
        SH_PFC_PIN_GROUP(sdhi2_wp_b),
+       SH_PFC_PIN_GROUP(ssi012_ctrl),
+       SH_PFC_PIN_GROUP(ssi0_data),
+       SH_PFC_PIN_GROUP(ssi1_a_ctrl),
+       SH_PFC_PIN_GROUP(ssi1_b_ctrl),
+       SH_PFC_PIN_GROUP(ssi1_data),
+       SH_PFC_PIN_GROUP(ssi2_a_ctrl),
+       SH_PFC_PIN_GROUP(ssi2_b_ctrl),
+       SH_PFC_PIN_GROUP(ssi2_data),
+       SH_PFC_PIN_GROUP(ssi34_ctrl),
+       SH_PFC_PIN_GROUP(ssi3_data),
+       SH_PFC_PIN_GROUP(ssi4_ctrl),
+       SH_PFC_PIN_GROUP(ssi4_data),
+       SH_PFC_PIN_GROUP(ssi5_ctrl),
+       SH_PFC_PIN_GROUP(ssi5_data),
+       SH_PFC_PIN_GROUP(ssi6_ctrl),
+       SH_PFC_PIN_GROUP(ssi6_data),
+       SH_PFC_PIN_GROUP(ssi78_ctrl),
+       SH_PFC_PIN_GROUP(ssi7_data),
+       SH_PFC_PIN_GROUP(ssi8_data),
        SH_PFC_PIN_GROUP(usb0),
        SH_PFC_PIN_GROUP(usb0_ovc),
        SH_PFC_PIN_GROUP(usb1),
@@ -1725,6 +1818,14 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
        SH_PFC_PIN_GROUP(vin1_sync),
 };
 
+static const char * const audio_clk_groups[] = {
+       "audio_clk_a",
+       "audio_clk_b",
+       "audio_clk_c",
+       "audio_clkout_a",
+       "audio_clkout_b",
+};
+
 static const char * const ether_groups[] = {
        "ether_rmii",
        "ether_link",
@@ -1875,6 +1976,28 @@ static const char * const sdhi2_groups[] = {
        "sdhi2_wp_b",
 };
 
+static const char * const ssi_groups[] = {
+       "ssi012_ctrl",
+       "ssi0_data",
+       "ssi1_a_ctrl",
+       "ssi1_b_ctrl",
+       "ssi1_data",
+       "ssi2_a_ctrl",
+       "ssi2_b_ctrl",
+       "ssi2_data",
+       "ssi34_ctrl",
+       "ssi3_data",
+       "ssi4_ctrl",
+       "ssi4_data",
+       "ssi5_ctrl",
+       "ssi5_data",
+       "ssi6_ctrl",
+       "ssi6_data",
+       "ssi78_ctrl",
+       "ssi7_data",
+       "ssi8_data",
+};
+
 static const char * const usb0_groups[] = {
        "usb0",
        "usb0_ovc",
@@ -1898,6 +2021,7 @@ static const char * const vin1_groups[] = {
 };
 
 static const struct sh_pfc_function pinmux_functions[] = {
+       SH_PFC_FUNCTION(audio_clk),
        SH_PFC_FUNCTION(ether),
        SH_PFC_FUNCTION(hscif0),
        SH_PFC_FUNCTION(hscif1),
@@ -1918,6 +2042,7 @@ static const struct sh_pfc_function pinmux_functions[] = {
        SH_PFC_FUNCTION(sdhi0),
        SH_PFC_FUNCTION(sdhi1),
        SH_PFC_FUNCTION(sdhi2),
+       SH_PFC_FUNCTION(ssi),
        SH_PFC_FUNCTION(usb0),
        SH_PFC_FUNCTION(usb1),
        SH_PFC_FUNCTION(vin0),
index 64fcc00693b519f7be27cafe48aeed5afe3a90d4..72786fc9395869d775ba1880095b62c819e1c5ee 100644 (file)
@@ -781,6 +781,8 @@ enum {
        ADICS_SAMP_MARK, DU2_CDE_MARK, QPOLB_MARK, SCIFA2_RXD_B_MARK,
        USB1_PWEN_MARK, AUDIO_CLKOUT_D_MARK, USB1_OVC_MARK,
        TCLK1_B_MARK,
+
+       I2C3_SCL_MARK, I2C3_SDA_MARK,
        PINMUX_MARK_END,
 };
 
@@ -1719,10 +1721,22 @@ static const u16 pinmux_data[] = {
        PINMUX_IPSR_DATA(IP16_6, AUDIO_CLKOUT_D),
        PINMUX_IPSR_DATA(IP16_7, USB1_OVC),
        PINMUX_IPSR_MODSEL_DATA(IP16_7, TCLK1_B, SEL_TMU1_1),
+
+       PINMUX_DATA(I2C3_SCL_MARK, FN_SEL_IICDVFS_1),
+       PINMUX_DATA(I2C3_SDA_MARK, FN_SEL_IICDVFS_1),
 };
 
+/* R8A7790 has 6 banks with 32 GPIOs in each = 192 GPIOs */
+#define ROW_GROUP_A(r) ('Z' - 'A' + 1 + (r))
+#define PIN_NUMBER(r, c) (((r) - 'A') * 31 + (c) + 200)
+#define PIN_A_NUMBER(r, c) PIN_NUMBER(ROW_GROUP_A(r), c)
+
 static struct sh_pfc_pin pinmux_pins[] = {
        PINMUX_GPIO_GP_ALL(),
+
+       /* Pins not associated with a GPIO port */
+       SH_PFC_PIN_NAMED(ROW_GROUP_A('J'), 15, AJ15),
+       SH_PFC_PIN_NAMED(ROW_GROUP_A('H'), 15, AH15),
 };
 
 /* - DU RGB ----------------------------------------------------------------- */
@@ -1990,6 +2004,72 @@ static const unsigned int hscif1_ctrl_b_pins[] = {
 static const unsigned int hscif1_ctrl_b_mux[] = {
        HRTS1_N_B_MARK, HCTS1_N_B_MARK,
 };
+/* - I2C1 ------------------------------------------------------------------- */
+static const unsigned int i2c1_pins[] = {
+       /* SCL, SDA */
+       RCAR_GP_PIN(1, 16), RCAR_GP_PIN(1, 17),
+};
+static const unsigned int i2c1_mux[] = {
+       I2C1_SCL_MARK, I2C1_SDA_MARK,
+};
+static const unsigned int i2c1_b_pins[] = {
+       /* SCL, SDA */
+       RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
+};
+static const unsigned int i2c1_b_mux[] = {
+       I2C1_SCL_B_MARK, I2C1_SDA_B_MARK,
+};
+static const unsigned int i2c1_c_pins[] = {
+       /* SCL, SDA */
+       RCAR_GP_PIN(4, 30), RCAR_GP_PIN(4, 27),
+};
+static const unsigned int i2c1_c_mux[] = {
+       I2C1_SCL_C_MARK, I2C1_SDA_C_MARK,
+};
+/* - I2C2 ------------------------------------------------------------------- */
+static const unsigned int i2c2_pins[] = {
+       /* SCL, SDA */
+       RCAR_GP_PIN(5, 5), RCAR_GP_PIN(5, 6),
+};
+static const unsigned int i2c2_mux[] = {
+       I2C2_SCL_MARK, I2C2_SDA_MARK,
+};
+static const unsigned int i2c2_b_pins[] = {
+       /* SCL, SDA */
+       RCAR_GP_PIN(4, 0), RCAR_GP_PIN(4, 1),
+};
+static const unsigned int i2c2_b_mux[] = {
+       I2C2_SCL_B_MARK, I2C2_SDA_B_MARK,
+};
+static const unsigned int i2c2_c_pins[] = {
+       /* SCL, SDA */
+       RCAR_GP_PIN(0, 6), RCAR_GP_PIN(0, 7),
+};
+static const unsigned int i2c2_c_mux[] = {
+       I2C2_SCL_C_MARK, I2C2_SDA_C_MARK,
+};
+static const unsigned int i2c2_d_pins[] = {
+       /* SCL, SDA */
+       RCAR_GP_PIN(3, 14), RCAR_GP_PIN(3, 15),
+};
+static const unsigned int i2c2_d_mux[] = {
+       I2C2_SCL_D_MARK, I2C2_SDA_D_MARK,
+};
+static const unsigned int i2c2_e_pins[] = {
+       /* SCL, SDA */
+       RCAR_GP_PIN(2, 18), RCAR_GP_PIN(2, 19),
+};
+static const unsigned int i2c2_e_mux[] = {
+       I2C2_SCL_E_MARK, I2C2_SDA_E_MARK,
+};
+/* - I2C3 ------------------------------------------------------------------- */
+static const unsigned int i2c3_pins[] = {
+       /* SCL, SDA */
+       PIN_A_NUMBER('J', 15), PIN_A_NUMBER('H', 15),
+};
+static const unsigned int i2c3_mux[] = {
+       I2C3_SCL_MARK, I2C3_SDA_MARK,
+};
 /* - INTC ------------------------------------------------------------------- */
 static const unsigned int intc_irq0_pins[] = {
        /* IRQ */
@@ -3047,6 +3127,15 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
        SH_PFC_PIN_GROUP(hscif1_data_b),
        SH_PFC_PIN_GROUP(hscif1_clk_b),
        SH_PFC_PIN_GROUP(hscif1_ctrl_b),
+       SH_PFC_PIN_GROUP(i2c1),
+       SH_PFC_PIN_GROUP(i2c1_b),
+       SH_PFC_PIN_GROUP(i2c1_c),
+       SH_PFC_PIN_GROUP(i2c2),
+       SH_PFC_PIN_GROUP(i2c2_b),
+       SH_PFC_PIN_GROUP(i2c2_c),
+       SH_PFC_PIN_GROUP(i2c2_d),
+       SH_PFC_PIN_GROUP(i2c2_e),
+       SH_PFC_PIN_GROUP(i2c3),
        SH_PFC_PIN_GROUP(intc_irq0),
        SH_PFC_PIN_GROUP(intc_irq1),
        SH_PFC_PIN_GROUP(intc_irq2),
@@ -3243,6 +3332,24 @@ static const char * const hscif1_groups[] = {
        "hscif1_ctrl_b",
 };
 
+static const char * const i2c1_groups[] = {
+       "i2c1",
+       "i2c1_b",
+       "i2c1_c",
+};
+
+static const char * const i2c2_groups[] = {
+       "i2c2",
+       "i2c2_b",
+       "i2c2_c",
+       "i2c2_d",
+       "i2c2_e",
+};
+
+static const char * const i2c3_groups[] = {
+       "i2c3",
+};
+
 static const char * const intc_groups[] = {
        "intc_irq0",
        "intc_irq1",
@@ -3469,6 +3576,9 @@ static const struct sh_pfc_function pinmux_functions[] = {
        SH_PFC_FUNCTION(eth),
        SH_PFC_FUNCTION(hscif0),
        SH_PFC_FUNCTION(hscif1),
+       SH_PFC_FUNCTION(i2c1),
+       SH_PFC_FUNCTION(i2c2),
+       SH_PFC_FUNCTION(i2c3),
        SH_PFC_FUNCTION(intc),
        SH_PFC_FUNCTION(mmc0),
        SH_PFC_FUNCTION(mmc1),
index edf45a6940cae7cc6334ff971b23934840f3ac67..8ab7898d21be3872dde3f5a70ed75c58c588023c 100644 (file)
@@ -122,6 +122,9 @@ static const struct pinctrl_pin_desc sirfsoc_pads[] = {
        PINCTRL_PIN(100, "ac97_dout"),
        PINCTRL_PIN(101, "ac97_din"),
        PINCTRL_PIN(102, "x_rtc_io"),
+
+       PINCTRL_PIN(103, "x_usb1_dp"),
+       PINCTRL_PIN(104, "x_usb1_dn"),
 };
 
 static const struct sirfsoc_muxmask lcd_16bits_sirfsoc_muxmask[] = {
@@ -139,6 +142,7 @@ static const struct sirfsoc_muxmask lcd_16bits_sirfsoc_muxmask[] = {
 static const struct sirfsoc_padmux lcd_16bits_padmux = {
        .muxmask_counts = ARRAY_SIZE(lcd_16bits_sirfsoc_muxmask),
        .muxmask = lcd_16bits_sirfsoc_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(4),
        .funcval = 0,
 };
@@ -164,6 +168,7 @@ static const struct sirfsoc_muxmask lcd_18bits_muxmask[] = {
 static const struct sirfsoc_padmux lcd_18bits_padmux = {
        .muxmask_counts = ARRAY_SIZE(lcd_18bits_muxmask),
        .muxmask = lcd_18bits_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(4) | BIT(15),
        .funcval = 0,
 };
@@ -189,6 +194,7 @@ static const struct sirfsoc_muxmask lcd_24bits_muxmask[] = {
 static const struct sirfsoc_padmux lcd_24bits_padmux = {
        .muxmask_counts = ARRAY_SIZE(lcd_24bits_muxmask),
        .muxmask = lcd_24bits_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(4) | BIT(15),
        .funcval = 0,
 };
@@ -214,6 +220,7 @@ static const struct sirfsoc_muxmask lcdrom_muxmask[] = {
 static const struct sirfsoc_padmux lcdrom_padmux = {
        .muxmask_counts = ARRAY_SIZE(lcdrom_muxmask),
        .muxmask = lcdrom_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(4),
        .funcval = BIT(4),
 };
@@ -237,6 +244,7 @@ static const struct sirfsoc_muxmask uart0_muxmask[] = {
 static const struct sirfsoc_padmux uart0_padmux = {
        .muxmask_counts = ARRAY_SIZE(uart0_muxmask),
        .muxmask = uart0_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(9),
        .funcval = BIT(9),
 };
@@ -284,6 +292,7 @@ static const struct sirfsoc_muxmask uart2_muxmask[] = {
 static const struct sirfsoc_padmux uart2_padmux = {
        .muxmask_counts = ARRAY_SIZE(uart2_muxmask),
        .muxmask = uart2_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(10),
        .funcval = BIT(10),
 };
@@ -317,6 +326,7 @@ static const struct sirfsoc_muxmask sdmmc3_muxmask[] = {
 static const struct sirfsoc_padmux sdmmc3_padmux = {
        .muxmask_counts = ARRAY_SIZE(sdmmc3_muxmask),
        .muxmask = sdmmc3_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(7),
        .funcval = 0,
 };
@@ -336,6 +346,7 @@ static const struct sirfsoc_muxmask spi0_muxmask[] = {
 static const struct sirfsoc_padmux spi0_padmux = {
        .muxmask_counts = ARRAY_SIZE(spi0_muxmask),
        .muxmask = spi0_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(7),
        .funcval = BIT(7),
 };
@@ -352,6 +363,7 @@ static const struct sirfsoc_muxmask cko1_muxmask[] = {
 static const struct sirfsoc_padmux cko1_padmux = {
        .muxmask_counts = ARRAY_SIZE(cko1_muxmask),
        .muxmask = cko1_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(3),
        .funcval = 0,
 };
@@ -371,6 +383,7 @@ static const struct sirfsoc_muxmask i2s_muxmask[] = {
 static const struct sirfsoc_padmux i2s_padmux = {
        .muxmask_counts = ARRAY_SIZE(i2s_muxmask),
        .muxmask = i2s_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(3),
        .funcval = BIT(3),
 };
@@ -390,6 +403,7 @@ static const struct sirfsoc_muxmask i2s_no_din_muxmask[] = {
 static const struct sirfsoc_padmux i2s_no_din_padmux = {
        .muxmask_counts = ARRAY_SIZE(i2s_no_din_muxmask),
        .muxmask = i2s_no_din_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(3),
        .funcval = BIT(3),
 };
@@ -409,6 +423,7 @@ static const struct sirfsoc_muxmask i2s_6chn_muxmask[] = {
 static const struct sirfsoc_padmux i2s_6chn_padmux = {
        .muxmask_counts = ARRAY_SIZE(i2s_6chn_muxmask),
        .muxmask = i2s_6chn_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(1) | BIT(3) | BIT(9),
        .funcval = BIT(1) | BIT(3) | BIT(9),
 };
@@ -439,6 +454,7 @@ static const struct sirfsoc_muxmask spi1_muxmask[] = {
 static const struct sirfsoc_padmux spi1_padmux = {
        .muxmask_counts = ARRAY_SIZE(spi1_muxmask),
        .muxmask = spi1_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(16),
        .funcval = 0,
 };
@@ -455,6 +471,7 @@ static const struct sirfsoc_muxmask sdmmc1_muxmask[] = {
 static const struct sirfsoc_padmux sdmmc1_padmux = {
        .muxmask_counts = ARRAY_SIZE(sdmmc1_muxmask),
        .muxmask = sdmmc1_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(5),
        .funcval = BIT(5),
 };
@@ -471,6 +488,7 @@ static const struct sirfsoc_muxmask gps_muxmask[] = {
 static const struct sirfsoc_padmux gps_padmux = {
        .muxmask_counts = ARRAY_SIZE(gps_muxmask),
        .muxmask = gps_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(13),
        .funcval = 0,
 };
@@ -487,6 +505,7 @@ static const struct sirfsoc_muxmask sdmmc5_muxmask[] = {
 static const struct sirfsoc_padmux sdmmc5_padmux = {
        .muxmask_counts = ARRAY_SIZE(sdmmc5_muxmask),
        .muxmask = sdmmc5_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(13),
        .funcval = BIT(13),
 };
@@ -503,6 +522,7 @@ static const struct sirfsoc_muxmask usp0_muxmask[] = {
 static const struct sirfsoc_padmux usp0_padmux = {
        .muxmask_counts = ARRAY_SIZE(usp0_muxmask),
        .muxmask = usp0_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(1) | BIT(2) | BIT(9),
        .funcval = 0,
 };
@@ -535,6 +555,7 @@ static const struct sirfsoc_muxmask usp1_muxmask[] = {
 static const struct sirfsoc_padmux usp1_padmux = {
        .muxmask_counts = ARRAY_SIZE(usp1_muxmask),
        .muxmask = usp1_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(16),
        .funcval = BIT(16),
 };
@@ -554,6 +575,7 @@ static const struct sirfsoc_muxmask nand_muxmask[] = {
 static const struct sirfsoc_padmux nand_padmux = {
        .muxmask_counts = ARRAY_SIZE(nand_muxmask),
        .muxmask = nand_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(5) | BIT(19),
        .funcval = 0,
 };
@@ -570,6 +592,7 @@ static const struct sirfsoc_muxmask sdmmc0_muxmask[] = {
 static const struct sirfsoc_padmux sdmmc0_padmux = {
        .muxmask_counts = ARRAY_SIZE(sdmmc0_muxmask),
        .muxmask = sdmmc0_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(5) | BIT(19),
        .funcval = BIT(19),
 };
@@ -586,6 +609,7 @@ static const struct sirfsoc_muxmask sdmmc2_muxmask[] = {
 static const struct sirfsoc_padmux sdmmc2_padmux = {
        .muxmask_counts = ARRAY_SIZE(sdmmc2_muxmask),
        .muxmask = sdmmc2_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(11),
        .funcval = 0,
 };
@@ -602,6 +626,7 @@ static const struct sirfsoc_muxmask sdmmc2_nowp_muxmask[] = {
 static const struct sirfsoc_padmux sdmmc2_nowp_padmux = {
        .muxmask_counts = ARRAY_SIZE(sdmmc2_nowp_muxmask),
        .muxmask = sdmmc2_nowp_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(11),
        .funcval = 0,
 };
@@ -634,6 +659,7 @@ static const struct sirfsoc_muxmask vip_muxmask[] = {
 static const struct sirfsoc_padmux vip_padmux = {
        .muxmask_counts = ARRAY_SIZE(vip_muxmask),
        .muxmask = vip_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(18),
        .funcval = BIT(18),
 };
@@ -654,6 +680,7 @@ static const struct sirfsoc_muxmask vip_noupli_muxmask[] = {
 static const struct sirfsoc_padmux vip_noupli_padmux = {
        .muxmask_counts = ARRAY_SIZE(vip_noupli_muxmask),
        .muxmask = vip_noupli_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(15),
        .funcval = BIT(15),
 };
@@ -684,6 +711,7 @@ static const struct sirfsoc_muxmask i2c1_muxmask[] = {
 static const struct sirfsoc_padmux i2c1_padmux = {
        .muxmask_counts = ARRAY_SIZE(i2c1_muxmask),
        .muxmask = i2c1_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(16),
        .funcval = 0,
 };
@@ -700,6 +728,7 @@ static const struct sirfsoc_muxmask pwm0_muxmask[] = {
 static const struct sirfsoc_padmux pwm0_padmux = {
        .muxmask_counts = ARRAY_SIZE(pwm0_muxmask),
        .muxmask = pwm0_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(12),
        .funcval = 0,
 };
@@ -772,6 +801,7 @@ static const struct sirfsoc_muxmask warm_rst_muxmask[] = {
 static const struct sirfsoc_padmux warm_rst_padmux = {
        .muxmask_counts = ARRAY_SIZE(warm_rst_muxmask),
        .muxmask = warm_rst_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(4),
        .funcval = 0,
 };
@@ -789,6 +819,7 @@ static const struct sirfsoc_muxmask usb0_upli_drvbus_muxmask[] = {
 static const struct sirfsoc_padmux usb0_upli_drvbus_padmux = {
        .muxmask_counts = ARRAY_SIZE(usb0_upli_drvbus_muxmask),
        .muxmask = usb0_upli_drvbus_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(18),
        .funcval = 0,
 };
@@ -805,12 +836,31 @@ static const struct sirfsoc_muxmask usb1_utmi_drvbus_muxmask[] = {
 static const struct sirfsoc_padmux usb1_utmi_drvbus_padmux = {
        .muxmask_counts = ARRAY_SIZE(usb1_utmi_drvbus_muxmask),
        .muxmask = usb1_utmi_drvbus_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(11),
        .funcval = BIT(11), /* refer to PAD_UTMI_DRVVBUS1_ENABLE */
 };
 
 static const unsigned usb1_utmi_drvbus_pins[] = { 28 };
 
+static const struct sirfsoc_padmux usb1_dp_dn_padmux = {
+       .muxmask_counts = 0,
+       .ctrlreg = SIRFSOC_RSC_USB_UART_SHARE,
+       .funcmask = BIT(2),
+       .funcval = BIT(2),
+};
+
+static const unsigned usb1_dp_dn_pins[] = { 103, 104 };
+
+static const struct sirfsoc_padmux uart1_route_io_usb1_padmux = {
+       .muxmask_counts = 0,
+       .ctrlreg = SIRFSOC_RSC_USB_UART_SHARE,
+       .funcmask = BIT(2),
+       .funcval = 0,
+};
+
+static const unsigned uart1_route_io_usb1_pins[] = { 103, 104 };
+
 static const struct sirfsoc_muxmask pulse_count_muxmask[] = {
        {
                .group = 0,
@@ -859,6 +909,8 @@ static const struct sirfsoc_pin_group sirfsoc_pin_groups[] = {
        SIRFSOC_PIN_GROUP("sdmmc5grp", sdmmc5_pins),
        SIRFSOC_PIN_GROUP("usb0_upli_drvbusgrp", usb0_upli_drvbus_pins),
        SIRFSOC_PIN_GROUP("usb1_utmi_drvbusgrp", usb1_utmi_drvbus_pins),
+       SIRFSOC_PIN_GROUP("usb1_dp_dngrp", usb1_dp_dn_pins),
+       SIRFSOC_PIN_GROUP("uart1_route_io_usb1grp", uart1_route_io_usb1_pins),
        SIRFSOC_PIN_GROUP("pulse_countgrp", pulse_count_pins),
        SIRFSOC_PIN_GROUP("i2sgrp", i2s_pins),
        SIRFSOC_PIN_GROUP("i2s_no_dingrp", i2s_no_din_pins),
@@ -903,6 +955,8 @@ static const char * const sdmmc5grp[] = { "sdmmc5grp" };
 static const char * const sdmmc2_nowpgrp[] = { "sdmmc2_nowpgrp" };
 static const char * const usb0_upli_drvbusgrp[] = { "usb0_upli_drvbusgrp" };
 static const char * const usb1_utmi_drvbusgrp[] = { "usb1_utmi_drvbusgrp" };
+static const char * const usb1_dp_dngrp[] = { "usb1_dp_dngrp" };
+static const char * const uart1_route_io_usb1grp[] = { "uart1_route_io_usb1grp" };
 static const char * const pulse_countgrp[] = { "pulse_countgrp" };
 static const char * const i2sgrp[] = { "i2sgrp" };
 static const char * const i2s_no_dingrp[] = { "i2s_no_dingrp" };
@@ -949,6 +1003,8 @@ static const struct sirfsoc_pmx_func sirfsoc_pmx_functions[] = {
        SIRFSOC_PMX_FUNCTION("sdmmc2_nowp", sdmmc2_nowpgrp, sdmmc2_nowp_padmux),
        SIRFSOC_PMX_FUNCTION("usb0_upli_drvbus", usb0_upli_drvbusgrp, usb0_upli_drvbus_padmux),
        SIRFSOC_PMX_FUNCTION("usb1_utmi_drvbus", usb1_utmi_drvbusgrp, usb1_utmi_drvbus_padmux),
+       SIRFSOC_PMX_FUNCTION("usb1_dp_dn", usb1_dp_dngrp, usb1_dp_dn_padmux),
+       SIRFSOC_PMX_FUNCTION("uart1_route_io_usb1", uart1_route_io_usb1grp, uart1_route_io_usb1_padmux),
        SIRFSOC_PMX_FUNCTION("pulse_count", pulse_countgrp, pulse_count_padmux),
        SIRFSOC_PMX_FUNCTION("i2s", i2sgrp, i2s_padmux),
        SIRFSOC_PMX_FUNCTION("i2s_no_din", i2s_no_dingrp, i2s_no_din_padmux),
index 1f0ad1ef5a3a5cb049afbd355f5635774fbec87b..050777be0f1e2633c40849be02e93825b9455b9d 100644 (file)
@@ -126,6 +126,9 @@ static const struct pinctrl_pin_desc sirfsoc_pads[] = {
        PINCTRL_PIN(112, "x_ldd[13]"),
        PINCTRL_PIN(113, "x_ldd[14]"),
        PINCTRL_PIN(114, "x_ldd[15]"),
+
+       PINCTRL_PIN(115, "x_usb1_dp"),
+       PINCTRL_PIN(116, "x_usb1_dn"),
 };
 
 static const struct sirfsoc_muxmask lcd_16bits_sirfsoc_muxmask[] = {
@@ -143,6 +146,7 @@ static const struct sirfsoc_muxmask lcd_16bits_sirfsoc_muxmask[] = {
 static const struct sirfsoc_padmux lcd_16bits_padmux = {
        .muxmask_counts = ARRAY_SIZE(lcd_16bits_sirfsoc_muxmask),
        .muxmask = lcd_16bits_sirfsoc_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(4),
        .funcval = 0,
 };
@@ -168,6 +172,7 @@ static const struct sirfsoc_muxmask lcd_18bits_muxmask[] = {
 static const struct sirfsoc_padmux lcd_18bits_padmux = {
        .muxmask_counts = ARRAY_SIZE(lcd_18bits_muxmask),
        .muxmask = lcd_18bits_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(4),
        .funcval = 0,
 };
@@ -193,6 +198,7 @@ static const struct sirfsoc_muxmask lcd_24bits_muxmask[] = {
 static const struct sirfsoc_padmux lcd_24bits_padmux = {
        .muxmask_counts = ARRAY_SIZE(lcd_24bits_muxmask),
        .muxmask = lcd_24bits_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(4),
        .funcval = 0,
 };
@@ -218,6 +224,7 @@ static const struct sirfsoc_muxmask lcdrom_muxmask[] = {
 static const struct sirfsoc_padmux lcdrom_padmux = {
        .muxmask_counts = ARRAY_SIZE(lcdrom_muxmask),
        .muxmask = lcdrom_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(4),
        .funcval = BIT(4),
 };
@@ -238,6 +245,7 @@ static const struct sirfsoc_muxmask uart0_muxmask[] = {
 static const struct sirfsoc_padmux uart0_padmux = {
        .muxmask_counts = ARRAY_SIZE(uart0_muxmask),
        .muxmask = uart0_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(9),
        .funcval = BIT(9),
 };
@@ -282,6 +290,7 @@ static const struct sirfsoc_muxmask uart2_muxmask[] = {
 static const struct sirfsoc_padmux uart2_padmux = {
        .muxmask_counts = ARRAY_SIZE(uart2_muxmask),
        .muxmask = uart2_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(10),
        .funcval = BIT(10),
 };
@@ -315,6 +324,7 @@ static const struct sirfsoc_muxmask sdmmc3_muxmask[] = {
 static const struct sirfsoc_padmux sdmmc3_padmux = {
        .muxmask_counts = ARRAY_SIZE(sdmmc3_muxmask),
        .muxmask = sdmmc3_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(7),
        .funcval = 0,
 };
@@ -331,6 +341,7 @@ static const struct sirfsoc_muxmask spi0_muxmask[] = {
 static const struct sirfsoc_padmux spi0_padmux = {
        .muxmask_counts = ARRAY_SIZE(spi0_muxmask),
        .muxmask = spi0_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(7),
        .funcval = BIT(7),
 };
@@ -361,6 +372,7 @@ static const struct sirfsoc_muxmask cko1_muxmask[] = {
 static const struct sirfsoc_padmux cko1_padmux = {
        .muxmask_counts = ARRAY_SIZE(cko1_muxmask),
        .muxmask = cko1_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(3),
        .funcval = 0,
 };
@@ -379,6 +391,7 @@ static const struct sirfsoc_muxmask i2s_muxmask[] = {
 static const struct sirfsoc_padmux i2s_padmux = {
        .muxmask_counts = ARRAY_SIZE(i2s_muxmask),
        .muxmask = i2s_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(3) | BIT(9),
        .funcval = BIT(3),
 };
@@ -395,6 +408,7 @@ static const struct sirfsoc_muxmask ac97_muxmask[] = {
 static const struct sirfsoc_padmux ac97_padmux = {
        .muxmask_counts = ARRAY_SIZE(ac97_muxmask),
        .muxmask = ac97_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(8),
        .funcval = 0,
 };
@@ -411,6 +425,7 @@ static const struct sirfsoc_muxmask spi1_muxmask[] = {
 static const struct sirfsoc_padmux spi1_padmux = {
        .muxmask_counts = ARRAY_SIZE(spi1_muxmask),
        .muxmask = spi1_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(8),
        .funcval = BIT(8),
 };
@@ -441,6 +456,7 @@ static const struct sirfsoc_muxmask gps_muxmask[] = {
 static const struct sirfsoc_padmux gps_padmux = {
        .muxmask_counts = ARRAY_SIZE(gps_muxmask),
        .muxmask = gps_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(12) | BIT(13) | BIT(14),
        .funcval = BIT(12),
 };
@@ -463,6 +479,7 @@ static const struct sirfsoc_muxmask sdmmc5_muxmask[] = {
 static const struct sirfsoc_padmux sdmmc5_padmux = {
        .muxmask_counts = ARRAY_SIZE(sdmmc5_muxmask),
        .muxmask = sdmmc5_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(13) | BIT(14),
        .funcval = BIT(13) | BIT(14),
 };
@@ -479,12 +496,27 @@ static const struct sirfsoc_muxmask usp0_muxmask[] = {
 static const struct sirfsoc_padmux usp0_padmux = {
        .muxmask_counts = ARRAY_SIZE(usp0_muxmask),
        .muxmask = usp0_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(1) | BIT(2) | BIT(6) | BIT(9),
        .funcval = 0,
 };
 
 static const unsigned usp0_pins[] = { 51, 52, 53, 54, 55 };
 
+static const struct sirfsoc_muxmask usp0_uart_nostreamctrl_muxmask[] = {
+       {
+               .group = 1,
+               .mask = BIT(20) | BIT(21),
+       },
+};
+
+static const struct sirfsoc_padmux usp0_uart_nostreamctrl_padmux = {
+       .muxmask_counts = ARRAY_SIZE(usp0_uart_nostreamctrl_muxmask),
+       .muxmask = usp0_uart_nostreamctrl_muxmask,
+};
+
+static const unsigned usp0_uart_nostreamctrl_pins[] = { 52, 53 };
+
 static const struct sirfsoc_muxmask usp1_muxmask[] = {
        {
                .group = 1,
@@ -495,12 +527,27 @@ static const struct sirfsoc_muxmask usp1_muxmask[] = {
 static const struct sirfsoc_padmux usp1_padmux = {
        .muxmask_counts = ARRAY_SIZE(usp1_muxmask),
        .muxmask = usp1_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(1) | BIT(9) | BIT(10) | BIT(11),
        .funcval = 0,
 };
 
 static const unsigned usp1_pins[] = { 56, 57, 58, 59, 60 };
 
+static const struct sirfsoc_muxmask usp1_uart_nostreamctrl_muxmask[] = {
+       {
+               .group = 1,
+               .mask = BIT(25) | BIT(26),
+       },
+};
+
+static const struct sirfsoc_padmux usp1_uart_nostreamctrl_padmux = {
+       .muxmask_counts = ARRAY_SIZE(usp1_uart_nostreamctrl_muxmask),
+       .muxmask = usp1_uart_nostreamctrl_muxmask,
+};
+
+static const unsigned usp1_uart_nostreamctrl_pins[] = { 57, 58 };
+
 static const struct sirfsoc_muxmask usp2_muxmask[] = {
        {
                .group = 1,
@@ -514,12 +561,27 @@ static const struct sirfsoc_muxmask usp2_muxmask[] = {
 static const struct sirfsoc_padmux usp2_padmux = {
        .muxmask_counts = ARRAY_SIZE(usp2_muxmask),
        .muxmask = usp2_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(13) | BIT(14),
        .funcval = 0,
 };
 
 static const unsigned usp2_pins[] = { 61, 62, 63, 64, 65 };
 
+static const struct sirfsoc_muxmask usp2_uart_nostreamctrl_muxmask[] = {
+       {
+               .group = 1,
+               .mask = BIT(30) | BIT(31),
+       },
+};
+
+static const struct sirfsoc_padmux usp2_uart_nostreamctrl_padmux = {
+       .muxmask_counts = ARRAY_SIZE(usp2_uart_nostreamctrl_muxmask),
+       .muxmask = usp2_uart_nostreamctrl_muxmask,
+};
+
+static const unsigned usp2_uart_nostreamctrl_pins[] = { 62, 63 };
+
 static const struct sirfsoc_muxmask nand_muxmask[] = {
        {
                .group = 2,
@@ -530,6 +592,7 @@ static const struct sirfsoc_muxmask nand_muxmask[] = {
 static const struct sirfsoc_padmux nand_padmux = {
        .muxmask_counts = ARRAY_SIZE(nand_muxmask),
        .muxmask = nand_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(5),
        .funcval = 0,
 };
@@ -538,6 +601,7 @@ static const unsigned nand_pins[] = { 64, 65, 92, 93, 94 };
 
 static const struct sirfsoc_padmux sdmmc0_padmux = {
        .muxmask_counts = 0,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(5),
        .funcval = 0,
 };
@@ -554,6 +618,7 @@ static const struct sirfsoc_muxmask sdmmc2_muxmask[] = {
 static const struct sirfsoc_padmux sdmmc2_padmux = {
        .muxmask_counts = ARRAY_SIZE(sdmmc2_muxmask),
        .muxmask = sdmmc2_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(5),
        .funcval = BIT(5),
 };
@@ -586,6 +651,7 @@ static const struct sirfsoc_muxmask vip_muxmask[] = {
 static const struct sirfsoc_padmux vip_padmux = {
        .muxmask_counts = ARRAY_SIZE(vip_muxmask),
        .muxmask = vip_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(0),
        .funcval = 0,
 };
@@ -635,6 +701,7 @@ static const struct sirfsoc_muxmask viprom_muxmask[] = {
 static const struct sirfsoc_padmux viprom_padmux = {
        .muxmask_counts = ARRAY_SIZE(viprom_muxmask),
        .muxmask = viprom_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(0),
        .funcval = BIT(0),
 };
@@ -651,6 +718,7 @@ static const struct sirfsoc_muxmask pwm0_muxmask[] = {
 static const struct sirfsoc_padmux pwm0_padmux = {
        .muxmask_counts = ARRAY_SIZE(pwm0_muxmask),
        .muxmask = pwm0_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(12),
        .funcval = 0,
 };
@@ -722,6 +790,7 @@ static const struct sirfsoc_muxmask usb0_utmi_drvbus_muxmask[] = {
 static const struct sirfsoc_padmux usb0_utmi_drvbus_padmux = {
        .muxmask_counts = ARRAY_SIZE(usb0_utmi_drvbus_muxmask),
        .muxmask = usb0_utmi_drvbus_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(6),
        .funcval = BIT(6), /* refer to PAD_UTMI_DRVVBUS0_ENABLE */
 };
@@ -738,12 +807,31 @@ static const struct sirfsoc_muxmask usb1_utmi_drvbus_muxmask[] = {
 static const struct sirfsoc_padmux usb1_utmi_drvbus_padmux = {
        .muxmask_counts = ARRAY_SIZE(usb1_utmi_drvbus_muxmask),
        .muxmask = usb1_utmi_drvbus_muxmask,
+       .ctrlreg = SIRFSOC_RSC_PIN_MUX,
        .funcmask = BIT(11),
        .funcval = BIT(11), /* refer to PAD_UTMI_DRVVBUS1_ENABLE */
 };
 
 static const unsigned usb1_utmi_drvbus_pins[] = { 59 };
 
+static const struct sirfsoc_padmux usb1_dp_dn_padmux = {
+       .muxmask_counts = 0,
+       .ctrlreg = SIRFSOC_RSC_USB_UART_SHARE,
+       .funcmask = BIT(2),
+       .funcval = BIT(2),
+};
+
+static const unsigned usb1_dp_dn_pins[] = { 115, 116 };
+
+static const struct sirfsoc_padmux uart1_route_io_usb1_padmux = {
+       .muxmask_counts = 0,
+       .ctrlreg = SIRFSOC_RSC_USB_UART_SHARE,
+       .funcmask = BIT(2),
+       .funcval = 0,
+};
+
+static const unsigned uart1_route_io_usb1_pins[] = { 115, 116 };
+
 static const struct sirfsoc_muxmask pulse_count_muxmask[] = {
        {
                .group = 0,
@@ -764,12 +852,19 @@ static const struct sirfsoc_pin_group sirfsoc_pin_groups[] = {
        SIRFSOC_PIN_GROUP("lcd_24bitsgrp", lcd_24bits_pins),
        SIRFSOC_PIN_GROUP("lcdrom_grp", lcdrom_pins),
        SIRFSOC_PIN_GROUP("uart0grp", uart0_pins),
+       SIRFSOC_PIN_GROUP("uart0_nostreamctrlgrp", uart0_nostreamctrl_pins),
        SIRFSOC_PIN_GROUP("uart1grp", uart1_pins),
        SIRFSOC_PIN_GROUP("uart2grp", uart2_pins),
        SIRFSOC_PIN_GROUP("uart2_nostreamctrlgrp", uart2_nostreamctrl_pins),
        SIRFSOC_PIN_GROUP("usp0grp", usp0_pins),
+       SIRFSOC_PIN_GROUP("usp0_uart_nostreamctrl_grp",
+                                       usp0_uart_nostreamctrl_pins),
        SIRFSOC_PIN_GROUP("usp1grp", usp1_pins),
+       SIRFSOC_PIN_GROUP("usp1_uart_nostreamctrl_grp",
+                                       usp1_uart_nostreamctrl_pins),
        SIRFSOC_PIN_GROUP("usp2grp", usp2_pins),
+       SIRFSOC_PIN_GROUP("usp2_uart_nostreamctrl_grp",
+                                       usp2_uart_nostreamctrl_pins),
        SIRFSOC_PIN_GROUP("i2c0grp", i2c0_pins),
        SIRFSOC_PIN_GROUP("i2c1grp", i2c1_pins),
        SIRFSOC_PIN_GROUP("pwm0grp", pwm0_pins),
@@ -789,6 +884,8 @@ static const struct sirfsoc_pin_group sirfsoc_pin_groups[] = {
        SIRFSOC_PIN_GROUP("sdmmc5grp", sdmmc5_pins),
        SIRFSOC_PIN_GROUP("usb0_utmi_drvbusgrp", usb0_utmi_drvbus_pins),
        SIRFSOC_PIN_GROUP("usb1_utmi_drvbusgrp", usb1_utmi_drvbus_pins),
+       SIRFSOC_PIN_GROUP("usb1_dp_dngrp", usb1_dp_dn_pins),
+       SIRFSOC_PIN_GROUP("uart1_route_io_usb1grp", uart1_route_io_usb1_pins),
        SIRFSOC_PIN_GROUP("pulse_countgrp", pulse_count_pins),
        SIRFSOC_PIN_GROUP("i2sgrp", i2s_pins),
        SIRFSOC_PIN_GROUP("ac97grp", ac97_pins),
@@ -803,12 +900,19 @@ static const char * const lcd_18bitsgrp[] = { "lcd_18bitsgrp" };
 static const char * const lcd_24bitsgrp[] = { "lcd_24bitsgrp" };
 static const char * const lcdromgrp[] = { "lcdromgrp" };
 static const char * const uart0grp[] = { "uart0grp" };
+static const char * const uart0_nostreamctrlgrp[] = { "uart0_nostreamctrlgrp" };
 static const char * const uart1grp[] = { "uart1grp" };
 static const char * const uart2grp[] = { "uart2grp" };
 static const char * const uart2_nostreamctrlgrp[] = { "uart2_nostreamctrlgrp" };
 static const char * const usp0grp[] = { "usp0grp" };
+static const char * const usp0_uart_nostreamctrl_grp[] =
+                                       { "usp0_uart_nostreamctrl_grp" };
 static const char * const usp1grp[] = { "usp1grp" };
+static const char * const usp1_uart_nostreamctrl_grp[] =
+                                       { "usp1_uart_nostreamctrl_grp" };
 static const char * const usp2grp[] = { "usp2grp" };
+static const char * const usp2_uart_nostreamctrl_grp[] =
+                                       { "usp2_uart_nostreamctrl_grp" };
 static const char * const i2c0grp[] = { "i2c0grp" };
 static const char * const i2c1grp[] = { "i2c1grp" };
 static const char * const pwm0grp[] = { "pwm0grp" };
@@ -828,6 +932,8 @@ static const char * const sdmmc4grp[] = { "sdmmc4grp" };
 static const char * const sdmmc5grp[] = { "sdmmc5grp" };
 static const char * const usb0_utmi_drvbusgrp[] = { "usb0_utmi_drvbusgrp" };
 static const char * const usb1_utmi_drvbusgrp[] = { "usb1_utmi_drvbusgrp" };
+static const char * const usb1_dp_dngrp[] = { "usb1_dp_dngrp" };
+static const char * const uart1_route_io_usb1grp[] = { "uart1_route_io_usb1grp" };
 static const char * const pulse_countgrp[] = { "pulse_countgrp" };
 static const char * const i2sgrp[] = { "i2sgrp" };
 static const char * const ac97grp[] = { "ac97grp" };
@@ -842,12 +948,19 @@ static const struct sirfsoc_pmx_func sirfsoc_pmx_functions[] = {
        SIRFSOC_PMX_FUNCTION("lcd_24bits", lcd_24bitsgrp, lcd_24bits_padmux),
        SIRFSOC_PMX_FUNCTION("lcdrom", lcdromgrp, lcdrom_padmux),
        SIRFSOC_PMX_FUNCTION("uart0", uart0grp, uart0_padmux),
+       SIRFSOC_PMX_FUNCTION("uart0_nostreamctrl", uart0_nostreamctrlgrp, uart0_nostreamctrl_padmux),
        SIRFSOC_PMX_FUNCTION("uart1", uart1grp, uart1_padmux),
        SIRFSOC_PMX_FUNCTION("uart2", uart2grp, uart2_padmux),
        SIRFSOC_PMX_FUNCTION("uart2_nostreamctrl", uart2_nostreamctrlgrp, uart2_nostreamctrl_padmux),
        SIRFSOC_PMX_FUNCTION("usp0", usp0grp, usp0_padmux),
+       SIRFSOC_PMX_FUNCTION("usp0_uart_nostreamctrl",
+               usp0_uart_nostreamctrl_grp, usp0_uart_nostreamctrl_padmux),
        SIRFSOC_PMX_FUNCTION("usp1", usp1grp, usp1_padmux),
+       SIRFSOC_PMX_FUNCTION("usp1_uart_nostreamctrl",
+               usp1_uart_nostreamctrl_grp, usp1_uart_nostreamctrl_padmux),
        SIRFSOC_PMX_FUNCTION("usp2", usp2grp, usp2_padmux),
+       SIRFSOC_PMX_FUNCTION("usp2_uart_nostreamctrl",
+               usp2_uart_nostreamctrl_grp, usp2_uart_nostreamctrl_padmux),
        SIRFSOC_PMX_FUNCTION("i2c0", i2c0grp, i2c0_padmux),
        SIRFSOC_PMX_FUNCTION("i2c1", i2c1grp, i2c1_padmux),
        SIRFSOC_PMX_FUNCTION("pwm0", pwm0grp, pwm0_padmux),
@@ -867,6 +980,8 @@ static const struct sirfsoc_pmx_func sirfsoc_pmx_functions[] = {
        SIRFSOC_PMX_FUNCTION("sdmmc5", sdmmc5grp, sdmmc5_padmux),
        SIRFSOC_PMX_FUNCTION("usb0_utmi_drvbus", usb0_utmi_drvbusgrp, usb0_utmi_drvbus_padmux),
        SIRFSOC_PMX_FUNCTION("usb1_utmi_drvbus", usb1_utmi_drvbusgrp, usb1_utmi_drvbus_padmux),
+       SIRFSOC_PMX_FUNCTION("usb1_dp_dn", usb1_dp_dngrp, usb1_dp_dn_padmux),
+       SIRFSOC_PMX_FUNCTION("uart1_route_io_usb1", uart1_route_io_usb1grp, uart1_route_io_usb1_padmux),
        SIRFSOC_PMX_FUNCTION("pulse_count", pulse_countgrp, pulse_count_padmux),
        SIRFSOC_PMX_FUNCTION("i2s", i2sgrp, i2s_padmux),
        SIRFSOC_PMX_FUNCTION("ac97", ac97grp, ac97_padmux),
index 26f946af79333f1ee5257e336a77fdd5a1019f88..b81e388c50defc06f7f6d2b4f21e68fecee2c0ae 100644 (file)
@@ -166,12 +166,12 @@ static void sirfsoc_pinmux_endisable(struct sirfsoc_pmx *spmx, unsigned selector
 
        if (mux->funcmask && enable) {
                u32 func_en_val;
+
                func_en_val =
-                       readl(spmx->rsc_virtbase + SIRFSOC_RSC_PIN_MUX);
+                       readl(spmx->rsc_virtbase + mux->ctrlreg);
                func_en_val =
-                       (func_en_val & ~mux->funcmask) | (mux->
-                               funcval);
-               writel(func_en_val, spmx->rsc_virtbase + SIRFSOC_RSC_PIN_MUX);
+                       (func_en_val & ~mux->funcmask) | (mux->funcval);
+               writel(func_en_val, spmx->rsc_virtbase + mux->ctrlreg);
        }
 }
 
index 17cc108510ba2b8cbe9e4cef0fbd3ac893ee912a..d7f16b499ad948e42fc99e6f44b69f1f8f397d61 100644 (file)
@@ -9,8 +9,9 @@
 #ifndef __PINMUX_SIRF_H__
 #define __PINMUX_SIRF_H__
 
-#define SIRFSOC_NUM_PADS    622
-#define SIRFSOC_RSC_PIN_MUX 0x4
+#define SIRFSOC_NUM_PADS               622
+#define SIRFSOC_RSC_USB_UART_SHARE     0
+#define SIRFSOC_RSC_PIN_MUX            0x4
 
 #define SIRFSOC_GPIO_PAD_EN(g)         ((g)*0x100 + 0x84)
 #define SIRFSOC_GPIO_PAD_EN_CLR(g)     ((g)*0x100 + 0x90)
@@ -61,6 +62,7 @@ struct sirfsoc_padmux {
        unsigned long muxmask_counts;
        const struct sirfsoc_muxmask *muxmask;
        /* RSC_PIN_MUX set */
+       unsigned long ctrlreg;
        unsigned long funcmask;
        unsigned long funcval;
 };
index 0a7f0bdbaa7d0c335c4c53e96d27b78f53526419..ff2940e9f2a7455cd0c93ac24dff0ce4f70849ad 100644 (file)
@@ -735,7 +735,7 @@ static struct platform_driver plgpio_driver = {
                .owner = THIS_MODULE,
                .name = "spear-plgpio",
                .pm = &plgpio_dev_pm_ops,
-               .of_match_table = of_match_ptr(plgpio_of_match),
+               .of_match_table = plgpio_of_match,
        },
 };
 
index bde646995d10ab7c214b69fd818ae8328aa6b319..523f4052553574082a256a239f3a573432e501e9 100644 (file)
@@ -228,6 +228,9 @@ struct gpio_pin_range {
 int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
                           unsigned int gpio_offset, unsigned int pin_offset,
                           unsigned int npins);
+int gpiochip_add_pingroup_range(struct gpio_chip *chip,
+                       struct pinctrl_dev *pctldev,
+                       unsigned int gpio_offset, const char *pin_group);
 void gpiochip_remove_pin_ranges(struct gpio_chip *chip);
 
 #else
@@ -239,6 +242,13 @@ gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
 {
        return 0;
 }
+static inline int
+gpiochip_add_pingroup_range(struct gpio_chip *chip,
+                       struct pinctrl_dev *pctldev,
+                       unsigned int gpio_offset, const char *pin_group)
+{
+       return 0;
+}
 
 static inline void
 gpiochip_remove_pin_ranges(struct gpio_chip *chip)
index d7988b4d8af96c527d3619f906305220aaafafa7..0fee6ff77ffcaeeaa52f71cea0dcec310007f221 100644 (file)
@@ -16,7 +16,7 @@
 #define AT91_PINCTRL_PULL_DOWN         (1 << 3)
 #define AT91_PINCTRL_DIS_SCHMIT                (1 << 4)
 #define AT91_PINCTRL_DEBOUNCE          (1 << 16)
-#define AT91_PINCTRL_DEBOUNCE_VA(x)    (x << 17)
+#define AT91_PINCTRL_DEBOUNCE_VAL(x)   (x << 17)
 
 #define AT91_PINCTRL_PULL_UP_DEGLITCH  (AT91_PINCTRL_PULL_UP | AT91_PINCTRL_DEGLITCH)
 
index 552e3f46e4a33f5b4915c86182c13cf0c876233a..b8d0e53a802f0eacadcd44f4f3fba8ec1163eda5 100644 (file)
@@ -80,6 +80,7 @@ static inline int irq_to_gpio(unsigned int irq)
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/bug.h>
+#include <linux/pinctrl/pinctrl.h>
 
 struct device;
 struct gpio_chip;
@@ -220,6 +221,15 @@ gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
        return -EINVAL;
 }
 
+static inline int
+gpiochip_add_pingroup_range(struct gpio_chip *chip,
+                       struct pinctrl_dev *pctldev,
+                       unsigned int gpio_offset, const char *pin_group)
+{
+       WARN_ON(1);
+       return -EINVAL;
+}
+
 static inline void
 gpiochip_remove_pin_ranges(struct gpio_chip *chip)
 {
index 5979147d2bda99587e07cc52e1fc4f0f3fd771f0..fefb88663975a363f42d15d05d2787fe7cbea1d7 100644 (file)
@@ -144,6 +144,9 @@ extern struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname,
 extern struct pinctrl_gpio_range *
 pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev,
                                 unsigned int pin);
+extern int pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+                               const char *pin_group, const unsigned **pins,
+                               unsigned *num_pins);
 
 #ifdef CONFIG_OF
 extern struct pinctrl_dev *of_pinctrl_get(struct device_node *np);
diff --git a/include/linux/platform_data/pinctrl-adi2.h b/include/linux/platform_data/pinctrl-adi2.h
new file mode 100644 (file)
index 0000000..8f91300
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Pinctrl Driver for ADI GPIO2 controller
+ *
+ * Copyright 2007-2013 Analog Devices Inc.
+ *
+ * Licensed under the GPLv2 or later
+ */
+
+
+#ifndef PINCTRL_ADI2_H
+#define PINCTRL_ADI2_H
+
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+/**
+ * struct adi_pinctrl_gpio_platform_data - Pinctrl gpio platform data
+ * for ADI GPIO2 device.
+ *
+ * @port_gpio_base: Optional global GPIO index of the GPIO bank.
+ *                 0 means driver decides.
+ * @port_pin_base: Pin index of the pin controller device.
+ * @port_width: PIN number of the GPIO bank device
+ * @pint_id: GPIO PINT device id that this GPIO bank should map to.
+ * @pint_assign: The 32-bit GPIO PINT registers can be divided into 2 parts. A
+ *               GPIO bank can be mapped into either low 16 bits[0] or high 16
+ *               bits[1] of each PINT register.
+ * @pint_map: GIOP bank mapping code in PINT device
+ */
+struct adi_pinctrl_gpio_platform_data {
+       unsigned int port_gpio_base;
+       unsigned int port_pin_base;
+       unsigned int port_width;
+       u8 pinctrl_id;
+       u8 pint_id;
+       bool pint_assign;
+       u8 pint_map;
+};
+
+#endif