diff options
author | viresh kumar <viresh.kumar@st.com> | 2010-04-01 07:31:29 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-04-14 06:34:38 -0400 |
commit | 70f4c0bf9e4d067744ee453bc37c0c4adcea6e53 (patch) | |
tree | 0918b10d980c503c258687a0c65b8d0428d3a455 /arch/arm | |
parent | b77932a4d265586748f05a8c8fad7ef4174c0296 (diff) |
ARM: 6020/1: ST SPEAr: Adding gpio pad multiplexing support
GPIO Pads in spear platform are are multiplexed in various machines.
This patch adds support for this pad multiplexing.
Reviewed-by: Linus Walleij <linux.walleij@stericsson.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-spear3xx/include/mach/generic.h | 161 | ||||
-rw-r--r-- | arch/arm/mach-spear3xx/spear300.c | 358 | ||||
-rw-r--r-- | arch/arm/mach-spear3xx/spear300_evb.c | 22 | ||||
-rw-r--r-- | arch/arm/mach-spear3xx/spear310.c | 129 | ||||
-rw-r--r-- | arch/arm/mach-spear3xx/spear310_evb.c | 30 | ||||
-rw-r--r-- | arch/arm/mach-spear3xx/spear320.c | 374 | ||||
-rw-r--r-- | arch/arm/mach-spear3xx/spear320_evb.c | 27 | ||||
-rw-r--r-- | arch/arm/mach-spear3xx/spear3xx.c | 447 | ||||
-rw-r--r-- | arch/arm/plat-spear/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/plat-spear/include/plat/padmux.h | 92 | ||||
-rw-r--r-- | arch/arm/plat-spear/padmux.c | 164 |
11 files changed, 1798 insertions, 8 deletions
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h index aeea8453a9e2..af7e02c909a3 100644 --- a/arch/arm/mach-spear3xx/include/mach/generic.h +++ b/arch/arm/mach-spear3xx/include/mach/generic.h | |||
@@ -19,7 +19,9 @@ | |||
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/amba/bus.h> | 21 | #include <linux/amba/bus.h> |
22 | #include <plat/padmux.h> | ||
22 | 23 | ||
24 | /* spear3xx declarations */ | ||
23 | /* | 25 | /* |
24 | * Each GPT has 2 timer channels | 26 | * Each GPT has 2 timer channels |
25 | * Following GPT channels will be used as clock source and clockevent | 27 | * Following GPT channels will be used as clock source and clockevent |
@@ -34,25 +36,170 @@ extern struct amba_device uart_device; | |||
34 | extern struct sys_timer spear_sys_timer; | 36 | extern struct sys_timer spear_sys_timer; |
35 | 37 | ||
36 | /* Add spear3xx family function declarations here */ | 38 | /* Add spear3xx family function declarations here */ |
39 | void __init clk_init(void); | ||
37 | void __init spear3xx_map_io(void); | 40 | void __init spear3xx_map_io(void); |
38 | void __init spear3xx_init_irq(void); | 41 | void __init spear3xx_init_irq(void); |
39 | void __init spear3xx_init(void); | 42 | void __init spear3xx_init(void); |
40 | void __init spear300_init(void); | 43 | void spear_pmx_init(struct pmx_driver *pmx_driver, uint base, uint size); |
41 | void __init spear310_init(void); | ||
42 | void __init spear320_init(void); | ||
43 | void __init clk_init(void); | ||
44 | 44 | ||
45 | /* Add spear300 machine device structure declarations here */ | 45 | /* pad mux declarations */ |
46 | #define PMX_FIRDA_MASK (1 << 14) | ||
47 | #define PMX_I2C_MASK (1 << 13) | ||
48 | #define PMX_SSP_CS_MASK (1 << 12) | ||
49 | #define PMX_SSP_MASK (1 << 11) | ||
50 | #define PMX_MII_MASK (1 << 10) | ||
51 | #define PMX_GPIO_PIN0_MASK (1 << 9) | ||
52 | #define PMX_GPIO_PIN1_MASK (1 << 8) | ||
53 | #define PMX_GPIO_PIN2_MASK (1 << 7) | ||
54 | #define PMX_GPIO_PIN3_MASK (1 << 6) | ||
55 | #define PMX_GPIO_PIN4_MASK (1 << 5) | ||
56 | #define PMX_GPIO_PIN5_MASK (1 << 4) | ||
57 | #define PMX_UART0_MODEM_MASK (1 << 3) | ||
58 | #define PMX_UART0_MASK (1 << 2) | ||
59 | #define PMX_TIMER_3_4_MASK (1 << 1) | ||
60 | #define PMX_TIMER_1_2_MASK (1 << 0) | ||
61 | |||
62 | /* pad mux devices */ | ||
63 | extern struct pmx_dev pmx_firda; | ||
64 | extern struct pmx_dev pmx_i2c; | ||
65 | extern struct pmx_dev pmx_ssp_cs; | ||
66 | extern struct pmx_dev pmx_ssp; | ||
67 | extern struct pmx_dev pmx_mii; | ||
68 | extern struct pmx_dev pmx_gpio_pin0; | ||
69 | extern struct pmx_dev pmx_gpio_pin1; | ||
70 | extern struct pmx_dev pmx_gpio_pin2; | ||
71 | extern struct pmx_dev pmx_gpio_pin3; | ||
72 | extern struct pmx_dev pmx_gpio_pin4; | ||
73 | extern struct pmx_dev pmx_gpio_pin5; | ||
74 | extern struct pmx_dev pmx_uart0_modem; | ||
75 | extern struct pmx_dev pmx_uart0; | ||
76 | extern struct pmx_dev pmx_timer_3_4; | ||
77 | extern struct pmx_dev pmx_timer_1_2; | ||
78 | |||
79 | #if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320) | ||
80 | /* padmux plgpio devices */ | ||
81 | extern struct pmx_dev pmx_plgpio_0_1; | ||
82 | extern struct pmx_dev pmx_plgpio_2_3; | ||
83 | extern struct pmx_dev pmx_plgpio_4_5; | ||
84 | extern struct pmx_dev pmx_plgpio_6_9; | ||
85 | extern struct pmx_dev pmx_plgpio_10_27; | ||
86 | extern struct pmx_dev pmx_plgpio_28; | ||
87 | extern struct pmx_dev pmx_plgpio_29; | ||
88 | extern struct pmx_dev pmx_plgpio_30; | ||
89 | extern struct pmx_dev pmx_plgpio_31; | ||
90 | extern struct pmx_dev pmx_plgpio_32; | ||
91 | extern struct pmx_dev pmx_plgpio_33; | ||
92 | extern struct pmx_dev pmx_plgpio_34_36; | ||
93 | extern struct pmx_dev pmx_plgpio_37_42; | ||
94 | extern struct pmx_dev pmx_plgpio_43_44_47_48; | ||
95 | extern struct pmx_dev pmx_plgpio_45_46_49_50; | ||
96 | #endif | ||
97 | |||
98 | extern struct pmx_driver pmx_driver; | ||
99 | |||
100 | /* spear300 declarations */ | ||
46 | #ifdef CONFIG_MACH_SPEAR300 | 101 | #ifdef CONFIG_MACH_SPEAR300 |
102 | /* Add spear300 machine device structure declarations here */ | ||
47 | extern struct amba_device gpio1_device; | 103 | extern struct amba_device gpio1_device; |
104 | |||
105 | /* pad mux modes */ | ||
106 | extern struct pmx_mode nand_mode; | ||
107 | extern struct pmx_mode nor_mode; | ||
108 | extern struct pmx_mode photo_frame_mode; | ||
109 | extern struct pmx_mode lend_ip_phone_mode; | ||
110 | extern struct pmx_mode hend_ip_phone_mode; | ||
111 | extern struct pmx_mode lend_wifi_phone_mode; | ||
112 | extern struct pmx_mode hend_wifi_phone_mode; | ||
113 | extern struct pmx_mode ata_pabx_wi2s_mode; | ||
114 | extern struct pmx_mode ata_pabx_i2s_mode; | ||
115 | extern struct pmx_mode caml_lcdw_mode; | ||
116 | extern struct pmx_mode camu_lcd_mode; | ||
117 | extern struct pmx_mode camu_wlcd_mode; | ||
118 | extern struct pmx_mode caml_lcd_mode; | ||
119 | |||
120 | /* pad mux devices */ | ||
121 | extern struct pmx_dev pmx_fsmc_2_chips; | ||
122 | extern struct pmx_dev pmx_fsmc_4_chips; | ||
123 | extern struct pmx_dev pmx_keyboard; | ||
124 | extern struct pmx_dev pmx_clcd; | ||
125 | extern struct pmx_dev pmx_telecom_gpio; | ||
126 | extern struct pmx_dev pmx_telecom_tdm; | ||
127 | extern struct pmx_dev pmx_telecom_spi_cs_i2c_clk; | ||
128 | extern struct pmx_dev pmx_telecom_camera; | ||
129 | extern struct pmx_dev pmx_telecom_dac; | ||
130 | extern struct pmx_dev pmx_telecom_i2s; | ||
131 | extern struct pmx_dev pmx_telecom_boot_pins; | ||
132 | extern struct pmx_dev pmx_telecom_sdio_4bit; | ||
133 | extern struct pmx_dev pmx_telecom_sdio_8bit; | ||
134 | extern struct pmx_dev pmx_gpio1; | ||
135 | |||
136 | void spear300_pmx_init(void); | ||
137 | |||
138 | /* Add spear300 machine function declarations here */ | ||
139 | void __init spear300_init(void); | ||
140 | |||
48 | #endif /* CONFIG_MACH_SPEAR300 */ | 141 | #endif /* CONFIG_MACH_SPEAR300 */ |
49 | 142 | ||
50 | /* Add spear310 machine device structure declarations here */ | 143 | /* spear310 declarations */ |
51 | #ifdef CONFIG_MACH_SPEAR310 | 144 | #ifdef CONFIG_MACH_SPEAR310 |
145 | /* Add spear310 machine device structure declarations here */ | ||
146 | |||
147 | /* pad mux devices */ | ||
148 | extern struct pmx_dev pmx_emi_cs_0_1_4_5; | ||
149 | extern struct pmx_dev pmx_emi_cs_2_3; | ||
150 | extern struct pmx_dev pmx_uart1; | ||
151 | extern struct pmx_dev pmx_uart2; | ||
152 | extern struct pmx_dev pmx_uart3_4_5; | ||
153 | extern struct pmx_dev pmx_fsmc; | ||
154 | extern struct pmx_dev pmx_rs485_0_1; | ||
155 | extern struct pmx_dev pmx_tdm0; | ||
156 | |||
157 | void spear310_pmx_init(void); | ||
158 | |||
159 | /* Add spear310 machine function declarations here */ | ||
160 | void __init spear310_init(void); | ||
161 | |||
52 | #endif /* CONFIG_MACH_SPEAR310 */ | 162 | #endif /* CONFIG_MACH_SPEAR310 */ |
53 | 163 | ||
54 | /* Add spear320 machine device structure declarations here */ | 164 | /* spear320 declarations */ |
55 | #ifdef CONFIG_MACH_SPEAR320 | 165 | #ifdef CONFIG_MACH_SPEAR320 |
166 | /* Add spear320 machine device structure declarations here */ | ||
167 | |||
168 | /* pad mux modes */ | ||
169 | extern struct pmx_mode auto_net_smii_mode; | ||
170 | extern struct pmx_mode auto_net_mii_mode; | ||
171 | extern struct pmx_mode auto_exp_mode; | ||
172 | extern struct pmx_mode small_printers_mode; | ||
173 | |||
174 | /* pad mux devices */ | ||
175 | extern struct pmx_dev pmx_clcd; | ||
176 | extern struct pmx_dev pmx_emi; | ||
177 | extern struct pmx_dev pmx_fsmc; | ||
178 | extern struct pmx_dev pmx_spp; | ||
179 | extern struct pmx_dev pmx_sdio; | ||
180 | extern struct pmx_dev pmx_i2s; | ||
181 | extern struct pmx_dev pmx_uart1; | ||
182 | extern struct pmx_dev pmx_uart1_modem; | ||
183 | extern struct pmx_dev pmx_uart2; | ||
184 | extern struct pmx_dev pmx_touchscreen; | ||
185 | extern struct pmx_dev pmx_can; | ||
186 | extern struct pmx_dev pmx_sdio_led; | ||
187 | extern struct pmx_dev pmx_pwm0; | ||
188 | extern struct pmx_dev pmx_pwm1; | ||
189 | extern struct pmx_dev pmx_pwm2; | ||
190 | extern struct pmx_dev pmx_pwm3; | ||
191 | extern struct pmx_dev pmx_ssp1; | ||
192 | extern struct pmx_dev pmx_ssp2; | ||
193 | extern struct pmx_dev pmx_mii1; | ||
194 | extern struct pmx_dev pmx_smii0; | ||
195 | extern struct pmx_dev pmx_smii1; | ||
196 | extern struct pmx_dev pmx_i2c1; | ||
197 | |||
198 | void spear320_pmx_init(void); | ||
199 | |||
200 | /* Add spear320 machine function declarations here */ | ||
201 | void __init spear320_init(void); | ||
202 | |||
56 | #endif /* CONFIG_MACH_SPEAR320 */ | 203 | #endif /* CONFIG_MACH_SPEAR320 */ |
57 | 204 | ||
58 | #endif /* __MACH_GENERIC_H */ | 205 | #endif /* __MACH_GENERIC_H */ |
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c index 63aca8fc3ebb..66e7fcd8baf8 100644 --- a/arch/arm/mach-spear3xx/spear300.c +++ b/arch/arm/mach-spear3xx/spear300.c | |||
@@ -18,6 +18,357 @@ | |||
18 | #include <mach/generic.h> | 18 | #include <mach/generic.h> |
19 | #include <mach/spear.h> | 19 | #include <mach/spear.h> |
20 | 20 | ||
21 | /* pad multiplexing support */ | ||
22 | /* muxing registers */ | ||
23 | #define PAD_MUX_CONFIG_REG 0x00 | ||
24 | #define MODE_CONFIG_REG 0x04 | ||
25 | |||
26 | /* modes */ | ||
27 | #define NAND_MODE (1 << 0) | ||
28 | #define NOR_MODE (1 << 1) | ||
29 | #define PHOTO_FRAME_MODE (1 << 2) | ||
30 | #define LEND_IP_PHONE_MODE (1 << 3) | ||
31 | #define HEND_IP_PHONE_MODE (1 << 4) | ||
32 | #define LEND_WIFI_PHONE_MODE (1 << 5) | ||
33 | #define HEND_WIFI_PHONE_MODE (1 << 6) | ||
34 | #define ATA_PABX_WI2S_MODE (1 << 7) | ||
35 | #define ATA_PABX_I2S_MODE (1 << 8) | ||
36 | #define CAML_LCDW_MODE (1 << 9) | ||
37 | #define CAMU_LCD_MODE (1 << 10) | ||
38 | #define CAMU_WLCD_MODE (1 << 11) | ||
39 | #define CAML_LCD_MODE (1 << 12) | ||
40 | #define ALL_MODES 0x1FFF | ||
41 | |||
42 | struct pmx_mode nand_mode = { | ||
43 | .id = NAND_MODE, | ||
44 | .name = "nand mode", | ||
45 | .mask = 0x00, | ||
46 | }; | ||
47 | |||
48 | struct pmx_mode nor_mode = { | ||
49 | .id = NOR_MODE, | ||
50 | .name = "nor mode", | ||
51 | .mask = 0x01, | ||
52 | }; | ||
53 | |||
54 | struct pmx_mode photo_frame_mode = { | ||
55 | .id = PHOTO_FRAME_MODE, | ||
56 | .name = "photo frame mode", | ||
57 | .mask = 0x02, | ||
58 | }; | ||
59 | |||
60 | struct pmx_mode lend_ip_phone_mode = { | ||
61 | .id = LEND_IP_PHONE_MODE, | ||
62 | .name = "lend ip phone mode", | ||
63 | .mask = 0x03, | ||
64 | }; | ||
65 | |||
66 | struct pmx_mode hend_ip_phone_mode = { | ||
67 | .id = HEND_IP_PHONE_MODE, | ||
68 | .name = "hend ip phone mode", | ||
69 | .mask = 0x04, | ||
70 | }; | ||
71 | |||
72 | struct pmx_mode lend_wifi_phone_mode = { | ||
73 | .id = LEND_WIFI_PHONE_MODE, | ||
74 | .name = "lend wifi phone mode", | ||
75 | .mask = 0x05, | ||
76 | }; | ||
77 | |||
78 | struct pmx_mode hend_wifi_phone_mode = { | ||
79 | .id = HEND_WIFI_PHONE_MODE, | ||
80 | .name = "hend wifi phone mode", | ||
81 | .mask = 0x06, | ||
82 | }; | ||
83 | |||
84 | struct pmx_mode ata_pabx_wi2s_mode = { | ||
85 | .id = ATA_PABX_WI2S_MODE, | ||
86 | .name = "ata pabx wi2s mode", | ||
87 | .mask = 0x07, | ||
88 | }; | ||
89 | |||
90 | struct pmx_mode ata_pabx_i2s_mode = { | ||
91 | .id = ATA_PABX_I2S_MODE, | ||
92 | .name = "ata pabx i2s mode", | ||
93 | .mask = 0x08, | ||
94 | }; | ||
95 | |||
96 | struct pmx_mode caml_lcdw_mode = { | ||
97 | .id = CAML_LCDW_MODE, | ||
98 | .name = "caml lcdw mode", | ||
99 | .mask = 0x0C, | ||
100 | }; | ||
101 | |||
102 | struct pmx_mode camu_lcd_mode = { | ||
103 | .id = CAMU_LCD_MODE, | ||
104 | .name = "camu lcd mode", | ||
105 | .mask = 0x0D, | ||
106 | }; | ||
107 | |||
108 | struct pmx_mode camu_wlcd_mode = { | ||
109 | .id = CAMU_WLCD_MODE, | ||
110 | .name = "camu wlcd mode", | ||
111 | .mask = 0x0E, | ||
112 | }; | ||
113 | |||
114 | struct pmx_mode caml_lcd_mode = { | ||
115 | .id = CAML_LCD_MODE, | ||
116 | .name = "caml lcd mode", | ||
117 | .mask = 0x0F, | ||
118 | }; | ||
119 | |||
120 | /* devices */ | ||
121 | struct pmx_dev_mode pmx_fsmc_2_chips_modes[] = { | ||
122 | { | ||
123 | .ids = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE | | ||
124 | ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE, | ||
125 | .mask = PMX_FIRDA_MASK, | ||
126 | }, | ||
127 | }; | ||
128 | |||
129 | struct pmx_dev pmx_fsmc_2_chips = { | ||
130 | .name = "fsmc_2_chips", | ||
131 | .modes = pmx_fsmc_2_chips_modes, | ||
132 | .mode_count = ARRAY_SIZE(pmx_fsmc_2_chips_modes), | ||
133 | .enb_on_reset = 1, | ||
134 | }; | ||
135 | |||
136 | struct pmx_dev_mode pmx_fsmc_4_chips_modes[] = { | ||
137 | { | ||
138 | .ids = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE | | ||
139 | ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE, | ||
140 | .mask = PMX_FIRDA_MASK | PMX_UART0_MASK, | ||
141 | }, | ||
142 | }; | ||
143 | |||
144 | struct pmx_dev pmx_fsmc_4_chips = { | ||
145 | .name = "fsmc_4_chips", | ||
146 | .modes = pmx_fsmc_4_chips_modes, | ||
147 | .mode_count = ARRAY_SIZE(pmx_fsmc_4_chips_modes), | ||
148 | .enb_on_reset = 1, | ||
149 | }; | ||
150 | |||
151 | struct pmx_dev_mode pmx_keyboard_modes[] = { | ||
152 | { | ||
153 | .ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE | | ||
154 | LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE | | ||
155 | CAML_LCDW_MODE | CAMU_LCD_MODE | CAMU_WLCD_MODE | | ||
156 | CAML_LCD_MODE, | ||
157 | .mask = 0x0, | ||
158 | }, | ||
159 | }; | ||
160 | |||
161 | struct pmx_dev pmx_keyboard = { | ||
162 | .name = "keyboard", | ||
163 | .modes = pmx_keyboard_modes, | ||
164 | .mode_count = ARRAY_SIZE(pmx_keyboard_modes), | ||
165 | .enb_on_reset = 1, | ||
166 | }; | ||
167 | |||
168 | struct pmx_dev_mode pmx_clcd_modes[] = { | ||
169 | { | ||
170 | .ids = PHOTO_FRAME_MODE, | ||
171 | .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK , | ||
172 | }, { | ||
173 | .ids = HEND_IP_PHONE_MODE | HEND_WIFI_PHONE_MODE | | ||
174 | CAMU_LCD_MODE | CAML_LCD_MODE, | ||
175 | .mask = PMX_TIMER_3_4_MASK, | ||
176 | }, | ||
177 | }; | ||
178 | |||
179 | struct pmx_dev pmx_clcd = { | ||
180 | .name = "clcd", | ||
181 | .modes = pmx_clcd_modes, | ||
182 | .mode_count = ARRAY_SIZE(pmx_clcd_modes), | ||
183 | .enb_on_reset = 1, | ||
184 | }; | ||
185 | |||
186 | struct pmx_dev_mode pmx_telecom_gpio_modes[] = { | ||
187 | { | ||
188 | .ids = PHOTO_FRAME_MODE | CAMU_LCD_MODE | CAML_LCD_MODE, | ||
189 | .mask = PMX_MII_MASK, | ||
190 | }, { | ||
191 | .ids = LEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE, | ||
192 | .mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK, | ||
193 | }, { | ||
194 | .ids = ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_WLCD_MODE, | ||
195 | .mask = PMX_MII_MASK | PMX_TIMER_3_4_MASK, | ||
196 | }, { | ||
197 | .ids = HEND_IP_PHONE_MODE | HEND_WIFI_PHONE_MODE, | ||
198 | .mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK, | ||
199 | }, { | ||
200 | .ids = ATA_PABX_WI2S_MODE, | ||
201 | .mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK | ||
202 | | PMX_UART0_MODEM_MASK, | ||
203 | }, | ||
204 | }; | ||
205 | |||
206 | struct pmx_dev pmx_telecom_gpio = { | ||
207 | .name = "telecom_gpio", | ||
208 | .modes = pmx_telecom_gpio_modes, | ||
209 | .mode_count = ARRAY_SIZE(pmx_telecom_gpio_modes), | ||
210 | .enb_on_reset = 1, | ||
211 | }; | ||
212 | |||
213 | struct pmx_dev_mode pmx_telecom_tdm_modes[] = { | ||
214 | { | ||
215 | .ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE | | ||
216 | HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE | ||
217 | | HEND_WIFI_PHONE_MODE | ATA_PABX_WI2S_MODE | ||
218 | | ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE | ||
219 | | CAMU_WLCD_MODE | CAML_LCD_MODE, | ||
220 | .mask = PMX_UART0_MODEM_MASK | PMX_SSP_CS_MASK, | ||
221 | }, | ||
222 | }; | ||
223 | |||
224 | struct pmx_dev pmx_telecom_tdm = { | ||
225 | .name = "telecom_tdm", | ||
226 | .modes = pmx_telecom_tdm_modes, | ||
227 | .mode_count = ARRAY_SIZE(pmx_telecom_tdm_modes), | ||
228 | .enb_on_reset = 1, | ||
229 | }; | ||
230 | |||
231 | struct pmx_dev_mode pmx_telecom_spi_cs_i2c_clk_modes[] = { | ||
232 | { | ||
233 | .ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE | | ||
234 | LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE | ||
235 | | ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE | | ||
236 | CAML_LCDW_MODE | CAML_LCD_MODE, | ||
237 | .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK, | ||
238 | }, | ||
239 | }; | ||
240 | |||
241 | struct pmx_dev pmx_telecom_spi_cs_i2c_clk = { | ||
242 | .name = "telecom_spi_cs_i2c_clk", | ||
243 | .modes = pmx_telecom_spi_cs_i2c_clk_modes, | ||
244 | .mode_count = ARRAY_SIZE(pmx_telecom_spi_cs_i2c_clk_modes), | ||
245 | .enb_on_reset = 1, | ||
246 | }; | ||
247 | |||
248 | struct pmx_dev_mode pmx_telecom_camera_modes[] = { | ||
249 | { | ||
250 | .ids = CAML_LCDW_MODE | CAML_LCD_MODE, | ||
251 | .mask = PMX_MII_MASK, | ||
252 | }, { | ||
253 | .ids = CAMU_LCD_MODE | CAMU_WLCD_MODE, | ||
254 | .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK | PMX_MII_MASK, | ||
255 | }, | ||
256 | }; | ||
257 | |||
258 | struct pmx_dev pmx_telecom_camera = { | ||
259 | .name = "telecom_camera", | ||
260 | .modes = pmx_telecom_camera_modes, | ||
261 | .mode_count = ARRAY_SIZE(pmx_telecom_camera_modes), | ||
262 | .enb_on_reset = 1, | ||
263 | }; | ||
264 | |||
265 | struct pmx_dev_mode pmx_telecom_dac_modes[] = { | ||
266 | { | ||
267 | .ids = ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE | ||
268 | | CAMU_WLCD_MODE | CAML_LCD_MODE, | ||
269 | .mask = PMX_TIMER_1_2_MASK, | ||
270 | }, | ||
271 | }; | ||
272 | |||
273 | struct pmx_dev pmx_telecom_dac = { | ||
274 | .name = "telecom_dac", | ||
275 | .modes = pmx_telecom_dac_modes, | ||
276 | .mode_count = ARRAY_SIZE(pmx_telecom_dac_modes), | ||
277 | .enb_on_reset = 1, | ||
278 | }; | ||
279 | |||
280 | struct pmx_dev_mode pmx_telecom_i2s_modes[] = { | ||
281 | { | ||
282 | .ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE | ||
283 | | LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE | | ||
284 | ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE | ||
285 | | CAMU_WLCD_MODE | CAML_LCD_MODE, | ||
286 | .mask = PMX_UART0_MODEM_MASK, | ||
287 | }, | ||
288 | }; | ||
289 | |||
290 | struct pmx_dev pmx_telecom_i2s = { | ||
291 | .name = "telecom_i2s", | ||
292 | .modes = pmx_telecom_i2s_modes, | ||
293 | .mode_count = ARRAY_SIZE(pmx_telecom_i2s_modes), | ||
294 | .enb_on_reset = 1, | ||
295 | }; | ||
296 | |||
297 | struct pmx_dev_mode pmx_telecom_boot_pins_modes[] = { | ||
298 | { | ||
299 | .ids = NAND_MODE | NOR_MODE, | ||
300 | .mask = PMX_UART0_MODEM_MASK | PMX_TIMER_1_2_MASK | | ||
301 | PMX_TIMER_3_4_MASK, | ||
302 | }, | ||
303 | }; | ||
304 | |||
305 | struct pmx_dev pmx_telecom_boot_pins = { | ||
306 | .name = "telecom_boot_pins", | ||
307 | .modes = pmx_telecom_boot_pins_modes, | ||
308 | .mode_count = ARRAY_SIZE(pmx_telecom_boot_pins_modes), | ||
309 | .enb_on_reset = 1, | ||
310 | }; | ||
311 | |||
312 | struct pmx_dev_mode pmx_telecom_sdio_4bit_modes[] = { | ||
313 | { | ||
314 | .ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE | | ||
315 | HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE | | ||
316 | HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE | | ||
317 | CAMU_WLCD_MODE | CAML_LCD_MODE | ATA_PABX_WI2S_MODE | | ||
318 | ATA_PABX_I2S_MODE, | ||
319 | .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK | | ||
320 | PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK | | ||
321 | PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK, | ||
322 | }, | ||
323 | }; | ||
324 | |||
325 | struct pmx_dev pmx_telecom_sdio_4bit = { | ||
326 | .name = "telecom_sdio_4bit", | ||
327 | .modes = pmx_telecom_sdio_4bit_modes, | ||
328 | .mode_count = ARRAY_SIZE(pmx_telecom_sdio_4bit_modes), | ||
329 | .enb_on_reset = 1, | ||
330 | }; | ||
331 | |||
332 | struct pmx_dev_mode pmx_telecom_sdio_8bit_modes[] = { | ||
333 | { | ||
334 | .ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE | | ||
335 | HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE | | ||
336 | HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE | | ||
337 | CAMU_WLCD_MODE | CAML_LCD_MODE, | ||
338 | .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK | | ||
339 | PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK | | ||
340 | PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK | PMX_MII_MASK, | ||
341 | }, | ||
342 | }; | ||
343 | |||
344 | struct pmx_dev pmx_telecom_sdio_8bit = { | ||
345 | .name = "telecom_sdio_8bit", | ||
346 | .modes = pmx_telecom_sdio_8bit_modes, | ||
347 | .mode_count = ARRAY_SIZE(pmx_telecom_sdio_8bit_modes), | ||
348 | .enb_on_reset = 1, | ||
349 | }; | ||
350 | |||
351 | struct pmx_dev_mode pmx_gpio1_modes[] = { | ||
352 | { | ||
353 | .ids = PHOTO_FRAME_MODE, | ||
354 | .mask = PMX_UART0_MODEM_MASK | PMX_TIMER_1_2_MASK | | ||
355 | PMX_TIMER_3_4_MASK, | ||
356 | }, | ||
357 | }; | ||
358 | |||
359 | struct pmx_dev pmx_gpio1 = { | ||
360 | .name = "arm gpio1", | ||
361 | .modes = pmx_gpio1_modes, | ||
362 | .mode_count = ARRAY_SIZE(pmx_gpio1_modes), | ||
363 | .enb_on_reset = 1, | ||
364 | }; | ||
365 | |||
366 | /* pmx driver structure */ | ||
367 | struct pmx_driver pmx_driver = { | ||
368 | .mode_reg = {.offset = MODE_CONFIG_REG, .mask = 0x0000000f}, | ||
369 | .mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff}, | ||
370 | }; | ||
371 | |||
21 | /* Add spear300 specific devices here */ | 372 | /* Add spear300 specific devices here */ |
22 | /* arm gpio1 device registeration */ | 373 | /* arm gpio1 device registeration */ |
23 | static struct pl061_platform_data gpio1_plat_data = { | 374 | static struct pl061_platform_data gpio1_plat_data = { |
@@ -38,8 +389,15 @@ struct amba_device gpio1_device = { | |||
38 | .irq = {IRQ_GEN_RAS_1, NO_IRQ}, | 389 | .irq = {IRQ_GEN_RAS_1, NO_IRQ}, |
39 | }; | 390 | }; |
40 | 391 | ||
392 | /* spear300 routines */ | ||
41 | void __init spear300_init(void) | 393 | void __init spear300_init(void) |
42 | { | 394 | { |
43 | /* call spear3xx family common init function */ | 395 | /* call spear3xx family common init function */ |
44 | spear3xx_init(); | 396 | spear3xx_init(); |
45 | } | 397 | } |
398 | |||
399 | void spear300_pmx_init(void) | ||
400 | { | ||
401 | spear_pmx_init(&pmx_driver, SPEAR300_SOC_CONFIG_BASE, | ||
402 | SPEAR300_SOC_CONFIG_SIZE); | ||
403 | } | ||
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c index 1272a385c208..bb21db152a23 100644 --- a/arch/arm/mach-spear3xx/spear300_evb.c +++ b/arch/arm/mach-spear3xx/spear300_evb.c | |||
@@ -16,6 +16,22 @@ | |||
16 | #include <mach/generic.h> | 16 | #include <mach/generic.h> |
17 | #include <mach/spear.h> | 17 | #include <mach/spear.h> |
18 | 18 | ||
19 | /* padmux devices to enable */ | ||
20 | static struct pmx_dev *pmx_devs[] = { | ||
21 | /* spear3xx specific devices */ | ||
22 | &pmx_i2c, | ||
23 | &pmx_ssp_cs, | ||
24 | &pmx_ssp, | ||
25 | &pmx_mii, | ||
26 | &pmx_uart0, | ||
27 | |||
28 | /* spear300 specific devices */ | ||
29 | &pmx_fsmc_2_chips, | ||
30 | &pmx_clcd, | ||
31 | &pmx_telecom_sdio_4bit, | ||
32 | &pmx_gpio1, | ||
33 | }; | ||
34 | |||
19 | static struct amba_device *amba_devs[] __initdata = { | 35 | static struct amba_device *amba_devs[] __initdata = { |
20 | /* spear3xx specific devices */ | 36 | /* spear3xx specific devices */ |
21 | &gpio_device, | 37 | &gpio_device, |
@@ -38,6 +54,12 @@ static void __init spear300_evb_init(void) | |||
38 | /* call spear300 machine init function */ | 54 | /* call spear300 machine init function */ |
39 | spear300_init(); | 55 | spear300_init(); |
40 | 56 | ||
57 | /* padmux initialization */ | ||
58 | pmx_driver.mode = &photo_frame_mode; | ||
59 | pmx_driver.devs = pmx_devs; | ||
60 | pmx_driver.devs_count = ARRAY_SIZE(pmx_devs); | ||
61 | spear300_pmx_init(); | ||
62 | |||
41 | /* Add Platform Devices */ | 63 | /* Add Platform Devices */ |
42 | platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs)); | 64 | platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs)); |
43 | 65 | ||
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c index 6eb62f9de7ee..dd5a57282711 100644 --- a/arch/arm/mach-spear3xx/spear310.c +++ b/arch/arm/mach-spear3xx/spear310.c | |||
@@ -16,10 +16,139 @@ | |||
16 | #include <mach/generic.h> | 16 | #include <mach/generic.h> |
17 | #include <mach/spear.h> | 17 | #include <mach/spear.h> |
18 | 18 | ||
19 | /* pad multiplexing support */ | ||
20 | /* muxing registers */ | ||
21 | #define PAD_MUX_CONFIG_REG 0x08 | ||
22 | |||
23 | /* devices */ | ||
24 | struct pmx_dev_mode pmx_emi_cs_0_1_4_5_modes[] = { | ||
25 | { | ||
26 | .ids = 0x00, | ||
27 | .mask = PMX_TIMER_3_4_MASK, | ||
28 | }, | ||
29 | }; | ||
30 | |||
31 | struct pmx_dev pmx_emi_cs_0_1_4_5 = { | ||
32 | .name = "emi_cs_0_1_4_5", | ||
33 | .modes = pmx_emi_cs_0_1_4_5_modes, | ||
34 | .mode_count = ARRAY_SIZE(pmx_emi_cs_0_1_4_5_modes), | ||
35 | .enb_on_reset = 1, | ||
36 | }; | ||
37 | |||
38 | struct pmx_dev_mode pmx_emi_cs_2_3_modes[] = { | ||
39 | { | ||
40 | .ids = 0x00, | ||
41 | .mask = PMX_TIMER_1_2_MASK, | ||
42 | }, | ||
43 | }; | ||
44 | |||
45 | struct pmx_dev pmx_emi_cs_2_3 = { | ||
46 | .name = "emi_cs_2_3", | ||
47 | .modes = pmx_emi_cs_2_3_modes, | ||
48 | .mode_count = ARRAY_SIZE(pmx_emi_cs_2_3_modes), | ||
49 | .enb_on_reset = 1, | ||
50 | }; | ||
51 | |||
52 | struct pmx_dev_mode pmx_uart1_modes[] = { | ||
53 | { | ||
54 | .ids = 0x00, | ||
55 | .mask = PMX_FIRDA_MASK, | ||
56 | }, | ||
57 | }; | ||
58 | |||
59 | struct pmx_dev pmx_uart1 = { | ||
60 | .name = "uart1", | ||
61 | .modes = pmx_uart1_modes, | ||
62 | .mode_count = ARRAY_SIZE(pmx_uart1_modes), | ||
63 | .enb_on_reset = 1, | ||
64 | }; | ||
65 | |||
66 | struct pmx_dev_mode pmx_uart2_modes[] = { | ||
67 | { | ||
68 | .ids = 0x00, | ||
69 | .mask = PMX_TIMER_1_2_MASK, | ||
70 | }, | ||
71 | }; | ||
72 | |||
73 | struct pmx_dev pmx_uart2 = { | ||
74 | .name = "uart2", | ||
75 | .modes = pmx_uart2_modes, | ||
76 | .mode_count = ARRAY_SIZE(pmx_uart2_modes), | ||
77 | .enb_on_reset = 1, | ||
78 | }; | ||
79 | |||
80 | struct pmx_dev_mode pmx_uart3_4_5_modes[] = { | ||
81 | { | ||
82 | .ids = 0x00, | ||
83 | .mask = PMX_UART0_MODEM_MASK, | ||
84 | }, | ||
85 | }; | ||
86 | |||
87 | struct pmx_dev pmx_uart3_4_5 = { | ||
88 | .name = "uart3_4_5", | ||
89 | .modes = pmx_uart3_4_5_modes, | ||
90 | .mode_count = ARRAY_SIZE(pmx_uart3_4_5_modes), | ||
91 | .enb_on_reset = 1, | ||
92 | }; | ||
93 | |||
94 | struct pmx_dev_mode pmx_fsmc_modes[] = { | ||
95 | { | ||
96 | .ids = 0x00, | ||
97 | .mask = PMX_SSP_CS_MASK, | ||
98 | }, | ||
99 | }; | ||
100 | |||
101 | struct pmx_dev pmx_fsmc = { | ||
102 | .name = "fsmc", | ||
103 | .modes = pmx_fsmc_modes, | ||
104 | .mode_count = ARRAY_SIZE(pmx_fsmc_modes), | ||
105 | .enb_on_reset = 1, | ||
106 | }; | ||
107 | |||
108 | struct pmx_dev_mode pmx_rs485_0_1_modes[] = { | ||
109 | { | ||
110 | .ids = 0x00, | ||
111 | .mask = PMX_MII_MASK, | ||
112 | }, | ||
113 | }; | ||
114 | |||
115 | struct pmx_dev pmx_rs485_0_1 = { | ||
116 | .name = "rs485_0_1", | ||
117 | .modes = pmx_rs485_0_1_modes, | ||
118 | .mode_count = ARRAY_SIZE(pmx_rs485_0_1_modes), | ||
119 | .enb_on_reset = 1, | ||
120 | }; | ||
121 | |||
122 | struct pmx_dev_mode pmx_tdm0_modes[] = { | ||
123 | { | ||
124 | .ids = 0x00, | ||
125 | .mask = PMX_MII_MASK, | ||
126 | }, | ||
127 | }; | ||
128 | |||
129 | struct pmx_dev pmx_tdm0 = { | ||
130 | .name = "tdm0", | ||
131 | .modes = pmx_tdm0_modes, | ||
132 | .mode_count = ARRAY_SIZE(pmx_tdm0_modes), | ||
133 | .enb_on_reset = 1, | ||
134 | }; | ||
135 | |||
136 | /* pmx driver structure */ | ||
137 | struct pmx_driver pmx_driver = { | ||
138 | .mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff}, | ||
139 | }; | ||
140 | |||
19 | /* Add spear310 specific devices here */ | 141 | /* Add spear310 specific devices here */ |
20 | 142 | ||
143 | /* spear310 routines */ | ||
21 | void __init spear310_init(void) | 144 | void __init spear310_init(void) |
22 | { | 145 | { |
23 | /* call spear3xx family common init function */ | 146 | /* call spear3xx family common init function */ |
24 | spear3xx_init(); | 147 | spear3xx_init(); |
25 | } | 148 | } |
149 | |||
150 | void spear310_pmx_init(void) | ||
151 | { | ||
152 | spear_pmx_init(&pmx_driver, SPEAR310_SOC_CONFIG_BASE, | ||
153 | SPEAR310_SOC_CONFIG_SIZE); | ||
154 | } | ||
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c index e781b2b7f137..7facf6643199 100644 --- a/arch/arm/mach-spear3xx/spear310_evb.c +++ b/arch/arm/mach-spear3xx/spear310_evb.c | |||
@@ -16,6 +16,30 @@ | |||
16 | #include <mach/generic.h> | 16 | #include <mach/generic.h> |
17 | #include <mach/spear.h> | 17 | #include <mach/spear.h> |
18 | 18 | ||
19 | /* padmux devices to enable */ | ||
20 | static struct pmx_dev *pmx_devs[] = { | ||
21 | /* spear3xx specific devices */ | ||
22 | &pmx_i2c, | ||
23 | &pmx_ssp, | ||
24 | &pmx_gpio_pin0, | ||
25 | &pmx_gpio_pin1, | ||
26 | &pmx_gpio_pin2, | ||
27 | &pmx_gpio_pin3, | ||
28 | &pmx_gpio_pin4, | ||
29 | &pmx_gpio_pin5, | ||
30 | &pmx_uart0, | ||
31 | |||
32 | /* spear310 specific devices */ | ||
33 | &pmx_emi_cs_0_1_4_5, | ||
34 | &pmx_emi_cs_2_3, | ||
35 | &pmx_uart1, | ||
36 | &pmx_uart2, | ||
37 | &pmx_uart3_4_5, | ||
38 | &pmx_fsmc, | ||
39 | &pmx_rs485_0_1, | ||
40 | &pmx_tdm0, | ||
41 | }; | ||
42 | |||
19 | static struct amba_device *amba_devs[] __initdata = { | 43 | static struct amba_device *amba_devs[] __initdata = { |
20 | /* spear3xx specific devices */ | 44 | /* spear3xx specific devices */ |
21 | &gpio_device, | 45 | &gpio_device, |
@@ -37,6 +61,12 @@ static void __init spear310_evb_init(void) | |||
37 | /* call spear310 machine init function */ | 61 | /* call spear310 machine init function */ |
38 | spear310_init(); | 62 | spear310_init(); |
39 | 63 | ||
64 | /* padmux initialization */ | ||
65 | pmx_driver.mode = NULL; | ||
66 | pmx_driver.devs = pmx_devs; | ||
67 | pmx_driver.devs_count = ARRAY_SIZE(pmx_devs); | ||
68 | spear310_pmx_init(); | ||
69 | |||
40 | /* Add Platform Devices */ | 70 | /* Add Platform Devices */ |
41 | platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs)); | 71 | platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs)); |
42 | 72 | ||
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c index 72d45489dcb0..2cedf5eb9ec9 100644 --- a/arch/arm/mach-spear3xx/spear320.c +++ b/arch/arm/mach-spear3xx/spear320.c | |||
@@ -16,10 +16,384 @@ | |||
16 | #include <mach/generic.h> | 16 | #include <mach/generic.h> |
17 | #include <mach/spear.h> | 17 | #include <mach/spear.h> |
18 | 18 | ||
19 | /* pad multiplexing support */ | ||
20 | /* muxing registers */ | ||
21 | #define PAD_MUX_CONFIG_REG 0x0C | ||
22 | #define MODE_CONFIG_REG 0x10 | ||
23 | |||
24 | /* modes */ | ||
25 | #define AUTO_NET_SMII_MODE (1 << 0) | ||
26 | #define AUTO_NET_MII_MODE (1 << 1) | ||
27 | #define AUTO_EXP_MODE (1 << 2) | ||
28 | #define SMALL_PRINTERS_MODE (1 << 3) | ||
29 | #define ALL_MODES 0xF | ||
30 | |||
31 | struct pmx_mode auto_net_smii_mode = { | ||
32 | .id = AUTO_NET_SMII_MODE, | ||
33 | .name = "Automation Networking SMII Mode", | ||
34 | .mask = 0x00, | ||
35 | }; | ||
36 | |||
37 | struct pmx_mode auto_net_mii_mode = { | ||
38 | .id = AUTO_NET_MII_MODE, | ||
39 | .name = "Automation Networking MII Mode", | ||
40 | .mask = 0x01, | ||
41 | }; | ||
42 | |||
43 | struct pmx_mode auto_exp_mode = { | ||
44 | .id = AUTO_EXP_MODE, | ||
45 | .name = "Automation Expanded Mode", | ||
46 | .mask = 0x02, | ||
47 | }; | ||
48 | |||
49 | struct pmx_mode small_printers_mode = { | ||
50 | .id = SMALL_PRINTERS_MODE, | ||
51 | .name = "Small Printers Mode", | ||
52 | .mask = 0x03, | ||
53 | }; | ||
54 | |||
55 | /* devices */ | ||
56 | struct pmx_dev_mode pmx_clcd_modes[] = { | ||
57 | { | ||
58 | .ids = AUTO_NET_SMII_MODE, | ||
59 | .mask = 0x0, | ||
60 | }, | ||
61 | }; | ||
62 | |||
63 | struct pmx_dev pmx_clcd = { | ||
64 | .name = "clcd", | ||
65 | .modes = pmx_clcd_modes, | ||
66 | .mode_count = ARRAY_SIZE(pmx_clcd_modes), | ||
67 | .enb_on_reset = 1, | ||
68 | }; | ||
69 | |||
70 | struct pmx_dev_mode pmx_emi_modes[] = { | ||
71 | { | ||
72 | .ids = AUTO_EXP_MODE, | ||
73 | .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK, | ||
74 | }, | ||
75 | }; | ||
76 | |||
77 | struct pmx_dev pmx_emi = { | ||
78 | .name = "emi", | ||
79 | .modes = pmx_emi_modes, | ||
80 | .mode_count = ARRAY_SIZE(pmx_emi_modes), | ||
81 | .enb_on_reset = 1, | ||
82 | }; | ||
83 | |||
84 | struct pmx_dev_mode pmx_fsmc_modes[] = { | ||
85 | { | ||
86 | .ids = ALL_MODES, | ||
87 | .mask = 0x0, | ||
88 | }, | ||
89 | }; | ||
90 | |||
91 | struct pmx_dev pmx_fsmc = { | ||
92 | .name = "fsmc", | ||
93 | .modes = pmx_fsmc_modes, | ||
94 | .mode_count = ARRAY_SIZE(pmx_fsmc_modes), | ||
95 | .enb_on_reset = 1, | ||
96 | }; | ||
97 | |||
98 | struct pmx_dev_mode pmx_spp_modes[] = { | ||
99 | { | ||
100 | .ids = SMALL_PRINTERS_MODE, | ||
101 | .mask = 0x0, | ||
102 | }, | ||
103 | }; | ||
104 | |||
105 | struct pmx_dev pmx_spp = { | ||
106 | .name = "spp", | ||
107 | .modes = pmx_spp_modes, | ||
108 | .mode_count = ARRAY_SIZE(pmx_spp_modes), | ||
109 | .enb_on_reset = 1, | ||
110 | }; | ||
111 | |||
112 | struct pmx_dev_mode pmx_sdio_modes[] = { | ||
113 | { | ||
114 | .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | | ||
115 | SMALL_PRINTERS_MODE, | ||
116 | .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK, | ||
117 | }, | ||
118 | }; | ||
119 | |||
120 | struct pmx_dev pmx_sdio = { | ||
121 | .name = "sdio", | ||
122 | .modes = pmx_sdio_modes, | ||
123 | .mode_count = ARRAY_SIZE(pmx_sdio_modes), | ||
124 | .enb_on_reset = 1, | ||
125 | }; | ||
126 | |||
127 | struct pmx_dev_mode pmx_i2s_modes[] = { | ||
128 | { | ||
129 | .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE, | ||
130 | .mask = PMX_UART0_MODEM_MASK, | ||
131 | }, | ||
132 | }; | ||
133 | |||
134 | struct pmx_dev pmx_i2s = { | ||
135 | .name = "i2s", | ||
136 | .modes = pmx_i2s_modes, | ||
137 | .mode_count = ARRAY_SIZE(pmx_i2s_modes), | ||
138 | .enb_on_reset = 1, | ||
139 | }; | ||
140 | |||
141 | struct pmx_dev_mode pmx_uart1_modes[] = { | ||
142 | { | ||
143 | .ids = ALL_MODES, | ||
144 | .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK, | ||
145 | }, | ||
146 | }; | ||
147 | |||
148 | struct pmx_dev pmx_uart1 = { | ||
149 | .name = "uart1", | ||
150 | .modes = pmx_uart1_modes, | ||
151 | .mode_count = ARRAY_SIZE(pmx_uart1_modes), | ||
152 | .enb_on_reset = 1, | ||
153 | }; | ||
154 | |||
155 | struct pmx_dev_mode pmx_uart1_modem_modes[] = { | ||
156 | { | ||
157 | .ids = AUTO_EXP_MODE, | ||
158 | .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK | | ||
159 | PMX_SSP_CS_MASK, | ||
160 | }, { | ||
161 | .ids = SMALL_PRINTERS_MODE, | ||
162 | .mask = PMX_GPIO_PIN3_MASK | PMX_GPIO_PIN4_MASK | | ||
163 | PMX_GPIO_PIN5_MASK | PMX_SSP_CS_MASK, | ||
164 | }, | ||
165 | }; | ||
166 | |||
167 | struct pmx_dev pmx_uart1_modem = { | ||
168 | .name = "uart1_modem", | ||
169 | .modes = pmx_uart1_modem_modes, | ||
170 | .mode_count = ARRAY_SIZE(pmx_uart1_modem_modes), | ||
171 | .enb_on_reset = 1, | ||
172 | }; | ||
173 | |||
174 | struct pmx_dev_mode pmx_uart2_modes[] = { | ||
175 | { | ||
176 | .ids = ALL_MODES, | ||
177 | .mask = PMX_FIRDA_MASK, | ||
178 | }, | ||
179 | }; | ||
180 | |||
181 | struct pmx_dev pmx_uart2 = { | ||
182 | .name = "uart2", | ||
183 | .modes = pmx_uart2_modes, | ||
184 | .mode_count = ARRAY_SIZE(pmx_uart2_modes), | ||
185 | .enb_on_reset = 1, | ||
186 | }; | ||
187 | |||
188 | struct pmx_dev_mode pmx_touchscreen_modes[] = { | ||
189 | { | ||
190 | .ids = AUTO_NET_SMII_MODE, | ||
191 | .mask = PMX_SSP_CS_MASK, | ||
192 | }, | ||
193 | }; | ||
194 | |||
195 | struct pmx_dev pmx_touchscreen = { | ||
196 | .name = "touchscreen", | ||
197 | .modes = pmx_touchscreen_modes, | ||
198 | .mode_count = ARRAY_SIZE(pmx_touchscreen_modes), | ||
199 | .enb_on_reset = 1, | ||
200 | }; | ||
201 | |||
202 | struct pmx_dev_mode pmx_can_modes[] = { | ||
203 | { | ||
204 | .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | AUTO_EXP_MODE, | ||
205 | .mask = PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK | | ||
206 | PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK, | ||
207 | }, | ||
208 | }; | ||
209 | |||
210 | struct pmx_dev pmx_can = { | ||
211 | .name = "can", | ||
212 | .modes = pmx_can_modes, | ||
213 | .mode_count = ARRAY_SIZE(pmx_can_modes), | ||
214 | .enb_on_reset = 1, | ||
215 | }; | ||
216 | |||
217 | struct pmx_dev_mode pmx_sdio_led_modes[] = { | ||
218 | { | ||
219 | .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE, | ||
220 | .mask = PMX_SSP_CS_MASK, | ||
221 | }, | ||
222 | }; | ||
223 | |||
224 | struct pmx_dev pmx_sdio_led = { | ||
225 | .name = "sdio_led", | ||
226 | .modes = pmx_sdio_led_modes, | ||
227 | .mode_count = ARRAY_SIZE(pmx_sdio_led_modes), | ||
228 | .enb_on_reset = 1, | ||
229 | }; | ||
230 | |||
231 | struct pmx_dev_mode pmx_pwm0_modes[] = { | ||
232 | { | ||
233 | .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE, | ||
234 | .mask = PMX_UART0_MODEM_MASK, | ||
235 | }, { | ||
236 | .ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE, | ||
237 | .mask = PMX_MII_MASK, | ||
238 | }, | ||
239 | }; | ||
240 | |||
241 | struct pmx_dev pmx_pwm0 = { | ||
242 | .name = "pwm0", | ||
243 | .modes = pmx_pwm0_modes, | ||
244 | .mode_count = ARRAY_SIZE(pmx_pwm0_modes), | ||
245 | .enb_on_reset = 1, | ||
246 | }; | ||
247 | |||
248 | struct pmx_dev_mode pmx_pwm1_modes[] = { | ||
249 | { | ||
250 | .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE, | ||
251 | .mask = PMX_UART0_MODEM_MASK, | ||
252 | }, { | ||
253 | .ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE, | ||
254 | .mask = PMX_MII_MASK, | ||
255 | }, | ||
256 | }; | ||
257 | |||
258 | struct pmx_dev pmx_pwm1 = { | ||
259 | .name = "pwm1", | ||
260 | .modes = pmx_pwm1_modes, | ||
261 | .mode_count = ARRAY_SIZE(pmx_pwm1_modes), | ||
262 | .enb_on_reset = 1, | ||
263 | }; | ||
264 | |||
265 | struct pmx_dev_mode pmx_pwm2_modes[] = { | ||
266 | { | ||
267 | .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE, | ||
268 | .mask = PMX_SSP_CS_MASK, | ||
269 | }, { | ||
270 | .ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE, | ||
271 | .mask = PMX_MII_MASK, | ||
272 | }, | ||
273 | }; | ||
274 | |||
275 | struct pmx_dev pmx_pwm2 = { | ||
276 | .name = "pwm2", | ||
277 | .modes = pmx_pwm2_modes, | ||
278 | .mode_count = ARRAY_SIZE(pmx_pwm2_modes), | ||
279 | .enb_on_reset = 1, | ||
280 | }; | ||
281 | |||
282 | struct pmx_dev_mode pmx_pwm3_modes[] = { | ||
283 | { | ||
284 | .ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE | AUTO_NET_SMII_MODE, | ||
285 | .mask = PMX_MII_MASK, | ||
286 | }, | ||
287 | }; | ||
288 | |||
289 | struct pmx_dev pmx_pwm3 = { | ||
290 | .name = "pwm3", | ||
291 | .modes = pmx_pwm3_modes, | ||
292 | .mode_count = ARRAY_SIZE(pmx_pwm3_modes), | ||
293 | .enb_on_reset = 1, | ||
294 | }; | ||
295 | |||
296 | struct pmx_dev_mode pmx_ssp1_modes[] = { | ||
297 | { | ||
298 | .ids = SMALL_PRINTERS_MODE | AUTO_NET_SMII_MODE, | ||
299 | .mask = PMX_MII_MASK, | ||
300 | }, | ||
301 | }; | ||
302 | |||
303 | struct pmx_dev pmx_ssp1 = { | ||
304 | .name = "ssp1", | ||
305 | .modes = pmx_ssp1_modes, | ||
306 | .mode_count = ARRAY_SIZE(pmx_ssp1_modes), | ||
307 | .enb_on_reset = 1, | ||
308 | }; | ||
309 | |||
310 | struct pmx_dev_mode pmx_ssp2_modes[] = { | ||
311 | { | ||
312 | .ids = AUTO_NET_SMII_MODE, | ||
313 | .mask = PMX_MII_MASK, | ||
314 | }, | ||
315 | }; | ||
316 | |||
317 | struct pmx_dev pmx_ssp2 = { | ||
318 | .name = "ssp2", | ||
319 | .modes = pmx_ssp2_modes, | ||
320 | .mode_count = ARRAY_SIZE(pmx_ssp2_modes), | ||
321 | .enb_on_reset = 1, | ||
322 | }; | ||
323 | |||
324 | struct pmx_dev_mode pmx_mii1_modes[] = { | ||
325 | { | ||
326 | .ids = AUTO_NET_MII_MODE, | ||
327 | .mask = 0x0, | ||
328 | }, | ||
329 | }; | ||
330 | |||
331 | struct pmx_dev pmx_mii1 = { | ||
332 | .name = "mii1", | ||
333 | .modes = pmx_mii1_modes, | ||
334 | .mode_count = ARRAY_SIZE(pmx_mii1_modes), | ||
335 | .enb_on_reset = 1, | ||
336 | }; | ||
337 | |||
338 | struct pmx_dev_mode pmx_smii0_modes[] = { | ||
339 | { | ||
340 | .ids = AUTO_NET_SMII_MODE | AUTO_EXP_MODE | SMALL_PRINTERS_MODE, | ||
341 | .mask = PMX_MII_MASK, | ||
342 | }, | ||
343 | }; | ||
344 | |||
345 | struct pmx_dev pmx_smii0 = { | ||
346 | .name = "smii0", | ||
347 | .modes = pmx_smii0_modes, | ||
348 | .mode_count = ARRAY_SIZE(pmx_smii0_modes), | ||
349 | .enb_on_reset = 1, | ||
350 | }; | ||
351 | |||
352 | struct pmx_dev_mode pmx_smii1_modes[] = { | ||
353 | { | ||
354 | .ids = AUTO_NET_SMII_MODE | SMALL_PRINTERS_MODE, | ||
355 | .mask = PMX_MII_MASK, | ||
356 | }, | ||
357 | }; | ||
358 | |||
359 | struct pmx_dev pmx_smii1 = { | ||
360 | .name = "smii1", | ||
361 | .modes = pmx_smii1_modes, | ||
362 | .mode_count = ARRAY_SIZE(pmx_smii1_modes), | ||
363 | .enb_on_reset = 1, | ||
364 | }; | ||
365 | |||
366 | struct pmx_dev_mode pmx_i2c1_modes[] = { | ||
367 | { | ||
368 | .ids = AUTO_EXP_MODE, | ||
369 | .mask = 0x0, | ||
370 | }, | ||
371 | }; | ||
372 | |||
373 | struct pmx_dev pmx_i2c1 = { | ||
374 | .name = "i2c1", | ||
375 | .modes = pmx_i2c1_modes, | ||
376 | .mode_count = ARRAY_SIZE(pmx_i2c1_modes), | ||
377 | .enb_on_reset = 1, | ||
378 | }; | ||
379 | |||
380 | /* pmx driver structure */ | ||
381 | struct pmx_driver pmx_driver = { | ||
382 | .mode_reg = {.offset = MODE_CONFIG_REG, .mask = 0x00000007}, | ||
383 | .mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff}, | ||
384 | }; | ||
385 | |||
19 | /* Add spear320 specific devices here */ | 386 | /* Add spear320 specific devices here */ |
20 | 387 | ||
388 | /* spear320 routines */ | ||
21 | void __init spear320_init(void) | 389 | void __init spear320_init(void) |
22 | { | 390 | { |
23 | /* call spear3xx family common init function */ | 391 | /* call spear3xx family common init function */ |
24 | spear3xx_init(); | 392 | spear3xx_init(); |
25 | } | 393 | } |
394 | |||
395 | void spear320_pmx_init(void) | ||
396 | { | ||
397 | spear_pmx_init(&pmx_driver, SPEAR320_SOC_CONFIG_BASE, | ||
398 | SPEAR320_SOC_CONFIG_SIZE); | ||
399 | } | ||
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c index 85bc4d226212..62ac685a4135 100644 --- a/arch/arm/mach-spear3xx/spear320_evb.c +++ b/arch/arm/mach-spear3xx/spear320_evb.c | |||
@@ -16,6 +16,27 @@ | |||
16 | #include <mach/generic.h> | 16 | #include <mach/generic.h> |
17 | #include <mach/spear.h> | 17 | #include <mach/spear.h> |
18 | 18 | ||
19 | /* padmux devices to enable */ | ||
20 | static struct pmx_dev *pmx_devs[] = { | ||
21 | /* spear3xx specific devices */ | ||
22 | &pmx_i2c, | ||
23 | &pmx_ssp, | ||
24 | &pmx_mii, | ||
25 | &pmx_uart0, | ||
26 | |||
27 | /* spear320 specific devices */ | ||
28 | &pmx_fsmc, | ||
29 | &pmx_sdio, | ||
30 | &pmx_i2s, | ||
31 | &pmx_uart1, | ||
32 | &pmx_uart2, | ||
33 | &pmx_can, | ||
34 | &pmx_pwm0, | ||
35 | &pmx_pwm1, | ||
36 | &pmx_pwm2, | ||
37 | &pmx_mii1, | ||
38 | }; | ||
39 | |||
19 | static struct amba_device *amba_devs[] __initdata = { | 40 | static struct amba_device *amba_devs[] __initdata = { |
20 | /* spear3xx specific devices */ | 41 | /* spear3xx specific devices */ |
21 | &gpio_device, | 42 | &gpio_device, |
@@ -37,6 +58,12 @@ static void __init spear320_evb_init(void) | |||
37 | /* call spear320 machine init function */ | 58 | /* call spear320 machine init function */ |
38 | spear320_init(); | 59 | spear320_init(); |
39 | 60 | ||
61 | /* padmux initialization */ | ||
62 | pmx_driver.mode = &auto_net_mii_mode; | ||
63 | pmx_driver.devs = pmx_devs; | ||
64 | pmx_driver.devs_count = ARRAY_SIZE(pmx_devs); | ||
65 | spear320_pmx_init(); | ||
66 | |||
40 | /* Add Platform Devices */ | 67 | /* Add Platform Devices */ |
41 | platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs)); | 68 | platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs)); |
42 | 69 | ||
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c index 82ebcd30465e..e87313aeae20 100644 --- a/arch/arm/mach-spear3xx/spear3xx.c +++ b/arch/arm/mach-spear3xx/spear3xx.c | |||
@@ -99,3 +99,450 @@ void __init spear3xx_map_io(void) | |||
99 | /* This will initialize clock framework */ | 99 | /* This will initialize clock framework */ |
100 | clk_init(); | 100 | clk_init(); |
101 | } | 101 | } |
102 | |||
103 | /* pad multiplexing support */ | ||
104 | /* devices */ | ||
105 | struct pmx_dev_mode pmx_firda_modes[] = { | ||
106 | { | ||
107 | .ids = 0xffffffff, | ||
108 | .mask = PMX_FIRDA_MASK, | ||
109 | }, | ||
110 | }; | ||
111 | |||
112 | struct pmx_dev pmx_firda = { | ||
113 | .name = "firda", | ||
114 | .modes = pmx_firda_modes, | ||
115 | .mode_count = ARRAY_SIZE(pmx_firda_modes), | ||
116 | .enb_on_reset = 0, | ||
117 | }; | ||
118 | |||
119 | struct pmx_dev_mode pmx_i2c_modes[] = { | ||
120 | { | ||
121 | .ids = 0xffffffff, | ||
122 | .mask = PMX_I2C_MASK, | ||
123 | }, | ||
124 | }; | ||
125 | |||
126 | struct pmx_dev pmx_i2c = { | ||
127 | .name = "i2c", | ||
128 | .modes = pmx_i2c_modes, | ||
129 | .mode_count = ARRAY_SIZE(pmx_i2c_modes), | ||
130 | .enb_on_reset = 0, | ||
131 | }; | ||
132 | |||
133 | struct pmx_dev_mode pmx_ssp_cs_modes[] = { | ||
134 | { | ||
135 | .ids = 0xffffffff, | ||
136 | .mask = PMX_SSP_CS_MASK, | ||
137 | }, | ||
138 | }; | ||
139 | |||
140 | struct pmx_dev pmx_ssp_cs = { | ||
141 | .name = "ssp_chip_selects", | ||
142 | .modes = pmx_ssp_cs_modes, | ||
143 | .mode_count = ARRAY_SIZE(pmx_ssp_cs_modes), | ||
144 | .enb_on_reset = 0, | ||
145 | }; | ||
146 | |||
147 | struct pmx_dev_mode pmx_ssp_modes[] = { | ||
148 | { | ||
149 | .ids = 0xffffffff, | ||
150 | .mask = PMX_SSP_MASK, | ||
151 | }, | ||
152 | }; | ||
153 | |||
154 | struct pmx_dev pmx_ssp = { | ||
155 | .name = "ssp", | ||
156 | .modes = pmx_ssp_modes, | ||
157 | .mode_count = ARRAY_SIZE(pmx_ssp_modes), | ||
158 | .enb_on_reset = 0, | ||
159 | }; | ||
160 | |||
161 | struct pmx_dev_mode pmx_mii_modes[] = { | ||
162 | { | ||
163 | .ids = 0xffffffff, | ||
164 | .mask = PMX_MII_MASK, | ||
165 | }, | ||
166 | }; | ||
167 | |||
168 | struct pmx_dev pmx_mii = { | ||
169 | .name = "mii", | ||
170 | .modes = pmx_mii_modes, | ||
171 | .mode_count = ARRAY_SIZE(pmx_mii_modes), | ||
172 | .enb_on_reset = 0, | ||
173 | }; | ||
174 | |||
175 | struct pmx_dev_mode pmx_gpio_pin0_modes[] = { | ||
176 | { | ||
177 | .ids = 0xffffffff, | ||
178 | .mask = PMX_GPIO_PIN0_MASK, | ||
179 | }, | ||
180 | }; | ||
181 | |||
182 | struct pmx_dev pmx_gpio_pin0 = { | ||
183 | .name = "gpio_pin0", | ||
184 | .modes = pmx_gpio_pin0_modes, | ||
185 | .mode_count = ARRAY_SIZE(pmx_gpio_pin0_modes), | ||
186 | .enb_on_reset = 0, | ||
187 | }; | ||
188 | |||
189 | struct pmx_dev_mode pmx_gpio_pin1_modes[] = { | ||
190 | { | ||
191 | .ids = 0xffffffff, | ||
192 | .mask = PMX_GPIO_PIN1_MASK, | ||
193 | }, | ||
194 | }; | ||
195 | |||
196 | struct pmx_dev pmx_gpio_pin1 = { | ||
197 | .name = "gpio_pin1", | ||
198 | .modes = pmx_gpio_pin1_modes, | ||
199 | .mode_count = ARRAY_SIZE(pmx_gpio_pin1_modes), | ||
200 | .enb_on_reset = 0, | ||
201 | }; | ||
202 | |||
203 | struct pmx_dev_mode pmx_gpio_pin2_modes[] = { | ||
204 | { | ||
205 | .ids = 0xffffffff, | ||
206 | .mask = PMX_GPIO_PIN2_MASK, | ||
207 | }, | ||
208 | }; | ||
209 | |||
210 | struct pmx_dev pmx_gpio_pin2 = { | ||
211 | .name = "gpio_pin2", | ||
212 | .modes = pmx_gpio_pin2_modes, | ||
213 | .mode_count = ARRAY_SIZE(pmx_gpio_pin2_modes), | ||
214 | .enb_on_reset = 0, | ||
215 | }; | ||
216 | |||
217 | struct pmx_dev_mode pmx_gpio_pin3_modes[] = { | ||
218 | { | ||
219 | .ids = 0xffffffff, | ||
220 | .mask = PMX_GPIO_PIN3_MASK, | ||
221 | }, | ||
222 | }; | ||
223 | |||
224 | struct pmx_dev pmx_gpio_pin3 = { | ||
225 | .name = "gpio_pin3", | ||
226 | .modes = pmx_gpio_pin3_modes, | ||
227 | .mode_count = ARRAY_SIZE(pmx_gpio_pin3_modes), | ||
228 | .enb_on_reset = 0, | ||
229 | }; | ||
230 | |||
231 | struct pmx_dev_mode pmx_gpio_pin4_modes[] = { | ||
232 | { | ||
233 | .ids = 0xffffffff, | ||
234 | .mask = PMX_GPIO_PIN4_MASK, | ||
235 | }, | ||
236 | }; | ||
237 | |||
238 | struct pmx_dev pmx_gpio_pin4 = { | ||
239 | .name = "gpio_pin4", | ||
240 | .modes = pmx_gpio_pin4_modes, | ||
241 | .mode_count = ARRAY_SIZE(pmx_gpio_pin4_modes), | ||
242 | .enb_on_reset = 0, | ||
243 | }; | ||
244 | |||
245 | struct pmx_dev_mode pmx_gpio_pin5_modes[] = { | ||
246 | { | ||
247 | .ids = 0xffffffff, | ||
248 | .mask = PMX_GPIO_PIN5_MASK, | ||
249 | }, | ||
250 | }; | ||
251 | |||
252 | struct pmx_dev pmx_gpio_pin5 = { | ||
253 | .name = "gpio_pin5", | ||
254 | .modes = pmx_gpio_pin5_modes, | ||
255 | .mode_count = ARRAY_SIZE(pmx_gpio_pin5_modes), | ||
256 | .enb_on_reset = 0, | ||
257 | }; | ||
258 | |||
259 | struct pmx_dev_mode pmx_uart0_modem_modes[] = { | ||
260 | { | ||
261 | .ids = 0xffffffff, | ||
262 | .mask = PMX_UART0_MODEM_MASK, | ||
263 | }, | ||
264 | }; | ||
265 | |||
266 | struct pmx_dev pmx_uart0_modem = { | ||
267 | .name = "uart0_modem", | ||
268 | .modes = pmx_uart0_modem_modes, | ||
269 | .mode_count = ARRAY_SIZE(pmx_uart0_modem_modes), | ||
270 | .enb_on_reset = 0, | ||
271 | }; | ||
272 | |||
273 | struct pmx_dev_mode pmx_uart0_modes[] = { | ||
274 | { | ||
275 | .ids = 0xffffffff, | ||
276 | .mask = PMX_UART0_MASK, | ||
277 | }, | ||
278 | }; | ||
279 | |||
280 | struct pmx_dev pmx_uart0 = { | ||
281 | .name = "uart0", | ||
282 | .modes = pmx_uart0_modes, | ||
283 | .mode_count = ARRAY_SIZE(pmx_uart0_modes), | ||
284 | .enb_on_reset = 0, | ||
285 | }; | ||
286 | |||
287 | struct pmx_dev_mode pmx_timer_3_4_modes[] = { | ||
288 | { | ||
289 | .ids = 0xffffffff, | ||
290 | .mask = PMX_TIMER_3_4_MASK, | ||
291 | }, | ||
292 | }; | ||
293 | |||
294 | struct pmx_dev pmx_timer_3_4 = { | ||
295 | .name = "timer_3_4", | ||
296 | .modes = pmx_timer_3_4_modes, | ||
297 | .mode_count = ARRAY_SIZE(pmx_timer_3_4_modes), | ||
298 | .enb_on_reset = 0, | ||
299 | }; | ||
300 | |||
301 | struct pmx_dev_mode pmx_timer_1_2_modes[] = { | ||
302 | { | ||
303 | .ids = 0xffffffff, | ||
304 | .mask = PMX_TIMER_1_2_MASK, | ||
305 | }, | ||
306 | }; | ||
307 | |||
308 | struct pmx_dev pmx_timer_1_2 = { | ||
309 | .name = "timer_1_2", | ||
310 | .modes = pmx_timer_1_2_modes, | ||
311 | .mode_count = ARRAY_SIZE(pmx_timer_1_2_modes), | ||
312 | .enb_on_reset = 0, | ||
313 | }; | ||
314 | |||
315 | #if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320) | ||
316 | /* plgpios devices */ | ||
317 | struct pmx_dev_mode pmx_plgpio_0_1_modes[] = { | ||
318 | { | ||
319 | .ids = 0x00, | ||
320 | .mask = PMX_FIRDA_MASK, | ||
321 | }, | ||
322 | }; | ||
323 | |||
324 | struct pmx_dev pmx_plgpio_0_1 = { | ||
325 | .name = "plgpio 0 and 1", | ||
326 | .modes = pmx_plgpio_0_1_modes, | ||
327 | .mode_count = ARRAY_SIZE(pmx_plgpio_0_1_modes), | ||
328 | .enb_on_reset = 1, | ||
329 | }; | ||
330 | |||
331 | struct pmx_dev_mode pmx_plgpio_2_3_modes[] = { | ||
332 | { | ||
333 | .ids = 0x00, | ||
334 | .mask = PMX_UART0_MASK, | ||
335 | }, | ||
336 | }; | ||
337 | |||
338 | struct pmx_dev pmx_plgpio_2_3 = { | ||
339 | .name = "plgpio 2 and 3", | ||
340 | .modes = pmx_plgpio_2_3_modes, | ||
341 | .mode_count = ARRAY_SIZE(pmx_plgpio_2_3_modes), | ||
342 | .enb_on_reset = 1, | ||
343 | }; | ||
344 | |||
345 | struct pmx_dev_mode pmx_plgpio_4_5_modes[] = { | ||
346 | { | ||
347 | .ids = 0x00, | ||
348 | .mask = PMX_I2C_MASK, | ||
349 | }, | ||
350 | }; | ||
351 | |||
352 | struct pmx_dev pmx_plgpio_4_5 = { | ||
353 | .name = "plgpio 4 and 5", | ||
354 | .modes = pmx_plgpio_4_5_modes, | ||
355 | .mode_count = ARRAY_SIZE(pmx_plgpio_4_5_modes), | ||
356 | .enb_on_reset = 1, | ||
357 | }; | ||
358 | |||
359 | struct pmx_dev_mode pmx_plgpio_6_9_modes[] = { | ||
360 | { | ||
361 | .ids = 0x00, | ||
362 | .mask = PMX_SSP_MASK, | ||
363 | }, | ||
364 | }; | ||
365 | |||
366 | struct pmx_dev pmx_plgpio_6_9 = { | ||
367 | .name = "plgpio 6 to 9", | ||
368 | .modes = pmx_plgpio_6_9_modes, | ||
369 | .mode_count = ARRAY_SIZE(pmx_plgpio_6_9_modes), | ||
370 | .enb_on_reset = 1, | ||
371 | }; | ||
372 | |||
373 | struct pmx_dev_mode pmx_plgpio_10_27_modes[] = { | ||
374 | { | ||
375 | .ids = 0x00, | ||
376 | .mask = PMX_MII_MASK, | ||
377 | }, | ||
378 | }; | ||
379 | |||
380 | struct pmx_dev pmx_plgpio_10_27 = { | ||
381 | .name = "plgpio 10 to 27", | ||
382 | .modes = pmx_plgpio_10_27_modes, | ||
383 | .mode_count = ARRAY_SIZE(pmx_plgpio_10_27_modes), | ||
384 | .enb_on_reset = 1, | ||
385 | }; | ||
386 | |||
387 | struct pmx_dev_mode pmx_plgpio_28_modes[] = { | ||
388 | { | ||
389 | .ids = 0x00, | ||
390 | .mask = PMX_GPIO_PIN0_MASK, | ||
391 | }, | ||
392 | }; | ||
393 | |||
394 | struct pmx_dev pmx_plgpio_28 = { | ||
395 | .name = "plgpio 28", | ||
396 | .modes = pmx_plgpio_28_modes, | ||
397 | .mode_count = ARRAY_SIZE(pmx_plgpio_28_modes), | ||
398 | .enb_on_reset = 1, | ||
399 | }; | ||
400 | |||
401 | struct pmx_dev_mode pmx_plgpio_29_modes[] = { | ||
402 | { | ||
403 | .ids = 0x00, | ||
404 | .mask = PMX_GPIO_PIN1_MASK, | ||
405 | }, | ||
406 | }; | ||
407 | |||
408 | struct pmx_dev pmx_plgpio_29 = { | ||
409 | .name = "plgpio 29", | ||
410 | .modes = pmx_plgpio_29_modes, | ||
411 | .mode_count = ARRAY_SIZE(pmx_plgpio_29_modes), | ||
412 | .enb_on_reset = 1, | ||
413 | }; | ||
414 | |||
415 | struct pmx_dev_mode pmx_plgpio_30_modes[] = { | ||
416 | { | ||
417 | .ids = 0x00, | ||
418 | .mask = PMX_GPIO_PIN2_MASK, | ||
419 | }, | ||
420 | }; | ||
421 | |||
422 | struct pmx_dev pmx_plgpio_30 = { | ||
423 | .name = "plgpio 30", | ||
424 | .modes = pmx_plgpio_30_modes, | ||
425 | .mode_count = ARRAY_SIZE(pmx_plgpio_30_modes), | ||
426 | .enb_on_reset = 1, | ||
427 | }; | ||
428 | |||
429 | struct pmx_dev_mode pmx_plgpio_31_modes[] = { | ||
430 | { | ||
431 | .ids = 0x00, | ||
432 | .mask = PMX_GPIO_PIN3_MASK, | ||
433 | }, | ||
434 | }; | ||
435 | |||
436 | struct pmx_dev pmx_plgpio_31 = { | ||
437 | .name = "plgpio 31", | ||
438 | .modes = pmx_plgpio_31_modes, | ||
439 | .mode_count = ARRAY_SIZE(pmx_plgpio_31_modes), | ||
440 | .enb_on_reset = 1, | ||
441 | }; | ||
442 | |||
443 | struct pmx_dev_mode pmx_plgpio_32_modes[] = { | ||
444 | { | ||
445 | .ids = 0x00, | ||
446 | .mask = PMX_GPIO_PIN4_MASK, | ||
447 | }, | ||
448 | }; | ||
449 | |||
450 | struct pmx_dev pmx_plgpio_32 = { | ||
451 | .name = "plgpio 32", | ||
452 | .modes = pmx_plgpio_32_modes, | ||
453 | .mode_count = ARRAY_SIZE(pmx_plgpio_32_modes), | ||
454 | .enb_on_reset = 1, | ||
455 | }; | ||
456 | |||
457 | struct pmx_dev_mode pmx_plgpio_33_modes[] = { | ||
458 | { | ||
459 | .ids = 0x00, | ||
460 | .mask = PMX_GPIO_PIN5_MASK, | ||
461 | }, | ||
462 | }; | ||
463 | |||
464 | struct pmx_dev pmx_plgpio_33 = { | ||
465 | .name = "plgpio 33", | ||
466 | .modes = pmx_plgpio_33_modes, | ||
467 | .mode_count = ARRAY_SIZE(pmx_plgpio_33_modes), | ||
468 | .enb_on_reset = 1, | ||
469 | }; | ||
470 | |||
471 | struct pmx_dev_mode pmx_plgpio_34_36_modes[] = { | ||
472 | { | ||
473 | .ids = 0x00, | ||
474 | .mask = PMX_SSP_CS_MASK, | ||
475 | }, | ||
476 | }; | ||
477 | |||
478 | struct pmx_dev pmx_plgpio_34_36 = { | ||
479 | .name = "plgpio 34 to 36", | ||
480 | .modes = pmx_plgpio_34_36_modes, | ||
481 | .mode_count = ARRAY_SIZE(pmx_plgpio_34_36_modes), | ||
482 | .enb_on_reset = 1, | ||
483 | }; | ||
484 | |||
485 | struct pmx_dev_mode pmx_plgpio_37_42_modes[] = { | ||
486 | { | ||
487 | .ids = 0x00, | ||
488 | .mask = PMX_UART0_MODEM_MASK, | ||
489 | }, | ||
490 | }; | ||
491 | |||
492 | struct pmx_dev pmx_plgpio_37_42 = { | ||
493 | .name = "plgpio 37 to 42", | ||
494 | .modes = pmx_plgpio_37_42_modes, | ||
495 | .mode_count = ARRAY_SIZE(pmx_plgpio_37_42_modes), | ||
496 | .enb_on_reset = 1, | ||
497 | }; | ||
498 | |||
499 | struct pmx_dev_mode pmx_plgpio_43_44_47_48_modes[] = { | ||
500 | { | ||
501 | .ids = 0x00, | ||
502 | .mask = PMX_TIMER_1_2_MASK, | ||
503 | }, | ||
504 | }; | ||
505 | |||
506 | struct pmx_dev pmx_plgpio_43_44_47_48 = { | ||
507 | .name = "plgpio 43, 44, 47 and 48", | ||
508 | .modes = pmx_plgpio_43_44_47_48_modes, | ||
509 | .mode_count = ARRAY_SIZE(pmx_plgpio_43_44_47_48_modes), | ||
510 | .enb_on_reset = 1, | ||
511 | }; | ||
512 | |||
513 | struct pmx_dev_mode pmx_plgpio_45_46_49_50_modes[] = { | ||
514 | { | ||
515 | .ids = 0x00, | ||
516 | .mask = PMX_TIMER_3_4_MASK, | ||
517 | }, | ||
518 | }; | ||
519 | |||
520 | struct pmx_dev pmx_plgpio_45_46_49_50 = { | ||
521 | .name = "plgpio 45, 46, 49 and 50", | ||
522 | .modes = pmx_plgpio_45_46_49_50_modes, | ||
523 | .mode_count = ARRAY_SIZE(pmx_plgpio_45_46_49_50_modes), | ||
524 | .enb_on_reset = 1, | ||
525 | }; | ||
526 | |||
527 | #endif | ||
528 | |||
529 | /* spear padmux initialization function */ | ||
530 | void spear_pmx_init(struct pmx_driver *pmx_driver, uint base, uint size) | ||
531 | { | ||
532 | int ret = 0; | ||
533 | |||
534 | /* pad mux initialization */ | ||
535 | pmx_driver->base = ioremap(base, size); | ||
536 | if (!pmx_driver->base) { | ||
537 | ret = -ENOMEM; | ||
538 | goto pmx_fail; | ||
539 | } | ||
540 | |||
541 | ret = pmx_register(pmx_driver); | ||
542 | iounmap(pmx_driver->base); | ||
543 | |||
544 | pmx_fail: | ||
545 | if (ret) | ||
546 | printk(KERN_ERR "padmux: registeration failed. err no: %d\n", | ||
547 | ret); | ||
548 | } | ||
diff --git a/arch/arm/plat-spear/Makefile b/arch/arm/plat-spear/Makefile index 96f9ac3d4b81..6f4ad5e9462e 100644 --- a/arch/arm/plat-spear/Makefile +++ b/arch/arm/plat-spear/Makefile | |||
@@ -3,4 +3,4 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | # Common support | 5 | # Common support |
6 | obj-y := clock.o time.o | 6 | obj-y := clock.o padmux.o time.o |
diff --git a/arch/arm/plat-spear/include/plat/padmux.h b/arch/arm/plat-spear/include/plat/padmux.h new file mode 100644 index 000000000000..877f3adcf610 --- /dev/null +++ b/arch/arm/plat-spear/include/plat/padmux.h | |||
@@ -0,0 +1,92 @@ | |||
1 | /* | ||
2 | * arch/arm/plat-spear/include/plat/padmux.h | ||
3 | * | ||
4 | * SPEAr platform specific gpio pads muxing file | ||
5 | * | ||
6 | * Copyright (C) 2009 ST Microelectronics | ||
7 | * Viresh Kumar<viresh.kumar@st.com> | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #ifndef __PLAT_PADMUX_H | ||
15 | #define __PLAT_PADMUX_H | ||
16 | |||
17 | #include <linux/types.h> | ||
18 | |||
19 | /* | ||
20 | * struct pmx_reg: configuration structure for mode reg and mux reg | ||
21 | * | ||
22 | * offset: offset of mode reg | ||
23 | * mask: mask of mode reg | ||
24 | */ | ||
25 | struct pmx_reg { | ||
26 | u32 offset; | ||
27 | u32 mask; | ||
28 | }; | ||
29 | |||
30 | /* | ||
31 | * struct pmx_dev_mode: configuration structure every group of modes of a device | ||
32 | * | ||
33 | * ids: all modes for this configuration | ||
34 | * mask: mask for supported mode | ||
35 | */ | ||
36 | struct pmx_dev_mode { | ||
37 | u32 ids; | ||
38 | u32 mask; | ||
39 | }; | ||
40 | |||
41 | /* | ||
42 | * struct pmx_mode: mode definition structure | ||
43 | * | ||
44 | * name: mode name | ||
45 | * mask: mode mask | ||
46 | */ | ||
47 | struct pmx_mode { | ||
48 | char *name; | ||
49 | u32 id; | ||
50 | u32 mask; | ||
51 | }; | ||
52 | |||
53 | /* | ||
54 | * struct pmx_dev: device definition structure | ||
55 | * | ||
56 | * name: device name | ||
57 | * modes: device configuration array for different modes supported | ||
58 | * mode_count: size of modes array | ||
59 | * is_active: is peripheral active/enabled | ||
60 | * enb_on_reset: if 1, mask bits to be cleared in reg otherwise to be set in reg | ||
61 | */ | ||
62 | struct pmx_dev { | ||
63 | char *name; | ||
64 | struct pmx_dev_mode *modes; | ||
65 | u8 mode_count; | ||
66 | bool is_active; | ||
67 | bool enb_on_reset; | ||
68 | }; | ||
69 | |||
70 | /* | ||
71 | * struct pmx_driver: driver definition structure | ||
72 | * | ||
73 | * mode: mode to be set | ||
74 | * devs: array of pointer to pmx devices | ||
75 | * devs_count: ARRAY_SIZE of devs | ||
76 | * base: base address of soc config registers | ||
77 | * mode_reg: structure of mode config register | ||
78 | * mux_reg: structure of device mux config register | ||
79 | */ | ||
80 | struct pmx_driver { | ||
81 | struct pmx_mode *mode; | ||
82 | struct pmx_dev **devs; | ||
83 | u8 devs_count; | ||
84 | u32 *base; | ||
85 | struct pmx_reg mode_reg; | ||
86 | struct pmx_reg mux_reg; | ||
87 | }; | ||
88 | |||
89 | /* pmx functions */ | ||
90 | int pmx_register(struct pmx_driver *driver); | ||
91 | |||
92 | #endif /* __PLAT_PADMUX_H */ | ||
diff --git a/arch/arm/plat-spear/padmux.c b/arch/arm/plat-spear/padmux.c new file mode 100644 index 000000000000..d2aab3adcdeb --- /dev/null +++ b/arch/arm/plat-spear/padmux.c | |||
@@ -0,0 +1,164 @@ | |||
1 | /* | ||
2 | * arch/arm/plat-spear/include/plat/padmux.c | ||
3 | * | ||
4 | * SPEAr platform specific gpio pads muxing source file | ||
5 | * | ||
6 | * Copyright (C) 2009 ST Microelectronics | ||
7 | * Viresh Kumar<viresh.kumar@st.com> | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/err.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <plat/padmux.h> | ||
18 | |||
19 | /* | ||
20 | * struct pmx: pmx definition structure | ||
21 | * | ||
22 | * base: base address of configuration registers | ||
23 | * mode_reg: mode configurations | ||
24 | * mux_reg: muxing configurations | ||
25 | * active_mode: pointer to current active mode | ||
26 | */ | ||
27 | struct pmx { | ||
28 | u32 base; | ||
29 | struct pmx_reg mode_reg; | ||
30 | struct pmx_reg mux_reg; | ||
31 | struct pmx_mode *active_mode; | ||
32 | }; | ||
33 | |||
34 | static struct pmx *pmx; | ||
35 | |||
36 | /** | ||
37 | * pmx_mode_set - Enables an multiplexing mode | ||
38 | * @mode - pointer to pmx mode | ||
39 | * | ||
40 | * It will set mode of operation in hardware. | ||
41 | * Returns -ve on Err otherwise 0 | ||
42 | */ | ||
43 | static int pmx_mode_set(struct pmx_mode *mode) | ||
44 | { | ||
45 | u32 val; | ||
46 | |||
47 | if (!mode->name) | ||
48 | return -EFAULT; | ||
49 | |||
50 | pmx->active_mode = mode; | ||
51 | |||
52 | val = readl(pmx->base + pmx->mode_reg.offset); | ||
53 | val &= ~pmx->mode_reg.mask; | ||
54 | val |= mode->mask & pmx->mode_reg.mask; | ||
55 | writel(val, pmx->base + pmx->mode_reg.offset); | ||
56 | |||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | /** | ||
61 | * pmx_devs_enable - Enables list of devices | ||
62 | * @devs - pointer to pmx device array | ||
63 | * @count - number of devices to enable | ||
64 | * | ||
65 | * It will enable pads for all required peripherals once and only once. | ||
66 | * If peripheral is not supported by current mode then request is rejected. | ||
67 | * Conflicts between peripherals are not handled and peripherals will be | ||
68 | * enabled in the order they are present in pmx_dev array. | ||
69 | * In case of conflicts last peripheral enalbed will be present. | ||
70 | * Returns -ve on Err otherwise 0 | ||
71 | */ | ||
72 | static int pmx_devs_enable(struct pmx_dev **devs, u8 count) | ||
73 | { | ||
74 | u32 val, i, mask; | ||
75 | |||
76 | if (!count) | ||
77 | return -EINVAL; | ||
78 | |||
79 | val = readl(pmx->base + pmx->mux_reg.offset); | ||
80 | for (i = 0; i < count; i++) { | ||
81 | u8 j = 0; | ||
82 | |||
83 | if (!devs[i]->name || !devs[i]->modes) { | ||
84 | printk(KERN_ERR "padmux: dev name or modes is null\n"); | ||
85 | continue; | ||
86 | } | ||
87 | /* check if peripheral exists in active mode */ | ||
88 | if (pmx->active_mode) { | ||
89 | bool found = false; | ||
90 | for (j = 0; j < devs[i]->mode_count; j++) { | ||
91 | if (devs[i]->modes[j].ids & | ||
92 | pmx->active_mode->id) { | ||
93 | found = true; | ||
94 | break; | ||
95 | } | ||
96 | } | ||
97 | if (found == false) { | ||
98 | printk(KERN_ERR "%s device not available in %s"\ | ||
99 | "mode\n", devs[i]->name, | ||
100 | pmx->active_mode->name); | ||
101 | continue; | ||
102 | } | ||
103 | } | ||
104 | |||
105 | /* enable peripheral */ | ||
106 | mask = devs[i]->modes[j].mask & pmx->mux_reg.mask; | ||
107 | if (devs[i]->enb_on_reset) | ||
108 | val &= ~mask; | ||
109 | else | ||
110 | val |= mask; | ||
111 | |||
112 | devs[i]->is_active = true; | ||
113 | } | ||
114 | writel(val, pmx->base + pmx->mux_reg.offset); | ||
115 | kfree(pmx); | ||
116 | |||
117 | /* this will ensure that multiplexing can't be changed now */ | ||
118 | pmx = (struct pmx *)-1; | ||
119 | |||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | /** | ||
124 | * pmx_register - registers a platform requesting pad mux feature | ||
125 | * @driver - pointer to driver structure containing driver specific parameters | ||
126 | * | ||
127 | * Also this must be called only once. This will allocate memory for pmx | ||
128 | * structure, will call pmx_mode_set, will call pmx_devs_enable. | ||
129 | * Returns -ve on Err otherwise 0 | ||
130 | */ | ||
131 | int pmx_register(struct pmx_driver *driver) | ||
132 | { | ||
133 | int ret = 0; | ||
134 | |||
135 | if (pmx) | ||
136 | return -EPERM; | ||
137 | if (!driver->base || !driver->devs) | ||
138 | return -EFAULT; | ||
139 | |||
140 | pmx = kzalloc(sizeof(*pmx), GFP_KERNEL); | ||
141 | if (!pmx) | ||
142 | return -ENOMEM; | ||
143 | |||
144 | pmx->base = (u32)driver->base; | ||
145 | pmx->mode_reg.offset = driver->mode_reg.offset; | ||
146 | pmx->mode_reg.mask = driver->mode_reg.mask; | ||
147 | pmx->mux_reg.offset = driver->mux_reg.offset; | ||
148 | pmx->mux_reg.mask = driver->mux_reg.mask; | ||
149 | |||
150 | /* choose mode to enable */ | ||
151 | if (driver->mode) { | ||
152 | ret = pmx_mode_set(driver->mode); | ||
153 | if (ret) | ||
154 | goto pmx_fail; | ||
155 | } | ||
156 | ret = pmx_devs_enable(driver->devs, driver->devs_count); | ||
157 | if (ret) | ||
158 | goto pmx_fail; | ||
159 | |||
160 | return 0; | ||
161 | |||
162 | pmx_fail: | ||
163 | return ret; | ||
164 | } | ||