summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@st.com>2012-03-28 22:27:07 +0530
committerArnd Bergmann <arnd@arndb.de>2012-04-22 22:49:25 +0200
commit52130b6033c580c27d968f64cd73209c9609e4e0 (patch)
treedd714e583a2c33f432e9244b9674a7d7b38da520
parentdeda8287e1a602393b052c80b815b3706987b3da (diff)
pinctrl: Add SPEAr3xx pinctrl drivers
This adds pinctrl driver for SPEAr3xx family. SPEAr3xx family supports three families: SPEAr300, SPEAr310 and SPEAr320. Signed-off-by: Viresh Kumar <viresh.kumar@st.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Reviewed-by: Stephen Warren <swarren@wwwdotorg.org>
-rw-r--r--Documentation/devicetree/bindings/pinctrl/pinctrl_spear.txt108
-rw-r--r--drivers/pinctrl/spear/Kconfig20
-rw-r--r--drivers/pinctrl/spear/Makefile4
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear300.c708
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear310.c431
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear320.c3468
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear3xx.c588
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear3xx.h92
8 files changed, 5419 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl_spear.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl_spear.txt
new file mode 100644
index 000000000000..3664d37e6799
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl_spear.txt
@@ -0,0 +1,108 @@
+ST Microelectronics, SPEAr pinmux controller
+
+Required properties:
+- compatible : "st,spear300-pinmux"
+ : "st,spear310-pinmux"
+ : "st,spear320-pinmux"
+- reg : Address range of the pinctrl registers
+- st,pinmux-mode: Mandatory for SPEAr300 and SPEAr320 and invalid for others.
+ - Its values for SPEAr300:
+ - NAND_MODE : <0>
+ - NOR_MODE : <1>
+ - PHOTO_FRAME_MODE : <2>
+ - LEND_IP_PHONE_MODE : <3>
+ - HEND_IP_PHONE_MODE : <4>
+ - LEND_WIFI_PHONE_MODE : <5>
+ - HEND_WIFI_PHONE_MODE : <6>
+ - ATA_PABX_WI2S_MODE : <7>
+ - ATA_PABX_I2S_MODE : <8>
+ - CAML_LCDW_MODE : <9>
+ - CAMU_LCD_MODE : <10>
+ - CAMU_WLCD_MODE : <11>
+ - CAML_LCD_MODE : <12>
+ - Its values for SPEAr320:
+ - AUTO_NET_SMII_MODE : <0>
+ - AUTO_NET_MII_MODE : <1>
+ - AUTO_EXP_MODE : <2>
+ - SMALL_PRINTERS_MODE : <3>
+ - EXTENDED_MODE : <4>
+
+Please refer to pinctrl-bindings.txt in this directory for details of the common
+pinctrl bindings used by client devices.
+
+SPEAr's pinmux nodes act as a container for an abitrary number of subnodes. Each
+of these subnodes represents muxing for a pin, a group, or a list of pins or
+groups.
+
+The name of each subnode is not important; all subnodes should be enumerated
+and processed purely based on their content.
+
+Required subnode-properties:
+- st,pins : An array of strings. Each string contains the name of a pin or
+ group.
+- st,function: A string containing the name of the function to mux to the pin or
+ group. See the SPEAr's TRM to determine which are valid for each pin or group.
+
+ Valid values for group and function names can be found from looking at the
+ group and function arrays in driver files:
+ drivers/pinctrl/spear/pinctrl-spear3*0.c
+
+Valid values for group names are:
+For All SPEAr3xx machines:
+ "firda_grp", "i2c0_grp", "ssp_cs_grp", "ssp0_grp", "mii0_grp",
+ "gpio0_pin0_grp", "gpio0_pin1_grp", "gpio0_pin2_grp", "gpio0_pin3_grp",
+ "gpio0_pin4_grp", "gpio0_pin5_grp", "uart0_ext_grp", "uart0_grp",
+ "timer_0_1_grp", timer_0_1_pins, "timer_2_3_grp"
+
+For SPEAr300 machines:
+ "fsmc_2chips_grp", "fsmc_4chips_grp", "clcd_lcdmode_grp",
+ "clcd_pfmode_grp", "tdm_grp", "i2c_clk_grp_grp", "caml_grp", "camu_grp",
+ "dac_grp", "i2s_grp", "sdhci_4bit_grp", "sdhci_8bit_grp",
+ "gpio1_0_to_3_grp", "gpio1_4_to_7_grp"
+
+For SPEAr310 machines:
+ "emi_cs_0_to_5_grp", "uart1_grp", "uart2_grp", "uart3_grp", "uart4_grp",
+ "uart5_grp", "fsmc_grp", "rs485_0_grp", "rs485_1_grp", "tdm_grp"
+
+For SPEAr320 machines:
+ "clcd_grp", "emi_grp", "fsmc_8bit_grp", "fsmc_16bit_grp", "spp_grp",
+ "sdhci_led_grp", "sdhci_cd_12_grp", "sdhci_cd_51_grp", "i2s_grp",
+ "uart1_grp", "uart1_modem_2_to_7_grp", "uart1_modem_31_to_36_grp",
+ "uart1_modem_34_to_45_grp", "uart1_modem_80_to_85_grp", "uart2_grp",
+ "uart3_8_9_grp", "uart3_15_16_grp", "uart3_41_42_grp",
+ "uart3_52_53_grp", "uart3_73_74_grp", "uart3_94_95_grp",
+ "uart3_98_99_grp", "uart4_6_7_grp", "uart4_13_14_grp",
+ "uart4_39_40_grp", "uart4_71_72_grp", "uart4_92_93_grp",
+ "uart4_100_101_grp", "uart5_4_5_grp", "uart5_37_38_grp",
+ "uart5_69_70_grp", "uart5_90_91_grp", "uart6_2_3_grp",
+ "uart6_88_89_grp", "rs485_grp", "touchscreen_grp", "can0_grp",
+ "can1_grp", "pwm0_1_pin_8_9_grp", "pwm0_1_pin_14_15_grp",
+ "pwm0_1_pin_30_31_grp", "pwm0_1_pin_37_38_grp", "pwm0_1_pin_42_43_grp",
+ "pwm0_1_pin_59_60_grp", "pwm0_1_pin_88_89_grp", "pwm2_pin_7_grp",
+ "pwm2_pin_13_grp", "pwm2_pin_29_grp", "pwm2_pin_34_grp",
+ "pwm2_pin_41_grp", "pwm2_pin_58_grp", "pwm2_pin_87_grp",
+ "pwm3_pin_6_grp", "pwm3_pin_12_grp", "pwm3_pin_28_grp",
+ "pwm3_pin_40_grp", "pwm3_pin_57_grp", "pwm3_pin_86_grp",
+ "ssp1_17_20_grp", "ssp1_36_39_grp", "ssp1_48_51_grp", "ssp1_65_68_grp",
+ "ssp1_94_97_grp", "ssp2_13_16_grp", "ssp2_32_35_grp", "ssp2_44_47_grp",
+ "ssp2_61_64_grp", "ssp2_90_93_grp", "mii2_grp", "smii0_1_grp",
+ "rmii0_1_grp", "i2c1_8_9_grp", "i2c1_98_99_grp", "i2c2_0_1_grp",
+ "i2c2_2_3_grp", "i2c2_19_20_grp", "i2c2_75_76_grp", "i2c2_96_97_grp"
+
+Valid values for function names are:
+For All SPEAr3xx machines:
+ "firda", "i2c0", "ssp_cs", "ssp0", "mii0", "gpio0", "uart0_ext",
+ "uart0", "timer_0_1", "timer_2_3"
+
+For SPEAr300 machines:
+ "fsmc", "clcd", "tdm", "i2c1", "cam", "dac", "i2s", "sdhci", "gpio1"
+
+For SPEAr310 machines:
+ "emi", "uart1", "uart2", "uart3", "uart4", "uart5", "fsmc", "rs485_0",
+ "rs485_1", "tdm"
+
+For SPEAr320 machines:
+ "clcd", "emi", "fsmc", "spp", "sdhci", "i2s", "uart1", "uart1_modem",
+ "uart2", "uart3", "uart4", "uart5", "uart6", "rs485", "touchscreen",
+ "can0", "can1", "pwm0_1", "pwm2", "pwm3", "ssp1", "ssp2", "mii2",
+ "mii0_1", "i2c1", "i2c2"
diff --git a/drivers/pinctrl/spear/Kconfig b/drivers/pinctrl/spear/Kconfig
index 47a0e2954922..6a2596b4f359 100644
--- a/drivers/pinctrl/spear/Kconfig
+++ b/drivers/pinctrl/spear/Kconfig
@@ -11,4 +11,24 @@ config PINCTRL_SPEAR
help
This enables pin control drivers for SPEAr Platform
+config PINCTRL_SPEAR3XX
+ bool
+ depends on ARCH_SPEAR3XX
+ select PINCTRL_SPEAR
+
+config PINCTRL_SPEAR300
+ bool "ST Microelectronics SPEAr300 SoC pin controller driver"
+ depends on MACH_SPEAR300
+ select PINCTRL_SPEAR3XX
+
+config PINCTRL_SPEAR310
+ bool "ST Microelectronics SPEAr310 SoC pin controller driver"
+ depends on MACH_SPEAR310
+ select PINCTRL_SPEAR3XX
+
+config PINCTRL_SPEAR320
+ bool "ST Microelectronics SPEAr320 SoC pin controller driver"
+ depends on MACH_SPEAR320
+ select PINCTRL_SPEAR3XX
+
endif
diff --git a/drivers/pinctrl/spear/Makefile b/drivers/pinctrl/spear/Makefile
index 69c1a51e19d3..15dcb85da22d 100644
--- a/drivers/pinctrl/spear/Makefile
+++ b/drivers/pinctrl/spear/Makefile
@@ -1,3 +1,7 @@
# SPEAr pinmux support
obj-$(CONFIG_PINCTRL_SPEAR) += pinctrl-spear.o
+obj-$(CONFIG_PINCTRL_SPEAR3XX) += pinctrl-spear3xx.o
+obj-$(CONFIG_PINCTRL_SPEAR300) += pinctrl-spear300.o
+obj-$(CONFIG_PINCTRL_SPEAR310) += pinctrl-spear310.o
+obj-$(CONFIG_PINCTRL_SPEAR320) += pinctrl-spear320.o
diff --git a/drivers/pinctrl/spear/pinctrl-spear300.c b/drivers/pinctrl/spear/pinctrl-spear300.c
new file mode 100644
index 000000000000..9c82a35e4e78
--- /dev/null
+++ b/drivers/pinctrl/spear/pinctrl-spear300.c
@@ -0,0 +1,708 @@
+/*
+ * Driver for the ST Microelectronics SPEAr300 pinmux
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "pinctrl-spear3xx.h"
+
+#define DRIVER_NAME "spear300-pinmux"
+
+/* addresses */
+#define PMX_CONFIG_REG 0x00
+#define MODE_CONFIG_REG 0x04
+
+/* modes */
+#define NAND_MODE (1 << 0)
+#define NOR_MODE (1 << 1)
+#define PHOTO_FRAME_MODE (1 << 2)
+#define LEND_IP_PHONE_MODE (1 << 3)
+#define HEND_IP_PHONE_MODE (1 << 4)
+#define LEND_WIFI_PHONE_MODE (1 << 5)
+#define HEND_WIFI_PHONE_MODE (1 << 6)
+#define ATA_PABX_WI2S_MODE (1 << 7)
+#define ATA_PABX_I2S_MODE (1 << 8)
+#define CAML_LCDW_MODE (1 << 9)
+#define CAMU_LCD_MODE (1 << 10)
+#define CAMU_WLCD_MODE (1 << 11)
+#define CAML_LCD_MODE (1 << 12)
+
+static struct spear_pmx_mode pmx_mode_nand = {
+ .name = "nand",
+ .mode = NAND_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0x00,
+};
+
+static struct spear_pmx_mode pmx_mode_nor = {
+ .name = "nor",
+ .mode = NOR_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0x01,
+};
+
+static struct spear_pmx_mode pmx_mode_photo_frame = {
+ .name = "photo frame mode",
+ .mode = PHOTO_FRAME_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0x02,
+};
+
+static struct spear_pmx_mode pmx_mode_lend_ip_phone = {
+ .name = "lend ip phone mode",
+ .mode = LEND_IP_PHONE_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0x03,
+};
+
+static struct spear_pmx_mode pmx_mode_hend_ip_phone = {
+ .name = "hend ip phone mode",
+ .mode = HEND_IP_PHONE_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0x04,
+};
+
+static struct spear_pmx_mode pmx_mode_lend_wifi_phone = {
+ .name = "lend wifi phone mode",
+ .mode = LEND_WIFI_PHONE_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0x05,
+};
+
+static struct spear_pmx_mode pmx_mode_hend_wifi_phone = {
+ .name = "hend wifi phone mode",
+ .mode = HEND_WIFI_PHONE_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0x06,
+};
+
+static struct spear_pmx_mode pmx_mode_ata_pabx_wi2s = {
+ .name = "ata pabx wi2s mode",
+ .mode = ATA_PABX_WI2S_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0x07,
+};
+
+static struct spear_pmx_mode pmx_mode_ata_pabx_i2s = {
+ .name = "ata pabx i2s mode",
+ .mode = ATA_PABX_I2S_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0x08,
+};
+
+static struct spear_pmx_mode pmx_mode_caml_lcdw = {
+ .name = "caml lcdw mode",
+ .mode = CAML_LCDW_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0x0C,
+};
+
+static struct spear_pmx_mode pmx_mode_camu_lcd = {
+ .name = "camu lcd mode",
+ .mode = CAMU_LCD_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0x0D,
+};
+
+static struct spear_pmx_mode pmx_mode_camu_wlcd = {
+ .name = "camu wlcd mode",
+ .mode = CAMU_WLCD_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0xE,
+};
+
+static struct spear_pmx_mode pmx_mode_caml_lcd = {
+ .name = "caml lcd mode",
+ .mode = CAML_LCD_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0x0F,
+};
+
+static struct spear_pmx_mode *spear300_pmx_modes[] = {
+ &pmx_mode_nand,
+ &pmx_mode_nor,
+ &pmx_mode_photo_frame,
+ &pmx_mode_lend_ip_phone,
+ &pmx_mode_hend_ip_phone,
+ &pmx_mode_lend_wifi_phone,
+ &pmx_mode_hend_wifi_phone,
+ &pmx_mode_ata_pabx_wi2s,
+ &pmx_mode_ata_pabx_i2s,
+ &pmx_mode_caml_lcdw,
+ &pmx_mode_camu_lcd,
+ &pmx_mode_camu_wlcd,
+ &pmx_mode_caml_lcd,
+};
+
+/* fsmc_2chips_pins */
+static const unsigned fsmc_2chips_pins[] = { 1, 97 };
+static struct spear_muxreg fsmc_2chips_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_FIRDA_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux fsmc_2chips_modemux[] = {
+ {
+ .modes = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE |
+ ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE,
+ .muxregs = fsmc_2chips_muxreg,
+ .nmuxregs = ARRAY_SIZE(fsmc_2chips_muxreg),
+ },
+};
+
+static struct spear_pingroup fsmc_2chips_pingroup = {
+ .name = "fsmc_2chips_grp",
+ .pins = fsmc_2chips_pins,
+ .npins = ARRAY_SIZE(fsmc_2chips_pins),
+ .modemuxs = fsmc_2chips_modemux,
+ .nmodemuxs = ARRAY_SIZE(fsmc_2chips_modemux),
+};
+
+/* fsmc_4chips_pins */
+static const unsigned fsmc_4chips_pins[] = { 1, 2, 3, 97 };
+static struct spear_muxreg fsmc_4chips_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_FIRDA_MASK | PMX_UART0_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux fsmc_4chips_modemux[] = {
+ {
+ .modes = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE |
+ ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE,
+ .muxregs = fsmc_4chips_muxreg,
+ .nmuxregs = ARRAY_SIZE(fsmc_4chips_muxreg),
+ },
+};
+
+static struct spear_pingroup fsmc_4chips_pingroup = {
+ .name = "fsmc_4chips_grp",
+ .pins = fsmc_4chips_pins,
+ .npins = ARRAY_SIZE(fsmc_4chips_pins),
+ .modemuxs = fsmc_4chips_modemux,
+ .nmodemuxs = ARRAY_SIZE(fsmc_4chips_modemux),
+};
+
+static const char *const fsmc_grps[] = { "fsmc_2chips_grp", "fsmc_4chips_grp"
+};
+static struct spear_function fsmc_function = {
+ .name = "fsmc",
+ .groups = fsmc_grps,
+ .ngroups = ARRAY_SIZE(fsmc_grps),
+};
+
+/* clcd_lcdmode_pins */
+static const unsigned clcd_lcdmode_pins[] = { 49, 50 };
+static struct spear_muxreg clcd_lcdmode_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux clcd_lcdmode_modemux[] = {
+ {
+ .modes = HEND_IP_PHONE_MODE | HEND_WIFI_PHONE_MODE |
+ CAMU_LCD_MODE | CAML_LCD_MODE,
+ .muxregs = clcd_lcdmode_muxreg,
+ .nmuxregs = ARRAY_SIZE(clcd_lcdmode_muxreg),
+ },
+};
+
+static struct spear_pingroup clcd_lcdmode_pingroup = {
+ .name = "clcd_lcdmode_grp",
+ .pins = clcd_lcdmode_pins,
+ .npins = ARRAY_SIZE(clcd_lcdmode_pins),
+ .modemuxs = clcd_lcdmode_modemux,
+ .nmodemuxs = ARRAY_SIZE(clcd_lcdmode_modemux),
+};
+
+/* clcd_pfmode_pins */
+static const unsigned clcd_pfmode_pins[] = { 47, 48, 49, 50 };
+static struct spear_muxreg clcd_pfmode_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_TIMER_2_3_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux clcd_pfmode_modemux[] = {
+ {
+ .modes = PHOTO_FRAME_MODE,
+ .muxregs = clcd_pfmode_muxreg,
+ .nmuxregs = ARRAY_SIZE(clcd_pfmode_muxreg),
+ },
+};
+
+static struct spear_pingroup clcd_pfmode_pingroup = {
+ .name = "clcd_pfmode_grp",
+ .pins = clcd_pfmode_pins,
+ .npins = ARRAY_SIZE(clcd_pfmode_pins),
+ .modemuxs = clcd_pfmode_modemux,
+ .nmodemuxs = ARRAY_SIZE(clcd_pfmode_modemux),
+};
+
+static const char *const clcd_grps[] = { "clcd_lcdmode_grp", "clcd_pfmode_grp"
+};
+static struct spear_function clcd_function = {
+ .name = "clcd",
+ .groups = clcd_grps,
+ .ngroups = ARRAY_SIZE(clcd_grps),
+};
+
+/* tdm_pins */
+static const unsigned tdm_pins[] = { 34, 35, 36, 37, 38 };
+static struct spear_muxreg tdm_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_UART0_MODEM_MASK | PMX_SSP_CS_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux tdm_modemux[] = {
+ {
+ .modes = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
+ HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE
+ | HEND_WIFI_PHONE_MODE | ATA_PABX_WI2S_MODE
+ | ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
+ | CAMU_WLCD_MODE | CAML_LCD_MODE,
+ .muxregs = tdm_muxreg,
+ .nmuxregs = ARRAY_SIZE(tdm_muxreg),
+ },
+};
+
+static struct spear_pingroup tdm_pingroup = {
+ .name = "tdm_grp",
+ .pins = tdm_pins,
+ .npins = ARRAY_SIZE(tdm_pins),
+ .modemuxs = tdm_modemux,
+ .nmodemuxs = ARRAY_SIZE(tdm_modemux),
+};
+
+static const char *const tdm_grps[] = { "tdm_grp" };
+static struct spear_function tdm_function = {
+ .name = "tdm",
+ .groups = tdm_grps,
+ .ngroups = ARRAY_SIZE(tdm_grps),
+};
+
+/* i2c_clk_pins */
+static const unsigned i2c_clk_pins[] = { 45, 46, 47, 48 };
+static struct spear_muxreg i2c_clk_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux i2c_clk_modemux[] = {
+ {
+ .modes = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE |
+ LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE |
+ ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE | CAML_LCDW_MODE
+ | CAML_LCD_MODE,
+ .muxregs = i2c_clk_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2c_clk_muxreg),
+ },
+};
+
+static struct spear_pingroup i2c_clk_pingroup = {
+ .name = "i2c_clk_grp_grp",
+ .pins = i2c_clk_pins,
+ .npins = ARRAY_SIZE(i2c_clk_pins),
+ .modemuxs = i2c_clk_modemux,
+ .nmodemuxs = ARRAY_SIZE(i2c_clk_modemux),
+};
+
+static const char *const i2c_grps[] = { "i2c_clk_grp" };
+static struct spear_function i2c_function = {
+ .name = "i2c1",
+ .groups = i2c_grps,
+ .ngroups = ARRAY_SIZE(i2c_grps),
+};
+
+/* caml_pins */
+static const unsigned caml_pins[] = { 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 };
+static struct spear_muxreg caml_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_MII_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux caml_modemux[] = {
+ {
+ .modes = CAML_LCDW_MODE | CAML_LCD_MODE,
+ .muxregs = caml_muxreg,
+ .nmuxregs = ARRAY_SIZE(caml_muxreg),
+ },
+};
+
+static struct spear_pingroup caml_pingroup = {
+ .name = "caml_grp",
+ .pins = caml_pins,
+ .npins = ARRAY_SIZE(caml_pins),
+ .modemuxs = caml_modemux,
+ .nmodemuxs = ARRAY_SIZE(caml_modemux),
+};
+
+/* camu_pins */
+static const unsigned camu_pins[] = { 16, 17, 18, 19, 20, 21, 45, 46, 47, 48 };
+static struct spear_muxreg camu_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK | PMX_MII_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux camu_modemux[] = {
+ {
+ .modes = CAMU_LCD_MODE | CAMU_WLCD_MODE,
+ .muxregs = camu_muxreg,
+ .nmuxregs = ARRAY_SIZE(camu_muxreg),
+ },
+};
+
+static struct spear_pingroup camu_pingroup = {
+ .name = "camu_grp",
+ .pins = camu_pins,
+ .npins = ARRAY_SIZE(camu_pins),
+ .modemuxs = camu_modemux,
+ .nmodemuxs = ARRAY_SIZE(camu_modemux),
+};
+
+static const char *const cam_grps[] = { "caml_grp", "camu_grp" };
+static struct spear_function cam_function = {
+ .name = "cam",
+ .groups = cam_grps,
+ .ngroups = ARRAY_SIZE(cam_grps),
+};
+
+/* dac_pins */
+static const unsigned dac_pins[] = { 43, 44 };
+static struct spear_muxreg dac_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_TIMER_0_1_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux dac_modemux[] = {
+ {
+ .modes = ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
+ | CAMU_WLCD_MODE | CAML_LCD_MODE,
+ .muxregs = dac_muxreg,
+ .nmuxregs = ARRAY_SIZE(dac_muxreg),
+ },
+};
+
+static struct spear_pingroup dac_pingroup = {
+ .name = "dac_grp",
+ .pins = dac_pins,
+ .npins = ARRAY_SIZE(dac_pins),
+ .modemuxs = dac_modemux,
+ .nmodemuxs = ARRAY_SIZE(dac_modemux),
+};
+
+static const char *const dac_grps[] = { "dac_grp" };
+static struct spear_function dac_function = {
+ .name = "dac",
+ .groups = dac_grps,
+ .ngroups = ARRAY_SIZE(dac_grps),
+};
+
+/* i2s_pins */
+static const unsigned i2s_pins[] = { 39, 40, 41, 42 };
+static struct spear_muxreg i2s_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_UART0_MODEM_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux i2s_modemux[] = {
+ {
+ .modes = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE
+ | LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE |
+ ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
+ | CAMU_WLCD_MODE | CAML_LCD_MODE,
+ .muxregs = i2s_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2s_muxreg),
+ },
+};
+
+static struct spear_pingroup i2s_pingroup = {
+ .name = "i2s_grp",
+ .pins = i2s_pins,
+ .npins = ARRAY_SIZE(i2s_pins),
+ .modemuxs = i2s_modemux,
+ .nmodemuxs = ARRAY_SIZE(i2s_modemux),
+};
+
+static const char *const i2s_grps[] = { "i2s_grp" };
+static struct spear_function i2s_function = {
+ .name = "i2s",
+ .groups = i2s_grps,
+ .ngroups = ARRAY_SIZE(i2s_grps),
+};
+
+/* sdhci_4bit_pins */
+static const unsigned sdhci_4bit_pins[] = { 28, 29, 30, 31, 32, 33 };
+static struct spear_muxreg sdhci_4bit_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK |
+ PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
+ PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux sdhci_4bit_modemux[] = {
+ {
+ .modes = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
+ HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE |
+ HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE |
+ CAMU_WLCD_MODE | CAML_LCD_MODE | ATA_PABX_WI2S_MODE,
+ .muxregs = sdhci_4bit_muxreg,
+ .nmuxregs = ARRAY_SIZE(sdhci_4bit_muxreg),
+ },
+};
+
+static struct spear_pingroup sdhci_4bit_pingroup = {
+ .name = "sdhci_4bit_grp",
+ .pins = sdhci_4bit_pins,
+ .npins = ARRAY_SIZE(sdhci_4bit_pins),
+ .modemuxs = sdhci_4bit_modemux,
+ .nmodemuxs = ARRAY_SIZE(sdhci_4bit_modemux),
+};
+
+/* sdhci_8bit_pins */
+static const unsigned sdhci_8bit_pins[] = { 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33 };
+static struct spear_muxreg sdhci_8bit_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK |
+ PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
+ PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK | PMX_MII_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux sdhci_8bit_modemux[] = {
+ {
+ .modes = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
+ HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE |
+ HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE |
+ CAMU_WLCD_MODE | CAML_LCD_MODE,
+ .muxregs = sdhci_8bit_muxreg,
+ .nmuxregs = ARRAY_SIZE(sdhci_8bit_muxreg),
+ },
+};
+
+static struct spear_pingroup sdhci_8bit_pingroup = {
+ .name = "sdhci_8bit_grp",
+ .pins = sdhci_8bit_pins,
+ .npins = ARRAY_SIZE(sdhci_8bit_pins),
+ .modemuxs = sdhci_8bit_modemux,
+ .nmodemuxs = ARRAY_SIZE(sdhci_8bit_modemux),
+};
+
+static const char *const sdhci_grps[] = { "sdhci_4bit_grp", "sdhci_8bit_grp" };
+static struct spear_function sdhci_function = {
+ .name = "sdhci",
+ .groups = sdhci_grps,
+ .ngroups = ARRAY_SIZE(sdhci_grps),
+};
+
+/* gpio1_0_to_3_pins */
+static const unsigned gpio1_0_to_3_pins[] = { 39, 40, 41, 42 };
+static struct spear_muxreg gpio1_0_to_3_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_UART0_MODEM_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux gpio1_0_to_3_modemux[] = {
+ {
+ .modes = PHOTO_FRAME_MODE,
+ .muxregs = gpio1_0_to_3_muxreg,
+ .nmuxregs = ARRAY_SIZE(gpio1_0_to_3_muxreg),
+ },
+};
+
+static struct spear_pingroup gpio1_0_to_3_pingroup = {
+ .name = "gpio1_0_to_3_grp",
+ .pins = gpio1_0_to_3_pins,
+ .npins = ARRAY_SIZE(gpio1_0_to_3_pins),
+ .modemuxs = gpio1_0_to_3_modemux,
+ .nmodemuxs = ARRAY_SIZE(gpio1_0_to_3_modemux),
+};
+
+/* gpio1_4_to_7_pins */
+static const unsigned gpio1_4_to_7_pins[] = { 43, 44, 45, 46 };
+
+static struct spear_muxreg gpio1_4_to_7_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux gpio1_4_to_7_modemux[] = {
+ {
+ .modes = PHOTO_FRAME_MODE,
+ .muxregs = gpio1_4_to_7_muxreg,
+ .nmuxregs = ARRAY_SIZE(gpio1_4_to_7_muxreg),
+ },
+};
+
+static struct spear_pingroup gpio1_4_to_7_pingroup = {
+ .name = "gpio1_4_to_7_grp",
+ .pins = gpio1_4_to_7_pins,
+ .npins = ARRAY_SIZE(gpio1_4_to_7_pins),
+ .modemuxs = gpio1_4_to_7_modemux,
+ .nmodemuxs = ARRAY_SIZE(gpio1_4_to_7_modemux),
+};
+
+static const char *const gpio1_grps[] = { "gpio1_0_to_3_grp", "gpio1_4_to_7_grp"
+};
+static struct spear_function gpio1_function = {
+ .name = "gpio1",
+ .groups = gpio1_grps,
+ .ngroups = ARRAY_SIZE(gpio1_grps),
+};
+
+/* pingroups */
+static struct spear_pingroup *spear300_pingroups[] = {
+ SPEAR3XX_COMMON_PINGROUPS,
+ &fsmc_2chips_pingroup,
+ &fsmc_4chips_pingroup,
+ &clcd_lcdmode_pingroup,
+ &clcd_pfmode_pingroup,
+ &tdm_pingroup,
+ &i2c_clk_pingroup,
+ &caml_pingroup,
+ &camu_pingroup,
+ &dac_pingroup,
+ &i2s_pingroup,
+ &sdhci_4bit_pingroup,
+ &sdhci_8bit_pingroup,
+ &gpio1_0_to_3_pingroup,
+ &gpio1_4_to_7_pingroup,
+};
+
+/* functions */
+static struct spear_function *spear300_functions[] = {
+ SPEAR3XX_COMMON_FUNCTIONS,
+ &fsmc_function,
+ &clcd_function,
+ &tdm_function,
+ &i2c_function,
+ &cam_function,
+ &dac_function,
+ &i2s_function,
+ &sdhci_function,
+ &gpio1_function,
+};
+
+static struct of_device_id spear300_pinctrl_of_match[] __devinitdata = {
+ {
+ .compatible = "st,spear300-pinmux",
+ },
+ {},
+};
+
+static int __devinit spear300_pinctrl_probe(struct platform_device *pdev)
+{
+ int ret;
+
+ spear3xx_machdata.groups = spear300_pingroups;
+ spear3xx_machdata.ngroups = ARRAY_SIZE(spear300_pingroups);
+ spear3xx_machdata.functions = spear300_functions;
+ spear3xx_machdata.nfunctions = ARRAY_SIZE(spear300_functions);
+
+ spear3xx_machdata.modes_supported = true;
+ spear3xx_machdata.pmx_modes = spear300_pmx_modes;
+ spear3xx_machdata.npmx_modes = ARRAY_SIZE(spear300_pmx_modes);
+
+ pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG);
+
+ ret = spear_pinctrl_probe(pdev, &spear3xx_machdata);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int __devexit spear300_pinctrl_remove(struct platform_device *pdev)
+{
+ return spear_pinctrl_remove(pdev);
+}
+
+static struct platform_driver spear300_pinctrl_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = spear300_pinctrl_of_match,
+ },
+ .probe = spear300_pinctrl_probe,
+ .remove = __devexit_p(spear300_pinctrl_remove),
+};
+
+static int __init spear300_pinctrl_init(void)
+{
+ return platform_driver_register(&spear300_pinctrl_driver);
+}
+arch_initcall(spear300_pinctrl_init);
+
+static void __exit spear300_pinctrl_exit(void)
+{
+ platform_driver_unregister(&spear300_pinctrl_driver);
+}
+module_exit(spear300_pinctrl_exit);
+
+MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>");
+MODULE_DESCRIPTION("ST Microelectronics SPEAr300 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, spear300_pinctrl_of_match);
diff --git a/drivers/pinctrl/spear/pinctrl-spear310.c b/drivers/pinctrl/spear/pinctrl-spear310.c
new file mode 100644
index 000000000000..1a9707605125
--- /dev/null
+++ b/drivers/pinctrl/spear/pinctrl-spear310.c
@@ -0,0 +1,431 @@
+/*
+ * Driver for the ST Microelectronics SPEAr310 pinmux
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "pinctrl-spear3xx.h"
+
+#define DRIVER_NAME "spear310-pinmux"
+
+/* addresses */
+#define PMX_CONFIG_REG 0x08
+
+/* emi_cs_0_to_5_pins */
+static const unsigned emi_cs_0_to_5_pins[] = { 45, 46, 47, 48, 49, 50 };
+static struct spear_muxreg emi_cs_0_to_5_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux emi_cs_0_to_5_modemux[] = {
+ {
+ .muxregs = emi_cs_0_to_5_muxreg,
+ .nmuxregs = ARRAY_SIZE(emi_cs_0_to_5_muxreg),
+ },
+};
+
+static struct spear_pingroup emi_cs_0_to_5_pingroup = {
+ .name = "emi_cs_0_to_5_grp",
+ .pins = emi_cs_0_to_5_pins,
+ .npins = ARRAY_SIZE(emi_cs_0_to_5_pins),
+ .modemuxs = emi_cs_0_to_5_modemux,
+ .nmodemuxs = ARRAY_SIZE(emi_cs_0_to_5_modemux),
+};
+
+static const char *const emi_cs_0_to_5_grps[] = { "emi_cs_0_to_5_grp" };
+static struct spear_function emi_cs_0_to_5_function = {
+ .name = "emi",
+ .groups = emi_cs_0_to_5_grps,
+ .ngroups = ARRAY_SIZE(emi_cs_0_to_5_grps),
+};
+
+/* uart1_pins */
+static const unsigned uart1_pins[] = { 0, 1 };
+static struct spear_muxreg uart1_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_FIRDA_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux uart1_modemux[] = {
+ {
+ .muxregs = uart1_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart1_muxreg),
+ },
+};
+
+static struct spear_pingroup uart1_pingroup = {
+ .name = "uart1_grp",
+ .pins = uart1_pins,
+ .npins = ARRAY_SIZE(uart1_pins),
+ .modemuxs = uart1_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart1_modemux),
+};
+
+static const char *const uart1_grps[] = { "uart1_grp" };
+static struct spear_function uart1_function = {
+ .name = "uart1",
+ .groups = uart1_grps,
+ .ngroups = ARRAY_SIZE(uart1_grps),
+};
+
+/* uart2_pins */
+static const unsigned uart2_pins[] = { 43, 44 };
+static struct spear_muxreg uart2_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_TIMER_0_1_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux uart2_modemux[] = {
+ {
+ .muxregs = uart2_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart2_muxreg),
+ },
+};
+
+static struct spear_pingroup uart2_pingroup = {
+ .name = "uart2_grp",
+ .pins = uart2_pins,
+ .npins = ARRAY_SIZE(uart2_pins),
+ .modemuxs = uart2_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart2_modemux),
+};
+
+static const char *const uart2_grps[] = { "uart2_grp" };
+static struct spear_function uart2_function = {
+ .name = "uart2",
+ .groups = uart2_grps,
+ .ngroups = ARRAY_SIZE(uart2_grps),
+};
+
+/* uart3_pins */
+static const unsigned uart3_pins[] = { 37, 38 };
+static struct spear_muxreg uart3_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_UART0_MODEM_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux uart3_modemux[] = {
+ {
+ .muxregs = uart3_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart3_muxreg),
+ },
+};
+
+static struct spear_pingroup uart3_pingroup = {
+ .name = "uart3_grp",
+ .pins = uart3_pins,
+ .npins = ARRAY_SIZE(uart3_pins),
+ .modemuxs = uart3_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart3_modemux),
+};
+
+static const char *const uart3_grps[] = { "uart3_grp" };
+static struct spear_function uart3_function = {
+ .name = "uart3",
+ .groups = uart3_grps,
+ .ngroups = ARRAY_SIZE(uart3_grps),
+};
+
+/* uart4_pins */
+static const unsigned uart4_pins[] = { 39, 40 };
+static struct spear_muxreg uart4_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_UART0_MODEM_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux uart4_modemux[] = {
+ {
+ .muxregs = uart4_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart4_muxreg),
+ },
+};
+
+static struct spear_pingroup uart4_pingroup = {
+ .name = "uart4_grp",
+ .pins = uart4_pins,
+ .npins = ARRAY_SIZE(uart4_pins),
+ .modemuxs = uart4_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart4_modemux),
+};
+
+static const char *const uart4_grps[] = { "uart4_grp" };
+static struct spear_function uart4_function = {
+ .name = "uart4",
+ .groups = uart4_grps,
+ .ngroups = ARRAY_SIZE(uart4_grps),
+};
+
+/* uart5_pins */
+static const unsigned uart5_pins[] = { 41, 42 };
+static struct spear_muxreg uart5_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_UART0_MODEM_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux uart5_modemux[] = {
+ {
+ .muxregs = uart5_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart5_muxreg),
+ },
+};
+
+static struct spear_pingroup uart5_pingroup = {
+ .name = "uart5_grp",
+ .pins = uart5_pins,
+ .npins = ARRAY_SIZE(uart5_pins),
+ .modemuxs = uart5_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart5_modemux),
+};
+
+static const char *const uart5_grps[] = { "uart5_grp" };
+static struct spear_function uart5_function = {
+ .name = "uart5",
+ .groups = uart5_grps,
+ .ngroups = ARRAY_SIZE(uart5_grps),
+};
+
+/* fsmc_pins */
+static const unsigned fsmc_pins[] = { 34, 35, 36 };
+static struct spear_muxreg fsmc_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_SSP_CS_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux fsmc_modemux[] = {
+ {
+ .muxregs = fsmc_muxreg,
+ .nmuxregs = ARRAY_SIZE(fsmc_muxreg),
+ },
+};
+
+static struct spear_pingroup fsmc_pingroup = {
+ .name = "fsmc_grp",
+ .pins = fsmc_pins,
+ .npins = ARRAY_SIZE(fsmc_pins),
+ .modemuxs = fsmc_modemux,
+ .nmodemuxs = ARRAY_SIZE(fsmc_modemux),
+};
+
+static const char *const fsmc_grps[] = { "fsmc_grp" };
+static struct spear_function fsmc_function = {
+ .name = "fsmc",
+ .groups = fsmc_grps,
+ .ngroups = ARRAY_SIZE(fsmc_grps),
+};
+
+/* rs485_0_pins */
+static const unsigned rs485_0_pins[] = { 19, 20,