aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorviresh kumar <viresh.kumar@st.com>2010-04-01 07:31:29 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-04-14 06:34:38 -0400
commit70f4c0bf9e4d067744ee453bc37c0c4adcea6e53 (patch)
tree0918b10d980c503c258687a0c65b8d0428d3a455 /arch/arm
parentb77932a4d265586748f05a8c8fad7ef4174c0296 (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.h161
-rw-r--r--arch/arm/mach-spear3xx/spear300.c358
-rw-r--r--arch/arm/mach-spear3xx/spear300_evb.c22
-rw-r--r--arch/arm/mach-spear3xx/spear310.c129
-rw-r--r--arch/arm/mach-spear3xx/spear310_evb.c30
-rw-r--r--arch/arm/mach-spear3xx/spear320.c374
-rw-r--r--arch/arm/mach-spear3xx/spear320_evb.c27
-rw-r--r--arch/arm/mach-spear3xx/spear3xx.c447
-rw-r--r--arch/arm/plat-spear/Makefile2
-rw-r--r--arch/arm/plat-spear/include/plat/padmux.h92
-rw-r--r--arch/arm/plat-spear/padmux.c164
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;
34extern struct sys_timer spear_sys_timer; 36extern struct sys_timer spear_sys_timer;
35 37
36/* Add spear3xx family function declarations here */ 38/* Add spear3xx family function declarations here */
39void __init clk_init(void);
37void __init spear3xx_map_io(void); 40void __init spear3xx_map_io(void);
38void __init spear3xx_init_irq(void); 41void __init spear3xx_init_irq(void);
39void __init spear3xx_init(void); 42void __init spear3xx_init(void);
40void __init spear300_init(void); 43void spear_pmx_init(struct pmx_driver *pmx_driver, uint base, uint size);
41void __init spear310_init(void);
42void __init spear320_init(void);
43void __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 */
63extern struct pmx_dev pmx_firda;
64extern struct pmx_dev pmx_i2c;
65extern struct pmx_dev pmx_ssp_cs;
66extern struct pmx_dev pmx_ssp;
67extern struct pmx_dev pmx_mii;
68extern struct pmx_dev pmx_gpio_pin0;
69extern struct pmx_dev pmx_gpio_pin1;
70extern struct pmx_dev pmx_gpio_pin2;
71extern struct pmx_dev pmx_gpio_pin3;
72extern struct pmx_dev pmx_gpio_pin4;
73extern struct pmx_dev pmx_gpio_pin5;
74extern struct pmx_dev pmx_uart0_modem;
75extern struct pmx_dev pmx_uart0;
76extern struct pmx_dev pmx_timer_3_4;
77extern struct pmx_dev pmx_timer_1_2;
78
79#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
80/* padmux plgpio devices */
81extern struct pmx_dev pmx_plgpio_0_1;
82extern struct pmx_dev pmx_plgpio_2_3;
83extern struct pmx_dev pmx_plgpio_4_5;
84extern struct pmx_dev pmx_plgpio_6_9;
85extern struct pmx_dev pmx_plgpio_10_27;
86extern struct pmx_dev pmx_plgpio_28;
87extern struct pmx_dev pmx_plgpio_29;
88extern struct pmx_dev pmx_plgpio_30;
89extern struct pmx_dev pmx_plgpio_31;
90extern struct pmx_dev pmx_plgpio_32;
91extern struct pmx_dev pmx_plgpio_33;
92extern struct pmx_dev pmx_plgpio_34_36;
93extern struct pmx_dev pmx_plgpio_37_42;
94extern struct pmx_dev pmx_plgpio_43_44_47_48;
95extern struct pmx_dev pmx_plgpio_45_46_49_50;
96#endif
97
98extern 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 */
47extern struct amba_device gpio1_device; 103extern struct amba_device gpio1_device;
104
105/* pad mux modes */
106extern struct pmx_mode nand_mode;
107extern struct pmx_mode nor_mode;
108extern struct pmx_mode photo_frame_mode;
109extern struct pmx_mode lend_ip_phone_mode;
110extern struct pmx_mode hend_ip_phone_mode;
111extern struct pmx_mode lend_wifi_phone_mode;
112extern struct pmx_mode hend_wifi_phone_mode;
113extern struct pmx_mode ata_pabx_wi2s_mode;
114extern struct pmx_mode ata_pabx_i2s_mode;
115extern struct pmx_mode caml_lcdw_mode;
116extern struct pmx_mode camu_lcd_mode;
117extern struct pmx_mode camu_wlcd_mode;
118extern struct pmx_mode caml_lcd_mode;
119
120/* pad mux devices */
121extern struct pmx_dev pmx_fsmc_2_chips;
122extern struct pmx_dev pmx_fsmc_4_chips;
123extern struct pmx_dev pmx_keyboard;
124extern struct pmx_dev pmx_clcd;
125extern struct pmx_dev pmx_telecom_gpio;
126extern struct pmx_dev pmx_telecom_tdm;
127extern struct pmx_dev pmx_telecom_spi_cs_i2c_clk;
128extern struct pmx_dev pmx_telecom_camera;
129extern struct pmx_dev pmx_telecom_dac;
130extern struct pmx_dev pmx_telecom_i2s;
131extern struct pmx_dev pmx_telecom_boot_pins;
132extern struct pmx_dev pmx_telecom_sdio_4bit;
133extern struct pmx_dev pmx_telecom_sdio_8bit;
134extern struct pmx_dev pmx_gpio1;
135
136void spear300_pmx_init(void);
137
138/* Add spear300 machine function declarations here */
139void __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 */
148extern struct pmx_dev pmx_emi_cs_0_1_4_5;
149extern struct pmx_dev pmx_emi_cs_2_3;
150extern struct pmx_dev pmx_uart1;
151extern struct pmx_dev pmx_uart2;
152extern struct pmx_dev pmx_uart3_4_5;
153extern struct pmx_dev pmx_fsmc;
154extern struct pmx_dev pmx_rs485_0_1;
155extern struct pmx_dev pmx_tdm0;
156
157void spear310_pmx_init(void);
158
159/* Add spear310 machine function declarations here */
160void __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 */
169extern struct pmx_mode auto_net_smii_mode;
170extern struct pmx_mode auto_net_mii_mode;
171extern struct pmx_mode auto_exp_mode;
172extern struct pmx_mode small_printers_mode;
173
174/* pad mux devices */
175extern struct pmx_dev pmx_clcd;
176extern struct pmx_dev pmx_emi;
177extern struct pmx_dev pmx_fsmc;
178extern struct pmx_dev pmx_spp;
179extern struct pmx_dev pmx_sdio;
180extern struct pmx_dev pmx_i2s;
181extern struct pmx_dev pmx_uart1;
182extern struct pmx_dev pmx_uart1_modem;
183extern struct pmx_dev pmx_uart2;
184extern struct pmx_dev pmx_touchscreen;
185extern struct pmx_dev pmx_can;
186extern struct pmx_dev pmx_sdio_led;
187extern struct pmx_dev pmx_pwm0;
188extern struct pmx_dev pmx_pwm1;
189extern struct pmx_dev pmx_pwm2;
190extern struct pmx_dev pmx_pwm3;
191extern struct pmx_dev pmx_ssp1;
192extern struct pmx_dev pmx_ssp2;
193extern struct pmx_dev pmx_mii1;
194extern struct pmx_dev pmx_smii0;
195extern struct pmx_dev pmx_smii1;
196extern struct pmx_dev pmx_i2c1;
197
198void spear320_pmx_init(void);
199
200/* Add spear320 machine function declarations here */
201void __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
42struct pmx_mode nand_mode = {
43 .id = NAND_MODE,
44 .name = "nand mode",
45 .mask = 0x00,
46};
47
48struct pmx_mode nor_mode = {
49 .id = NOR_MODE,
50 .name = "nor mode",
51 .mask = 0x01,
52};
53
54struct pmx_mode photo_frame_mode = {
55 .id = PHOTO_FRAME_MODE,
56 .name = "photo frame mode",
57 .mask = 0x02,
58};
59
60struct pmx_mode lend_ip_phone_mode = {
61 .id = LEND_IP_PHONE_MODE,
62 .name = "lend ip phone mode",
63 .mask = 0x03,
64};
65
66struct pmx_mode hend_ip_phone_mode = {
67 .id = HEND_IP_PHONE_MODE,
68 .name = "hend ip phone mode",
69 .mask = 0x04,
70};
71
72struct pmx_mode lend_wifi_phone_mode = {
73 .id = LEND_WIFI_PHONE_MODE,
74 .name = "lend wifi phone mode",
75 .mask = 0x05,
76};
77
78struct pmx_mode hend_wifi_phone_mode = {
79 .id = HEND_WIFI_PHONE_MODE,
80 .name = "hend wifi phone mode",
81 .mask = 0x06,
82};
83
84struct pmx_mode ata_pabx_wi2s_mode = {
85 .id = ATA_PABX_WI2S_MODE,
86 .name = "ata pabx wi2s mode",
87 .mask = 0x07,
88};
89
90struct pmx_mode ata_pabx_i2s_mode = {
91 .id = ATA_PABX_I2S_MODE,
92 .name = "ata pabx i2s mode",
93 .mask = 0x08,
94};
95
96struct pmx_mode caml_lcdw_mode = {
97 .id = CAML_LCDW_MODE,
98 .name = "caml lcdw mode",
99 .mask = 0x0C,
100};
101
102struct pmx_mode camu_lcd_mode = {
103 .id = CAMU_LCD_MODE,
104 .name = "camu lcd mode",
105 .mask = 0x0D,
106};
107
108struct pmx_mode camu_wlcd_mode = {
109 .id = CAMU_WLCD_MODE,
110 .name = "camu wlcd mode",
111 .mask = 0x0E,
112};
113
114struct pmx_mode caml_lcd_mode = {
115 .id = CAML_LCD_MODE,
116 .name = "caml lcd mode",
117 .mask = 0x0F,
118};
119
120/* devices */
121struct 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
129struct 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
136struct 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
144struct 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
151struct 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
161struct 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
168struct 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
179struct 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
186struct 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
206struct 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
213struct 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
224struct 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
231struct 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
241struct 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
248struct 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
258struct 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
265struct 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
273struct 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
280struct 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
290struct 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
297struct 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
305struct 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
312struct 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
325struct 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
332struct 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
344struct 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
351struct 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
359struct 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 */
367struct 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 */
23static struct pl061_platform_data gpio1_plat_data = { 374static 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 */
41void __init spear300_init(void) 393void __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
399void 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 */
20static 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
19static struct amba_device *amba_devs[] __initdata = { 35static 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 */
24struct 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
31struct 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
38struct pmx_dev_mode pmx_emi_cs_2_3_modes[] = {
39 {
40 .ids = 0x00,
41 .mask = PMX_TIMER_1_2_MASK,
42 },
43};
44
45struct 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
52struct pmx_dev_mode pmx_uart1_modes[] = {
53 {
54 .ids = 0x00,
55 .mask = PMX_FIRDA_MASK,
56 },
57};
58
59struct 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
66struct pmx_dev_mode pmx_uart2_modes[] = {
67 {
68 .ids = 0x00,
69 .mask = PMX_TIMER_1_2_MASK,
70 },
71};
72
73struct 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
80struct pmx_dev_mode pmx_uart3_4_5_modes[] = {
81 {
82 .ids = 0x00,
83 .mask = PMX_UART0_MODEM_MASK,
84 },
85};
86
87struct 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
94struct pmx_dev_mode pmx_fsmc_modes[] = {
95 {
96 .ids = 0x00,
97 .mask = PMX_SSP_CS_MASK,
98 },
99};
100
101struct 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
108struct pmx_dev_mode pmx_rs485_0_1_modes[] = {
109 {
110 .ids = 0x00,
111 .mask = PMX_MII_MASK,
112 },
113};
114
115struct 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
122struct pmx_dev_mode pmx_tdm0_modes[] = {
123 {
124 .ids = 0x00,
125 .mask = PMX_MII_MASK,
126 },
127};
128
129struct 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 */
137struct 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 */
21void __init spear310_init(void) 144void __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
150void 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 */
20static 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
19static struct amba_device *amba_devs[] __initdata = { 43static 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
31struct pmx_mode auto_net_smii_mode = {
32 .id = AUTO_NET_SMII_MODE,
33 .name = "Automation Networking SMII Mode",
34 .mask = 0x00,
35};
36
37struct pmx_mode auto_net_mii_mode = {
38 .id = AUTO_NET_MII_MODE,
39 .name = "Automation Networking MII Mode",
40 .mask = 0x01,
41};
42
43struct pmx_mode auto_exp_mode = {
44 .id = AUTO_EXP_MODE,
45 .name = "Automation Expanded Mode",
46 .mask = 0x02,
47};
48
49struct pmx_mode small_printers_mode = {
50 .id = SMALL_PRINTERS_MODE,
51 .name = "Small Printers Mode",
52 .mask = 0x03,
53};
54
55/* devices */
56struct pmx_dev_mode pmx_clcd_modes[] = {
57 {
58 .ids = AUTO_NET_SMII_MODE,
59 .mask = 0x0,
60 },
61};
62
63struct 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
70struct 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
77struct 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
84struct pmx_dev_mode pmx_fsmc_modes[] = {
85 {
86 .ids = ALL_MODES,
87 .mask = 0x0,
88 },
89};
90
91struct 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
98struct pmx_dev_mode pmx_spp_modes[] = {
99 {
100 .ids = SMALL_PRINTERS_MODE,
101 .mask = 0x0,
102 },
103};
104
105struct 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
112struct 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
120struct 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
127struct 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
134struct 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
141struct pmx_dev_mode pmx_uart1_modes[] = {
142 {
143 .ids = ALL_MODES,
144 .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK,
145 },
146};
147
148struct 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
155struct 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
167struct 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
174struct pmx_dev_mode pmx_uart2_modes[] = {
175 {
176 .ids = ALL_MODES,
177 .mask = PMX_FIRDA_MASK,
178 },
179};
180
181struct 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
188struct pmx_dev_mode pmx_touchscreen_modes[] = {
189 {
190 .ids = AUTO_NET_SMII_MODE,
191 .mask = PMX_SSP_CS_MASK,
192 },
193};
194
195struct 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
202struct 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
210struct 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
217struct 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
224struct 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
231struct 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
241struct 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
248struct 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
258struct 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
265struct 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
275struct 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
282struct 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
289struct 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
296struct pmx_dev_mode pmx_ssp1_modes[] = {
297 {
298 .ids = SMALL_PRINTERS_MODE | AUTO_NET_SMII_MODE,
299 .mask = PMX_MII_MASK,
300 },
301};
302
303struct 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
310struct pmx_dev_mode pmx_ssp2_modes[] = {
311 {
312 .ids = AUTO_NET_SMII_MODE,
313 .mask = PMX_MII_MASK,
314 },
315};
316
317struct 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
324struct pmx_dev_mode pmx_mii1_modes[] = {
325 {
326 .ids = AUTO_NET_MII_MODE,
327 .mask = 0x0,
328 },
329};
330
331struct 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
338struct 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
345struct 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
352struct pmx_dev_mode pmx_smii1_modes[] = {
353 {
354 .ids = AUTO_NET_SMII_MODE | SMALL_PRINTERS_MODE,
355 .mask = PMX_MII_MASK,
356 },
357};
358
359struct 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
366struct pmx_dev_mode pmx_i2c1_modes[] = {
367 {
368 .ids = AUTO_EXP_MODE,
369 .mask = 0x0,
370 },
371};
372
373struct 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 */
381struct 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 */
21void __init spear320_init(void) 389void __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
395void 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 */
20static 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
19static struct amba_device *amba_devs[] __initdata = { 40static 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 */
105struct pmx_dev_mode pmx_firda_modes[] = {
106 {
107 .ids = 0xffffffff,
108 .mask = PMX_FIRDA_MASK,
109 },
110};
111
112struct 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
119struct pmx_dev_mode pmx_i2c_modes[] = {
120 {
121 .ids = 0xffffffff,
122 .mask = PMX_I2C_MASK,
123 },
124};
125
126struct 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
133struct pmx_dev_mode pmx_ssp_cs_modes[] = {
134 {
135 .ids = 0xffffffff,
136 .mask = PMX_SSP_CS_MASK,
137 },
138};
139
140struct 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
147struct pmx_dev_mode pmx_ssp_modes[] = {
148 {
149 .ids = 0xffffffff,
150 .mask = PMX_SSP_MASK,
151 },
152};
153
154struct 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
161struct pmx_dev_mode pmx_mii_modes[] = {
162 {
163 .ids = 0xffffffff,
164 .mask = PMX_MII_MASK,
165 },
166};
167
168struct 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
175struct pmx_dev_mode pmx_gpio_pin0_modes[] = {
176 {
177 .ids = 0xffffffff,
178 .mask = PMX_GPIO_PIN0_MASK,
179 },
180};
181
182struct 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
189struct pmx_dev_mode pmx_gpio_pin1_modes[] = {
190 {
191 .ids = 0xffffffff,
192 .mask = PMX_GPIO_PIN1_MASK,
193 },
194};
195
196struct 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
203struct pmx_dev_mode pmx_gpio_pin2_modes[] = {
204 {
205 .ids = 0xffffffff,
206 .mask = PMX_GPIO_PIN2_MASK,
207 },
208};
209
210struct 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
217struct pmx_dev_mode pmx_gpio_pin3_modes[] = {
218 {
219 .ids = 0xffffffff,
220 .mask = PMX_GPIO_PIN3_MASK,
221 },
222};
223
224struct 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
231struct pmx_dev_mode pmx_gpio_pin4_modes[] = {
232 {
233 .ids = 0xffffffff,
234 .mask = PMX_GPIO_PIN4_MASK,
235 },
236};
237
238struct 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
245struct pmx_dev_mode pmx_gpio_pin5_modes[] = {
246 {
247 .ids = 0xffffffff,
248 .mask = PMX_GPIO_PIN5_MASK,
249 },
250};
251
252struct 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
259struct pmx_dev_mode pmx_uart0_modem_modes[] = {
260 {
261 .ids = 0xffffffff,
262 .mask = PMX_UART0_MODEM_MASK,
263 },
264};
265
266struct 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
273struct pmx_dev_mode pmx_uart0_modes[] = {
274 {
275 .ids = 0xffffffff,
276 .mask = PMX_UART0_MASK,
277 },
278};
279
280struct 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
287struct pmx_dev_mode pmx_timer_3_4_modes[] = {
288 {
289 .ids = 0xffffffff,
290 .mask = PMX_TIMER_3_4_MASK,
291 },
292};
293
294struct 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
301struct pmx_dev_mode pmx_timer_1_2_modes[] = {
302 {
303 .ids = 0xffffffff,
304 .mask = PMX_TIMER_1_2_MASK,
305 },
306};
307
308struct 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 */
317struct pmx_dev_mode pmx_plgpio_0_1_modes[] = {
318 {
319 .ids = 0x00,
320 .mask = PMX_FIRDA_MASK,
321 },
322};
323
324struct 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
331struct pmx_dev_mode pmx_plgpio_2_3_modes[] = {
332 {
333 .ids = 0x00,
334 .mask = PMX_UART0_MASK,
335 },
336};
337
338struct 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
345struct pmx_dev_mode pmx_plgpio_4_5_modes[] = {
346 {
347 .ids = 0x00,
348 .mask = PMX_I2C_MASK,
349 },
350};
351
352struct 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
359struct pmx_dev_mode pmx_plgpio_6_9_modes[] = {
360 {
361 .ids = 0x00,
362 .mask = PMX_SSP_MASK,
363 },
364};
365
366struct 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
373struct pmx_dev_mode pmx_plgpio_10_27_modes[] = {
374 {
375 .ids = 0x00,
376 .mask = PMX_MII_MASK,
377 },
378};
379
380struct 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
387struct pmx_dev_mode pmx_plgpio_28_modes[] = {
388 {
389 .ids = 0x00,
390 .mask = PMX_GPIO_PIN0_MASK,
391 },
392};
393
394struct 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
401struct pmx_dev_mode pmx_plgpio_29_modes[] = {
402 {
403 .ids = 0x00,
404 .mask = PMX_GPIO_PIN1_MASK,
405 },
406};
407
408struct 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
415struct pmx_dev_mode pmx_plgpio_30_modes[] = {
416 {
417 .ids = 0x00,
418 .mask = PMX_GPIO_PIN2_MASK,
419 },
420};
421
422struct 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
429struct pmx_dev_mode pmx_plgpio_31_modes[] = {
430 {
431 .ids = 0x00,
432 .mask = PMX_GPIO_PIN3_MASK,
433 },
434};
435
436struct 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
443struct pmx_dev_mode pmx_plgpio_32_modes[] = {
444 {
445 .ids = 0x00,
446 .mask = PMX_GPIO_PIN4_MASK,
447 },
448};
449
450struct 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
457struct pmx_dev_mode pmx_plgpio_33_modes[] = {
458 {
459 .ids = 0x00,
460 .mask = PMX_GPIO_PIN5_MASK,
461 },
462};
463
464struct 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
471struct pmx_dev_mode pmx_plgpio_34_36_modes[] = {
472 {
473 .ids = 0x00,
474 .mask = PMX_SSP_CS_MASK,
475 },
476};
477
478struct 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
485struct pmx_dev_mode pmx_plgpio_37_42_modes[] = {
486 {
487 .ids = 0x00,
488 .mask = PMX_UART0_MODEM_MASK,
489 },
490};
491
492struct 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
499struct pmx_dev_mode pmx_plgpio_43_44_47_48_modes[] = {
500 {
501 .ids = 0x00,
502 .mask = PMX_TIMER_1_2_MASK,
503 },
504};
505
506struct 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
513struct pmx_dev_mode pmx_plgpio_45_46_49_50_modes[] = {
514 {
515 .ids = 0x00,
516 .mask = PMX_TIMER_3_4_MASK,
517 },
518};
519
520struct 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 */
530void 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
544pmx_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
6obj-y := clock.o time.o 6obj-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 */
25struct 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 */
36struct 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 */
47struct 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 */
62struct 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 */
80struct 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 */
90int 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 */
27struct pmx {
28 u32 base;
29 struct pmx_reg mode_reg;
30 struct pmx_reg mux_reg;
31 struct pmx_mode *active_mode;
32};
33
34static 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 */
43static 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 */
72static 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 */
131int 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
162pmx_fail:
163 return ret;
164}