diff options
Diffstat (limited to 'arch/arm/mach-omap2/mux.c')
-rw-r--r-- | arch/arm/mach-omap2/mux.c | 1061 |
1 files changed, 705 insertions, 356 deletions
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index c18a94eca641..e071b3fd1878 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c | |||
@@ -27,19 +27,52 @@ | |||
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/io.h> | 28 | #include <linux/io.h> |
29 | #include <linux/spinlock.h> | 29 | #include <linux/spinlock.h> |
30 | #include <linux/list.h> | ||
31 | #include <linux/ctype.h> | ||
32 | #include <linux/debugfs.h> | ||
33 | #include <linux/seq_file.h> | ||
34 | #include <linux/uaccess.h> | ||
30 | 35 | ||
31 | #include <asm/system.h> | 36 | #include <asm/system.h> |
32 | 37 | ||
33 | #include <plat/control.h> | 38 | #include <plat/control.h> |
34 | #include <plat/mux.h> | 39 | #include <plat/mux.h> |
35 | 40 | ||
36 | #ifdef CONFIG_OMAP_MUX | 41 | #include "mux.h" |
42 | |||
43 | #define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */ | ||
44 | #define OMAP_MUX_BASE_SZ 0x5ca | ||
45 | |||
46 | struct omap_mux_entry { | ||
47 | struct omap_mux mux; | ||
48 | struct list_head node; | ||
49 | }; | ||
50 | |||
51 | static unsigned long mux_phys; | ||
52 | static void __iomem *mux_base; | ||
53 | |||
54 | static inline u16 omap_mux_read(u16 reg) | ||
55 | { | ||
56 | if (cpu_is_omap24xx()) | ||
57 | return __raw_readb(mux_base + reg); | ||
58 | else | ||
59 | return __raw_readw(mux_base + reg); | ||
60 | } | ||
61 | |||
62 | static inline void omap_mux_write(u16 val, u16 reg) | ||
63 | { | ||
64 | if (cpu_is_omap24xx()) | ||
65 | __raw_writeb(val, mux_base + reg); | ||
66 | else | ||
67 | __raw_writew(val, mux_base + reg); | ||
68 | } | ||
69 | |||
70 | #if defined(CONFIG_ARCH_OMAP24XX) && defined(CONFIG_OMAP_MUX) | ||
37 | 71 | ||
38 | static struct omap_mux_cfg arch_mux_cfg; | 72 | static struct omap_mux_cfg arch_mux_cfg; |
39 | 73 | ||
40 | /* NOTE: See mux.h for the enumeration */ | 74 | /* NOTE: See mux.h for the enumeration */ |
41 | 75 | ||
42 | #ifdef CONFIG_ARCH_OMAP24XX | ||
43 | static struct pin_config __initdata_or_module omap24xx_pins[] = { | 76 | static struct pin_config __initdata_or_module omap24xx_pins[] = { |
44 | /* | 77 | /* |
45 | * description mux mux pull pull debug | 78 | * description mux mux pull pull debug |
@@ -249,342 +282,14 @@ MUX_CFG_24XX("AF19_2430_GPIO_85", 0x0113, 3, 0, 0, 1) | |||
249 | 282 | ||
250 | #define OMAP24XX_PINS_SZ ARRAY_SIZE(omap24xx_pins) | 283 | #define OMAP24XX_PINS_SZ ARRAY_SIZE(omap24xx_pins) |
251 | 284 | ||
252 | #else | ||
253 | #define omap24xx_pins NULL | ||
254 | #define OMAP24XX_PINS_SZ 0 | ||
255 | #endif /* CONFIG_ARCH_OMAP24XX */ | ||
256 | |||
257 | #ifdef CONFIG_ARCH_OMAP34XX | ||
258 | static struct pin_config __initdata_or_module omap34xx_pins[] = { | ||
259 | /* | ||
260 | * Name, reg-offset, | ||
261 | * mux-mode | [active-mode | off-mode] | ||
262 | */ | ||
263 | |||
264 | /* 34xx I2C */ | ||
265 | MUX_CFG_34XX("K21_34XX_I2C1_SCL", 0x1ba, | ||
266 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
267 | MUX_CFG_34XX("J21_34XX_I2C1_SDA", 0x1bc, | ||
268 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
269 | MUX_CFG_34XX("AF15_34XX_I2C2_SCL", 0x1be, | ||
270 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
271 | MUX_CFG_34XX("AE15_34XX_I2C2_SDA", 0x1c0, | ||
272 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
273 | MUX_CFG_34XX("AF14_34XX_I2C3_SCL", 0x1c2, | ||
274 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
275 | MUX_CFG_34XX("AG14_34XX_I2C3_SDA", 0x1c4, | ||
276 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
277 | MUX_CFG_34XX("AD26_34XX_I2C4_SCL", 0xa00, | ||
278 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
279 | MUX_CFG_34XX("AE26_34XX_I2C4_SDA", 0xa02, | ||
280 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
281 | |||
282 | /* PHY - HSUSB: 12-pin ULPI PHY: Port 1*/ | ||
283 | MUX_CFG_34XX("Y8_3430_USB1HS_PHY_CLK", 0x5da, | ||
284 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT) | ||
285 | MUX_CFG_34XX("Y9_3430_USB1HS_PHY_STP", 0x5d8, | ||
286 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT) | ||
287 | MUX_CFG_34XX("AA14_3430_USB1HS_PHY_DIR", 0x5ec, | ||
288 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
289 | MUX_CFG_34XX("AA11_3430_USB1HS_PHY_NXT", 0x5ee, | ||
290 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
291 | MUX_CFG_34XX("W13_3430_USB1HS_PHY_D0", 0x5dc, | ||
292 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
293 | MUX_CFG_34XX("W12_3430_USB1HS_PHY_D1", 0x5de, | ||
294 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
295 | MUX_CFG_34XX("W11_3430_USB1HS_PHY_D2", 0x5e0, | ||
296 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
297 | MUX_CFG_34XX("Y11_3430_USB1HS_PHY_D3", 0x5ea, | ||
298 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
299 | MUX_CFG_34XX("W9_3430_USB1HS_PHY_D4", 0x5e4, | ||
300 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
301 | MUX_CFG_34XX("Y12_3430_USB1HS_PHY_D5", 0x5e6, | ||
302 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
303 | MUX_CFG_34XX("W8_3430_USB1HS_PHY_D6", 0x5e8, | ||
304 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
305 | MUX_CFG_34XX("Y13_3430_USB1HS_PHY_D7", 0x5e2, | ||
306 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
307 | |||
308 | /* PHY - HSUSB: 12-pin ULPI PHY: Port 2*/ | ||
309 | MUX_CFG_34XX("AA8_3430_USB2HS_PHY_CLK", 0x5f0, | ||
310 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT) | ||
311 | MUX_CFG_34XX("AA10_3430_USB2HS_PHY_STP", 0x5f2, | ||
312 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT) | ||
313 | MUX_CFG_34XX("AA9_3430_USB2HS_PHY_DIR", 0x5f4, | ||
314 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
315 | MUX_CFG_34XX("AB11_3430_USB2HS_PHY_NXT", 0x5f6, | ||
316 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
317 | MUX_CFG_34XX("AB10_3430_USB2HS_PHY_D0", 0x5f8, | ||
318 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
319 | MUX_CFG_34XX("AB9_3430_USB2HS_PHY_D1", 0x5fa, | ||
320 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
321 | MUX_CFG_34XX("W3_3430_USB2HS_PHY_D2", 0x1d4, | ||
322 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
323 | MUX_CFG_34XX("T4_3430_USB2HS_PHY_D3", 0x1de, | ||
324 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
325 | MUX_CFG_34XX("T3_3430_USB2HS_PHY_D4", 0x1d8, | ||
326 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
327 | MUX_CFG_34XX("R3_3430_USB2HS_PHY_D5", 0x1da, | ||
328 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
329 | MUX_CFG_34XX("R4_3430_USB2HS_PHY_D6", 0x1dc, | ||
330 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
331 | MUX_CFG_34XX("T2_3430_USB2HS_PHY_D7", 0x1d6, | ||
332 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
333 | |||
334 | /* TLL - HSUSB: 12-pin TLL Port 1*/ | ||
335 | MUX_CFG_34XX("Y8_3430_USB1HS_TLL_CLK", 0x5da, | ||
336 | OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
337 | MUX_CFG_34XX("Y9_3430_USB1HS_TLL_STP", 0x5d8, | ||
338 | OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLUP) | ||
339 | MUX_CFG_34XX("AA14_3430_USB1HS_TLL_DIR", 0x5ec, | ||
340 | OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
341 | MUX_CFG_34XX("AA11_3430_USB1HS_TLL_NXT", 0x5ee, | ||
342 | OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
343 | MUX_CFG_34XX("W13_3430_USB1HS_TLL_D0", 0x5dc, | ||
344 | OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
345 | MUX_CFG_34XX("W12_3430_USB1HS_TLL_D1", 0x5de, | ||
346 | OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
347 | MUX_CFG_34XX("W11_3430_USB1HS_TLL_D2", 0x5e0, | ||
348 | OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
349 | MUX_CFG_34XX("Y11_3430_USB1HS_TLL_D3", 0x5ea, | ||
350 | OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
351 | MUX_CFG_34XX("W9_3430_USB1HS_TLL_D4", 0x5e4, | ||
352 | OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
353 | MUX_CFG_34XX("Y12_3430_USB1HS_TLL_D5", 0x5e6, | ||
354 | OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
355 | MUX_CFG_34XX("W8_3430_USB1HS_TLL_D6", 0x5e8, | ||
356 | OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
357 | MUX_CFG_34XX("Y13_3430_USB1HS_TLL_D7", 0x5e2, | ||
358 | OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
359 | |||
360 | /* TLL - HSUSB: 12-pin TLL Port 2*/ | ||
361 | MUX_CFG_34XX("AA8_3430_USB2HS_TLL_CLK", 0x5f0, | ||
362 | OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
363 | MUX_CFG_34XX("AA10_3430_USB2HS_TLL_STP", 0x5f2, | ||
364 | OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLUP) | ||
365 | MUX_CFG_34XX("AA9_3430_USB2HS_TLL_DIR", 0x5f4, | ||
366 | OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
367 | MUX_CFG_34XX("AB11_3430_USB2HS_TLL_NXT", 0x5f6, | ||
368 | OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
369 | MUX_CFG_34XX("AB10_3430_USB2HS_TLL_D0", 0x5f8, | ||
370 | OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
371 | MUX_CFG_34XX("AB9_3430_USB2HS_TLL_D1", 0x5fa, | ||
372 | OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
373 | MUX_CFG_34XX("W3_3430_USB2HS_TLL_D2", 0x1d4, | ||
374 | OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
375 | MUX_CFG_34XX("T4_3430_USB2HS_TLL_D3", 0x1de, | ||
376 | OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
377 | MUX_CFG_34XX("T3_3430_USB2HS_TLL_D4", 0x1d8, | ||
378 | OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
379 | MUX_CFG_34XX("R3_3430_USB2HS_TLL_D5", 0x1da, | ||
380 | OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
381 | MUX_CFG_34XX("R4_3430_USB2HS_TLL_D6", 0x1dc, | ||
382 | OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
383 | MUX_CFG_34XX("T2_3430_USB2HS_TLL_D7", 0x1d6, | ||
384 | OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
385 | |||
386 | /* TLL - HSUSB: 12-pin TLL Port 3*/ | ||
387 | MUX_CFG_34XX("AA6_3430_USB3HS_TLL_CLK", 0x180, | ||
388 | OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
389 | MUX_CFG_34XX("AB3_3430_USB3HS_TLL_STP", 0x166, | ||
390 | OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLUP) | ||
391 | MUX_CFG_34XX("AA3_3430_USB3HS_TLL_DIR", 0x168, | ||
392 | OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
393 | MUX_CFG_34XX("Y3_3430_USB3HS_TLL_NXT", 0x16a, | ||
394 | OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
395 | MUX_CFG_34XX("AA5_3430_USB3HS_TLL_D0", 0x186, | ||
396 | OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
397 | MUX_CFG_34XX("Y4_3430_USB3HS_TLL_D1", 0x184, | ||
398 | OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
399 | MUX_CFG_34XX("Y5_3430_USB3HS_TLL_D2", 0x188, | ||
400 | OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
401 | MUX_CFG_34XX("W5_3430_USB3HS_TLL_D3", 0x18a, | ||
402 | OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
403 | MUX_CFG_34XX("AB12_3430_USB3HS_TLL_D4", 0x16c, | ||
404 | OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
405 | MUX_CFG_34XX("AB13_3430_USB3HS_TLL_D5", 0x16e, | ||
406 | OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
407 | MUX_CFG_34XX("AA13_3430_USB3HS_TLL_D6", 0x170, | ||
408 | OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
409 | MUX_CFG_34XX("AA12_3430_USB3HS_TLL_D7", 0x172, | ||
410 | OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
411 | |||
412 | /* PHY FSUSB: FS Serial for Port 1 (multiple PHY modes supported) */ | ||
413 | MUX_CFG_34XX("AF10_3430_USB1FS_PHY_MM1_RXDP", 0x5d8, | ||
414 | OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
415 | MUX_CFG_34XX("AG9_3430_USB1FS_PHY_MM1_RXDM", 0x5ee, | ||
416 | OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
417 | MUX_CFG_34XX("W13_3430_USB1FS_PHY_MM1_RXRCV", 0x5dc, | ||
418 | OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
419 | MUX_CFG_34XX("W12_3430_USB1FS_PHY_MM1_TXSE0", 0x5de, | ||
420 | OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
421 | MUX_CFG_34XX("W11_3430_USB1FS_PHY_MM1_TXDAT", 0x5e0, | ||
422 | OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
423 | MUX_CFG_34XX("Y11_3430_USB1FS_PHY_MM1_TXEN_N", 0x5ea, | ||
424 | OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_OUTPUT) | ||
425 | |||
426 | /* PHY FSUSB: FS Serial for Port 2 (multiple PHY modes supported) */ | ||
427 | MUX_CFG_34XX("AF7_3430_USB2FS_PHY_MM2_RXDP", 0x5f2, | ||
428 | OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
429 | MUX_CFG_34XX("AH7_3430_USB2FS_PHY_MM2_RXDM", 0x5f6, | ||
430 | OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
431 | MUX_CFG_34XX("AB10_3430_USB2FS_PHY_MM2_RXRCV", 0x5f8, | ||
432 | OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
433 | MUX_CFG_34XX("AB9_3430_USB2FS_PHY_MM2_TXSE0", 0x5fa, | ||
434 | OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
435 | MUX_CFG_34XX("W3_3430_USB2FS_PHY_MM2_TXDAT", 0x1d4, | ||
436 | OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
437 | MUX_CFG_34XX("T4_3430_USB2FS_PHY_MM2_TXEN_N", 0x1de, | ||
438 | OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_OUTPUT) | ||
439 | |||
440 | /* PHY FSUSB: FS Serial for Port 3 (multiple PHY modes supported) */ | ||
441 | MUX_CFG_34XX("AH3_3430_USB3FS_PHY_MM3_RXDP", 0x166, | ||
442 | OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
443 | MUX_CFG_34XX("AE3_3430_USB3FS_PHY_MM3_RXDM", 0x16a, | ||
444 | OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
445 | MUX_CFG_34XX("AD1_3430_USB3FS_PHY_MM3_RXRCV", 0x186, | ||
446 | OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
447 | MUX_CFG_34XX("AE1_3430_USB3FS_PHY_MM3_TXSE0", 0x184, | ||
448 | OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
449 | MUX_CFG_34XX("AD2_3430_USB3FS_PHY_MM3_TXDAT", 0x188, | ||
450 | OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
451 | MUX_CFG_34XX("AC1_3430_USB3FS_PHY_MM3_TXEN_N", 0x18a, | ||
452 | OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_OUTPUT) | ||
453 | |||
454 | |||
455 | /* 34XX GPIO - bidirectional, unless the name has an "_OUT" suffix. | ||
456 | * (Always specify PIN_INPUT, except for names suffixed by "_OUT".) | ||
457 | * No internal pullup/pulldown without "_UP" or "_DOWN" suffix. | ||
458 | */ | ||
459 | MUX_CFG_34XX("AF26_34XX_GPIO0", 0x1e0, | ||
460 | OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) | ||
461 | MUX_CFG_34XX("AF22_34XX_GPIO9", 0xa18, | ||
462 | OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) | ||
463 | MUX_CFG_34XX("AG9_34XX_GPIO23", 0x5ee, | ||
464 | OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) | ||
465 | MUX_CFG_34XX("AH8_34XX_GPIO29", 0x5fa, | ||
466 | OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) | ||
467 | MUX_CFG_34XX("U8_34XX_GPIO54_OUT", 0x0b4, | ||
468 | OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT) | ||
469 | MUX_CFG_34XX("U8_34XX_GPIO54_DOWN", 0x0b4, | ||
470 | OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT_PULLDOWN) | ||
471 | MUX_CFG_34XX("L8_34XX_GPIO63", 0x0ce, | ||
472 | OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) | ||
473 | MUX_CFG_34XX("G25_34XX_GPIO86_OUT", 0x0fc, | ||
474 | OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT) | ||
475 | MUX_CFG_34XX("AG4_34XX_GPIO134_OUT", 0x160, | ||
476 | OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT) | ||
477 | MUX_CFG_34XX("AF4_34XX_GPIO135_OUT", 0x162, | ||
478 | OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT) | ||
479 | MUX_CFG_34XX("AE4_34XX_GPIO136_OUT", 0x164, | ||
480 | OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT) | ||
481 | MUX_CFG_34XX("AF6_34XX_GPIO140_UP", 0x16c, | ||
482 | OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT_PULLUP) | ||
483 | MUX_CFG_34XX("AE6_34XX_GPIO141", 0x16e, | ||
484 | OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) | ||
485 | MUX_CFG_34XX("AF5_34XX_GPIO142", 0x170, | ||
486 | OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) | ||
487 | MUX_CFG_34XX("AE5_34XX_GPIO143", 0x172, | ||
488 | OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) | ||
489 | MUX_CFG_34XX("H19_34XX_GPIO164_OUT", 0x19c, | ||
490 | OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT) | ||
491 | MUX_CFG_34XX("J25_34XX_GPIO170", 0x1c6, | ||
492 | OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) | ||
493 | |||
494 | /* OMAP3 SDRC CKE signals to SDR/DDR ram chips */ | ||
495 | MUX_CFG_34XX("H16_34XX_SDRC_CKE0", 0x262, | ||
496 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT) | ||
497 | MUX_CFG_34XX("H17_34XX_SDRC_CKE1", 0x264, | ||
498 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT) | ||
499 | |||
500 | /* MMC1 */ | ||
501 | MUX_CFG_34XX("N28_3430_MMC1_CLK", 0x144, | ||
502 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
503 | MUX_CFG_34XX("M27_3430_MMC1_CMD", 0x146, | ||
504 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
505 | MUX_CFG_34XX("N27_3430_MMC1_DAT0", 0x148, | ||
506 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
507 | MUX_CFG_34XX("N26_3430_MMC1_DAT1", 0x14a, | ||
508 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
509 | MUX_CFG_34XX("N25_3430_MMC1_DAT2", 0x14c, | ||
510 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
511 | MUX_CFG_34XX("P28_3430_MMC1_DAT3", 0x14e, | ||
512 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
513 | MUX_CFG_34XX("P27_3430_MMC1_DAT4", 0x150, | ||
514 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
515 | MUX_CFG_34XX("P26_3430_MMC1_DAT5", 0x152, | ||
516 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
517 | MUX_CFG_34XX("R27_3430_MMC1_DAT6", 0x154, | ||
518 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
519 | MUX_CFG_34XX("R25_3430_MMC1_DAT7", 0x156, | ||
520 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
521 | |||
522 | /* MMC2 */ | ||
523 | MUX_CFG_34XX("AE2_3430_MMC2_CLK", 0x158, | ||
524 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
525 | MUX_CFG_34XX("AG5_3430_MMC2_CMD", 0x15A, | ||
526 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
527 | MUX_CFG_34XX("AH5_3430_MMC2_DAT0", 0x15c, | ||
528 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
529 | MUX_CFG_34XX("AH4_3430_MMC2_DAT1", 0x15e, | ||
530 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
531 | MUX_CFG_34XX("AG4_3430_MMC2_DAT2", 0x160, | ||
532 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
533 | MUX_CFG_34XX("AF4_3430_MMC2_DAT3", 0x162, | ||
534 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
535 | MUX_CFG_34XX("AE4_3430_MMC2_DAT4", 0x164, | ||
536 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
537 | MUX_CFG_34XX("AH3_3430_MMC2_DAT5", 0x166, | ||
538 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
539 | MUX_CFG_34XX("AF3_3430_MMC2_DAT6", 0x168, | ||
540 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
541 | MUX_CFG_34XX("AE3_3430_MMC2_DAT7", 0x16A, | ||
542 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
543 | |||
544 | /* MMC3 */ | ||
545 | MUX_CFG_34XX("AF10_3430_MMC3_CLK", 0x5d8, | ||
546 | OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP) | ||
547 | MUX_CFG_34XX("AC3_3430_MMC3_CMD", 0x1d0, | ||
548 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLUP) | ||
549 | MUX_CFG_34XX("AE11_3430_MMC3_DAT0", 0x5e4, | ||
550 | OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP) | ||
551 | MUX_CFG_34XX("AH9_3430_MMC3_DAT1", 0x5e6, | ||
552 | OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP) | ||
553 | MUX_CFG_34XX("AF13_3430_MMC3_DAT2", 0x5e8, | ||
554 | OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP) | ||
555 | MUX_CFG_34XX("AF13_3430_MMC3_DAT3", 0x5e2, | ||
556 | OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP) | ||
557 | |||
558 | /* SYS_NIRQ T2 INT1 */ | ||
559 | MUX_CFG_34XX("AF26_34XX_SYS_NIRQ", 0x1E0, | ||
560 | OMAP3_WAKEUP_EN | OMAP34XX_PIN_INPUT_PULLUP | | ||
561 | OMAP34XX_MUX_MODE0) | ||
562 | /* EHCI GPIO's on OMAP3EVM (Rev >= E) */ | ||
563 | MUX_CFG_34XX("AH14_34XX_GPIO21", 0x5ea, | ||
564 | OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT_PULLUP) | ||
565 | MUX_CFG_34XX("AF9_34XX_GPIO22", 0x5ec, | ||
566 | OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT_PULLUP) | ||
567 | MUX_CFG_34XX("U3_34XX_GPIO61", 0x0c8, | ||
568 | OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT_PULLUP) | ||
569 | }; | ||
570 | |||
571 | #define OMAP34XX_PINS_SZ ARRAY_SIZE(omap34xx_pins) | ||
572 | |||
573 | #else | ||
574 | #define omap34xx_pins NULL | ||
575 | #define OMAP34XX_PINS_SZ 0 | ||
576 | #endif /* CONFIG_ARCH_OMAP34XX */ | ||
577 | |||
578 | #if defined(CONFIG_OMAP_MUX_DEBUG) || defined(CONFIG_OMAP_MUX_WARNINGS) | 285 | #if defined(CONFIG_OMAP_MUX_DEBUG) || defined(CONFIG_OMAP_MUX_WARNINGS) |
286 | |||
579 | static void __init_or_module omap2_cfg_debug(const struct pin_config *cfg, u16 reg) | 287 | static void __init_or_module omap2_cfg_debug(const struct pin_config *cfg, u16 reg) |
580 | { | 288 | { |
581 | u16 orig; | 289 | u16 orig; |
582 | u8 warn = 0, debug = 0; | 290 | u8 warn = 0, debug = 0; |
583 | 291 | ||
584 | if (cpu_is_omap24xx()) | 292 | orig = omap_mux_read(cfg->mux_reg - OMAP_MUX_BASE_OFFSET); |
585 | orig = omap_ctrl_readb(cfg->mux_reg); | ||
586 | else | ||
587 | orig = omap_ctrl_readw(cfg->mux_reg); | ||
588 | 293 | ||
589 | #ifdef CONFIG_OMAP_MUX_DEBUG | 294 | #ifdef CONFIG_OMAP_MUX_DEBUG |
590 | debug = cfg->debug; | 295 | debug = cfg->debug; |
@@ -600,7 +305,6 @@ static void __init_or_module omap2_cfg_debug(const struct pin_config *cfg, u16 r | |||
600 | #define omap2_cfg_debug(x, y) do {} while (0) | 305 | #define omap2_cfg_debug(x, y) do {} while (0) |
601 | #endif | 306 | #endif |
602 | 307 | ||
603 | #ifdef CONFIG_ARCH_OMAP24XX | ||
604 | static int __init_or_module omap24xx_cfg_reg(const struct pin_config *cfg) | 308 | static int __init_or_module omap24xx_cfg_reg(const struct pin_config *cfg) |
605 | { | 309 | { |
606 | static DEFINE_SPINLOCK(mux_spin_lock); | 310 | static DEFINE_SPINLOCK(mux_spin_lock); |
@@ -614,47 +318,692 @@ static int __init_or_module omap24xx_cfg_reg(const struct pin_config *cfg) | |||
614 | if (cfg->pu_pd_val) | 318 | if (cfg->pu_pd_val) |
615 | reg |= OMAP2_PULL_UP; | 319 | reg |= OMAP2_PULL_UP; |
616 | omap2_cfg_debug(cfg, reg); | 320 | omap2_cfg_debug(cfg, reg); |
617 | omap_ctrl_writeb(reg, cfg->mux_reg); | 321 | omap_mux_write(reg, cfg->mux_reg - OMAP_MUX_BASE_OFFSET); |
618 | spin_unlock_irqrestore(&mux_spin_lock, flags); | 322 | spin_unlock_irqrestore(&mux_spin_lock, flags); |
619 | 323 | ||
620 | return 0; | 324 | return 0; |
621 | } | 325 | } |
326 | |||
327 | int __init omap2_mux_init(void) | ||
328 | { | ||
329 | u32 mux_pbase; | ||
330 | |||
331 | if (cpu_is_omap2420()) | ||
332 | mux_pbase = OMAP2420_CTRL_BASE + OMAP_MUX_BASE_OFFSET; | ||
333 | else if (cpu_is_omap2430()) | ||
334 | mux_pbase = OMAP243X_CTRL_BASE + OMAP_MUX_BASE_OFFSET; | ||
335 | else | ||
336 | return -ENODEV; | ||
337 | |||
338 | mux_base = ioremap(mux_pbase, OMAP_MUX_BASE_SZ); | ||
339 | if (!mux_base) { | ||
340 | printk(KERN_ERR "mux: Could not ioremap\n"); | ||
341 | return -ENODEV; | ||
342 | } | ||
343 | |||
344 | if (cpu_is_omap24xx()) { | ||
345 | arch_mux_cfg.pins = omap24xx_pins; | ||
346 | arch_mux_cfg.size = OMAP24XX_PINS_SZ; | ||
347 | arch_mux_cfg.cfg_reg = omap24xx_cfg_reg; | ||
348 | |||
349 | return omap_mux_register(&arch_mux_cfg); | ||
350 | } | ||
351 | |||
352 | return 0; | ||
353 | } | ||
354 | |||
622 | #else | 355 | #else |
623 | #define omap24xx_cfg_reg NULL | 356 | int __init omap2_mux_init(void) |
624 | #endif | 357 | { |
358 | return 0; | ||
359 | } | ||
360 | #endif /* CONFIG_OMAP_MUX */ | ||
361 | |||
362 | /*----------------------------------------------------------------------------*/ | ||
625 | 363 | ||
626 | #ifdef CONFIG_ARCH_OMAP34XX | 364 | #ifdef CONFIG_ARCH_OMAP34XX |
627 | static int __init_or_module omap34xx_cfg_reg(const struct pin_config *cfg) | 365 | static LIST_HEAD(muxmodes); |
366 | static DEFINE_MUTEX(muxmode_mutex); | ||
367 | |||
368 | #ifdef CONFIG_OMAP_MUX | ||
369 | |||
370 | static char *omap_mux_options; | ||
371 | |||
372 | int __init omap_mux_init_gpio(int gpio, int val) | ||
628 | { | 373 | { |
629 | static DEFINE_SPINLOCK(mux_spin_lock); | 374 | struct omap_mux_entry *e; |
630 | unsigned long flags; | 375 | int found = 0; |
631 | u16 reg = 0; | 376 | |
377 | if (!gpio) | ||
378 | return -EINVAL; | ||
379 | |||
380 | list_for_each_entry(e, &muxmodes, node) { | ||
381 | struct omap_mux *m = &e->mux; | ||
382 | if (gpio == m->gpio) { | ||
383 | u16 old_mode; | ||
384 | u16 mux_mode; | ||
385 | |||
386 | old_mode = omap_mux_read(m->reg_offset); | ||
387 | mux_mode = val & ~(OMAP_MUX_NR_MODES - 1); | ||
388 | mux_mode |= OMAP_MUX_MODE4; | ||
389 | printk(KERN_DEBUG "mux: Setting signal " | ||
390 | "%s.gpio%i 0x%04x -> 0x%04x\n", | ||
391 | m->muxnames[0], gpio, old_mode, mux_mode); | ||
392 | omap_mux_write(mux_mode, m->reg_offset); | ||
393 | found++; | ||
394 | } | ||
395 | } | ||
632 | 396 | ||
633 | spin_lock_irqsave(&mux_spin_lock, flags); | 397 | if (found == 1) |
634 | reg |= cfg->mux_val; | 398 | return 0; |
635 | omap2_cfg_debug(cfg, reg); | 399 | |
636 | omap_ctrl_writew(reg, cfg->mux_reg); | 400 | if (found > 1) { |
637 | spin_unlock_irqrestore(&mux_spin_lock, flags); | 401 | printk(KERN_ERR "mux: Multiple gpio paths for gpio%i\n", gpio); |
402 | return -EINVAL; | ||
403 | } | ||
404 | |||
405 | printk(KERN_ERR "mux: Could not set gpio%i\n", gpio); | ||
406 | |||
407 | return -ENODEV; | ||
408 | } | ||
409 | |||
410 | int __init omap_mux_init_signal(char *muxname, int val) | ||
411 | { | ||
412 | struct omap_mux_entry *e; | ||
413 | char *m0_name = NULL, *mode_name = NULL; | ||
414 | int found = 0; | ||
415 | |||
416 | mode_name = strchr(muxname, '.'); | ||
417 | if (mode_name) { | ||
418 | *mode_name = '\0'; | ||
419 | mode_name++; | ||
420 | m0_name = muxname; | ||
421 | } else { | ||
422 | mode_name = muxname; | ||
423 | } | ||
424 | |||
425 | list_for_each_entry(e, &muxmodes, node) { | ||
426 | struct omap_mux *m = &e->mux; | ||
427 | char *m0_entry = m->muxnames[0]; | ||
428 | int i; | ||
429 | |||
430 | if (m0_name && strcmp(m0_name, m0_entry)) | ||
431 | continue; | ||
432 | |||
433 | for (i = 0; i < OMAP_MUX_NR_MODES; i++) { | ||
434 | char *mode_cur = m->muxnames[i]; | ||
435 | |||
436 | if (!mode_cur) | ||
437 | continue; | ||
438 | |||
439 | if (!strcmp(mode_name, mode_cur)) { | ||
440 | u16 old_mode; | ||
441 | u16 mux_mode; | ||
442 | |||
443 | old_mode = omap_mux_read(m->reg_offset); | ||
444 | mux_mode = val | i; | ||
445 | printk(KERN_DEBUG "mux: Setting signal " | ||
446 | "%s.%s 0x%04x -> 0x%04x\n", | ||
447 | m0_entry, muxname, old_mode, mux_mode); | ||
448 | omap_mux_write(mux_mode, m->reg_offset); | ||
449 | found++; | ||
450 | } | ||
451 | } | ||
452 | } | ||
453 | |||
454 | if (found == 1) | ||
455 | return 0; | ||
456 | |||
457 | if (found > 1) { | ||
458 | printk(KERN_ERR "mux: Multiple signal paths (%i) for %s\n", | ||
459 | found, muxname); | ||
460 | return -EINVAL; | ||
461 | } | ||
462 | |||
463 | printk(KERN_ERR "mux: Could not set signal %s\n", muxname); | ||
464 | |||
465 | return -ENODEV; | ||
466 | } | ||
467 | |||
468 | #ifdef CONFIG_DEBUG_FS | ||
469 | |||
470 | #define OMAP_MUX_MAX_NR_FLAGS 10 | ||
471 | #define OMAP_MUX_TEST_FLAG(val, mask) \ | ||
472 | if (((val) & (mask)) == (mask)) { \ | ||
473 | i++; \ | ||
474 | flags[i] = #mask; \ | ||
475 | } | ||
476 | |||
477 | /* REVISIT: Add checking for non-optimal mux settings */ | ||
478 | static inline void omap_mux_decode(struct seq_file *s, u16 val) | ||
479 | { | ||
480 | char *flags[OMAP_MUX_MAX_NR_FLAGS]; | ||
481 | char mode[14]; | ||
482 | int i = -1; | ||
483 | |||
484 | sprintf(mode, "OMAP_MUX_MODE%d", val & 0x7); | ||
485 | i++; | ||
486 | flags[i] = mode; | ||
487 | |||
488 | OMAP_MUX_TEST_FLAG(val, OMAP_PIN_OFF_WAKEUPENABLE); | ||
489 | if (val & OMAP_OFF_EN) { | ||
490 | if (!(val & OMAP_OFFOUT_EN)) { | ||
491 | if (!(val & OMAP_OFF_PULL_UP)) { | ||
492 | OMAP_MUX_TEST_FLAG(val, | ||
493 | OMAP_PIN_OFF_INPUT_PULLDOWN); | ||
494 | } else { | ||
495 | OMAP_MUX_TEST_FLAG(val, | ||
496 | OMAP_PIN_OFF_INPUT_PULLUP); | ||
497 | } | ||
498 | } else { | ||
499 | if (!(val & OMAP_OFFOUT_VAL)) { | ||
500 | OMAP_MUX_TEST_FLAG(val, | ||
501 | OMAP_PIN_OFF_OUTPUT_LOW); | ||
502 | } else { | ||
503 | OMAP_MUX_TEST_FLAG(val, | ||
504 | OMAP_PIN_OFF_OUTPUT_HIGH); | ||
505 | } | ||
506 | } | ||
507 | } | ||
508 | |||
509 | if (val & OMAP_INPUT_EN) { | ||
510 | if (val & OMAP_PULL_ENA) { | ||
511 | if (!(val & OMAP_PULL_UP)) { | ||
512 | OMAP_MUX_TEST_FLAG(val, | ||
513 | OMAP_PIN_INPUT_PULLDOWN); | ||
514 | } else { | ||
515 | OMAP_MUX_TEST_FLAG(val, OMAP_PIN_INPUT_PULLUP); | ||
516 | } | ||
517 | } else { | ||
518 | OMAP_MUX_TEST_FLAG(val, OMAP_PIN_INPUT); | ||
519 | } | ||
520 | } else { | ||
521 | i++; | ||
522 | flags[i] = "OMAP_PIN_OUTPUT"; | ||
523 | } | ||
524 | |||
525 | do { | ||
526 | seq_printf(s, "%s", flags[i]); | ||
527 | if (i > 0) | ||
528 | seq_printf(s, " | "); | ||
529 | } while (i-- > 0); | ||
530 | } | ||
531 | |||
532 | #define OMAP_MUX_DEFNAME_LEN 16 | ||
533 | |||
534 | static int omap_mux_dbg_board_show(struct seq_file *s, void *unused) | ||
535 | { | ||
536 | struct omap_mux_entry *e; | ||
537 | |||
538 | list_for_each_entry(e, &muxmodes, node) { | ||
539 | struct omap_mux *m = &e->mux; | ||
540 | char m0_def[OMAP_MUX_DEFNAME_LEN]; | ||
541 | char *m0_name = m->muxnames[0]; | ||
542 | u16 val; | ||
543 | int i, mode; | ||
544 | |||
545 | if (!m0_name) | ||
546 | continue; | ||
547 | |||
548 | for (i = 0; i < OMAP_MUX_DEFNAME_LEN; i++) { | ||
549 | if (m0_name[i] == '\0') { | ||
550 | m0_def[i] = m0_name[i]; | ||
551 | break; | ||
552 | } | ||
553 | m0_def[i] = toupper(m0_name[i]); | ||
554 | } | ||
555 | val = omap_mux_read(m->reg_offset); | ||
556 | mode = val & OMAP_MUX_MODE7; | ||
557 | |||
558 | seq_printf(s, "OMAP%i_MUX(%s, ", | ||
559 | cpu_is_omap34xx() ? 3 : 0, m0_def); | ||
560 | omap_mux_decode(s, val); | ||
561 | seq_printf(s, "),\n"); | ||
562 | } | ||
563 | |||
564 | return 0; | ||
565 | } | ||
566 | |||
567 | static int omap_mux_dbg_board_open(struct inode *inode, struct file *file) | ||
568 | { | ||
569 | return single_open(file, omap_mux_dbg_board_show, &inode->i_private); | ||
570 | } | ||
571 | |||
572 | static const struct file_operations omap_mux_dbg_board_fops = { | ||
573 | .open = omap_mux_dbg_board_open, | ||
574 | .read = seq_read, | ||
575 | .llseek = seq_lseek, | ||
576 | .release = single_release, | ||
577 | }; | ||
578 | |||
579 | static int omap_mux_dbg_signal_show(struct seq_file *s, void *unused) | ||
580 | { | ||
581 | struct omap_mux *m = s->private; | ||
582 | const char *none = "NA"; | ||
583 | u16 val; | ||
584 | int mode; | ||
585 | |||
586 | val = omap_mux_read(m->reg_offset); | ||
587 | mode = val & OMAP_MUX_MODE7; | ||
588 | |||
589 | seq_printf(s, "name: %s.%s (0x%08lx/0x%03x = 0x%04x), b %s, t %s\n", | ||
590 | m->muxnames[0], m->muxnames[mode], | ||
591 | mux_phys + m->reg_offset, m->reg_offset, val, | ||
592 | m->balls[0] ? m->balls[0] : none, | ||
593 | m->balls[1] ? m->balls[1] : none); | ||
594 | seq_printf(s, "mode: "); | ||
595 | omap_mux_decode(s, val); | ||
596 | seq_printf(s, "\n"); | ||
597 | seq_printf(s, "signals: %s | %s | %s | %s | %s | %s | %s | %s\n", | ||
598 | m->muxnames[0] ? m->muxnames[0] : none, | ||
599 | m->muxnames[1] ? m->muxnames[1] : none, | ||
600 | m->muxnames[2] ? m->muxnames[2] : none, | ||
601 | m->muxnames[3] ? m->muxnames[3] : none, | ||
602 | m->muxnames[4] ? m->muxnames[4] : none, | ||
603 | m->muxnames[5] ? m->muxnames[5] : none, | ||
604 | m->muxnames[6] ? m->muxnames[6] : none, | ||
605 | m->muxnames[7] ? m->muxnames[7] : none); | ||
638 | 606 | ||
639 | return 0; | 607 | return 0; |
640 | } | 608 | } |
609 | |||
610 | #define OMAP_MUX_MAX_ARG_CHAR 7 | ||
611 | |||
612 | static ssize_t omap_mux_dbg_signal_write(struct file *file, | ||
613 | const char __user *user_buf, | ||
614 | size_t count, loff_t *ppos) | ||
615 | { | ||
616 | char buf[OMAP_MUX_MAX_ARG_CHAR]; | ||
617 | struct seq_file *seqf; | ||
618 | struct omap_mux *m; | ||
619 | unsigned long val; | ||
620 | int buf_size, ret; | ||
621 | |||
622 | if (count > OMAP_MUX_MAX_ARG_CHAR) | ||
623 | return -EINVAL; | ||
624 | |||
625 | memset(buf, 0, sizeof(buf)); | ||
626 | buf_size = min(count, sizeof(buf) - 1); | ||
627 | |||
628 | if (copy_from_user(buf, user_buf, buf_size)) | ||
629 | return -EFAULT; | ||
630 | |||
631 | ret = strict_strtoul(buf, 0x10, &val); | ||
632 | if (ret < 0) | ||
633 | return ret; | ||
634 | |||
635 | if (val > 0xffff) | ||
636 | return -EINVAL; | ||
637 | |||
638 | seqf = file->private_data; | ||
639 | m = seqf->private; | ||
640 | |||
641 | omap_mux_write((u16)val, m->reg_offset); | ||
642 | *ppos += count; | ||
643 | |||
644 | return count; | ||
645 | } | ||
646 | |||
647 | static int omap_mux_dbg_signal_open(struct inode *inode, struct file *file) | ||
648 | { | ||
649 | return single_open(file, omap_mux_dbg_signal_show, inode->i_private); | ||
650 | } | ||
651 | |||
652 | static const struct file_operations omap_mux_dbg_signal_fops = { | ||
653 | .open = omap_mux_dbg_signal_open, | ||
654 | .read = seq_read, | ||
655 | .write = omap_mux_dbg_signal_write, | ||
656 | .llseek = seq_lseek, | ||
657 | .release = single_release, | ||
658 | }; | ||
659 | |||
660 | static struct dentry *mux_dbg_dir; | ||
661 | |||
662 | static void __init omap_mux_dbg_init(void) | ||
663 | { | ||
664 | struct omap_mux_entry *e; | ||
665 | |||
666 | mux_dbg_dir = debugfs_create_dir("omap_mux", NULL); | ||
667 | if (!mux_dbg_dir) | ||
668 | return; | ||
669 | |||
670 | (void)debugfs_create_file("board", S_IRUGO, mux_dbg_dir, | ||
671 | NULL, &omap_mux_dbg_board_fops); | ||
672 | |||
673 | list_for_each_entry(e, &muxmodes, node) { | ||
674 | struct omap_mux *m = &e->mux; | ||
675 | |||
676 | (void)debugfs_create_file(m->muxnames[0], S_IWUGO, mux_dbg_dir, | ||
677 | m, &omap_mux_dbg_signal_fops); | ||
678 | } | ||
679 | } | ||
680 | |||
641 | #else | 681 | #else |
642 | #define omap34xx_cfg_reg NULL | 682 | static inline void omap_mux_dbg_init(void) |
683 | { | ||
684 | } | ||
685 | #endif /* CONFIG_DEBUG_FS */ | ||
686 | |||
687 | static void __init omap_mux_free_names(struct omap_mux *m) | ||
688 | { | ||
689 | int i; | ||
690 | |||
691 | for (i = 0; i < OMAP_MUX_NR_MODES; i++) | ||
692 | kfree(m->muxnames[i]); | ||
693 | |||
694 | #ifdef CONFIG_DEBUG_FS | ||
695 | for (i = 0; i < OMAP_MUX_NR_SIDES; i++) | ||
696 | kfree(m->balls[i]); | ||
643 | #endif | 697 | #endif |
644 | 698 | ||
645 | int __init omap2_mux_init(void) | 699 | } |
700 | |||
701 | /* Free all data except for GPIO pins unless CONFIG_DEBUG_FS is set */ | ||
702 | static int __init omap_mux_late_init(void) | ||
646 | { | 703 | { |
647 | if (cpu_is_omap24xx()) { | 704 | struct omap_mux_entry *e, *tmp; |
648 | arch_mux_cfg.pins = omap24xx_pins; | 705 | |
649 | arch_mux_cfg.size = OMAP24XX_PINS_SZ; | 706 | list_for_each_entry_safe(e, tmp, &muxmodes, node) { |
650 | arch_mux_cfg.cfg_reg = omap24xx_cfg_reg; | 707 | struct omap_mux *m = &e->mux; |
651 | } else if (cpu_is_omap34xx()) { | 708 | u16 mode = omap_mux_read(m->reg_offset); |
652 | arch_mux_cfg.pins = omap34xx_pins; | 709 | |
653 | arch_mux_cfg.size = OMAP34XX_PINS_SZ; | 710 | if (OMAP_MODE_GPIO(mode)) |
654 | arch_mux_cfg.cfg_reg = omap34xx_cfg_reg; | 711 | continue; |
712 | |||
713 | #ifndef CONFIG_DEBUG_FS | ||
714 | mutex_lock(&muxmode_mutex); | ||
715 | list_del(&e->node); | ||
716 | mutex_unlock(&muxmode_mutex); | ||
717 | omap_mux_free_names(m); | ||
718 | kfree(m); | ||
719 | #endif | ||
720 | |||
721 | } | ||
722 | |||
723 | omap_mux_dbg_init(); | ||
724 | |||
725 | return 0; | ||
726 | } | ||
727 | late_initcall(omap_mux_late_init); | ||
728 | |||
729 | static void __init omap_mux_package_fixup(struct omap_mux *p, | ||
730 | struct omap_mux *superset) | ||
731 | { | ||
732 | while (p->reg_offset != OMAP_MUX_TERMINATOR) { | ||
733 | struct omap_mux *s = superset; | ||
734 | int found = 0; | ||
735 | |||
736 | while (s->reg_offset != OMAP_MUX_TERMINATOR) { | ||
737 | if (s->reg_offset == p->reg_offset) { | ||
738 | *s = *p; | ||
739 | found++; | ||
740 | break; | ||
741 | } | ||
742 | s++; | ||
743 | } | ||
744 | if (!found) | ||
745 | printk(KERN_ERR "mux: Unknown entry offset 0x%x\n", | ||
746 | p->reg_offset); | ||
747 | p++; | ||
748 | } | ||
749 | } | ||
750 | |||
751 | #ifdef CONFIG_DEBUG_FS | ||
752 | |||
753 | static void __init omap_mux_package_init_balls(struct omap_ball *b, | ||
754 | struct omap_mux *superset) | ||
755 | { | ||
756 | while (b->reg_offset != OMAP_MUX_TERMINATOR) { | ||
757 | struct omap_mux *s = superset; | ||
758 | int found = 0; | ||
759 | |||
760 | while (s->reg_offset != OMAP_MUX_TERMINATOR) { | ||
761 | if (s->reg_offset == b->reg_offset) { | ||
762 | s->balls[0] = b->balls[0]; | ||
763 | s->balls[1] = b->balls[1]; | ||
764 | found++; | ||
765 | break; | ||
766 | } | ||
767 | s++; | ||
768 | } | ||
769 | if (!found) | ||
770 | printk(KERN_ERR "mux: Unknown ball offset 0x%x\n", | ||
771 | b->reg_offset); | ||
772 | b++; | ||
773 | } | ||
774 | } | ||
775 | |||
776 | #else /* CONFIG_DEBUG_FS */ | ||
777 | |||
778 | static inline void omap_mux_package_init_balls(struct omap_ball *b, | ||
779 | struct omap_mux *superset) | ||
780 | { | ||
781 | } | ||
782 | |||
783 | #endif /* CONFIG_DEBUG_FS */ | ||
784 | |||
785 | static int __init omap_mux_setup(char *options) | ||
786 | { | ||
787 | if (!options) | ||
788 | return 0; | ||
789 | |||
790 | omap_mux_options = options; | ||
791 | |||
792 | return 1; | ||
793 | } | ||
794 | __setup("omap_mux=", omap_mux_setup); | ||
795 | |||
796 | /* | ||
797 | * Note that the omap_mux=some.signal1=0x1234,some.signal2=0x1234 | ||
798 | * cmdline options only override the bootloader values. | ||
799 | * During development, please enable CONFIG_DEBUG_FS, and use the | ||
800 | * signal specific entries under debugfs. | ||
801 | */ | ||
802 | static void __init omap_mux_set_cmdline_signals(void) | ||
803 | { | ||
804 | char *options, *next_opt, *token; | ||
805 | |||
806 | if (!omap_mux_options) | ||
807 | return; | ||
808 | |||
809 | options = kmalloc(strlen(omap_mux_options) + 1, GFP_KERNEL); | ||
810 | if (!options) | ||
811 | return; | ||
812 | |||
813 | strcpy(options, omap_mux_options); | ||
814 | next_opt = options; | ||
815 | |||
816 | while ((token = strsep(&next_opt, ",")) != NULL) { | ||
817 | char *keyval, *name; | ||
818 | unsigned long val; | ||
819 | |||
820 | keyval = token; | ||
821 | name = strsep(&keyval, "="); | ||
822 | if (name) { | ||
823 | int res; | ||
824 | |||
825 | res = strict_strtoul(keyval, 0x10, &val); | ||
826 | if (res < 0) | ||
827 | continue; | ||
828 | |||
829 | omap_mux_init_signal(name, (u16)val); | ||
830 | } | ||
831 | } | ||
832 | |||
833 | kfree(options); | ||
834 | } | ||
835 | |||
836 | static void __init omap_mux_set_board_signals(struct omap_board_mux *board_mux) | ||
837 | { | ||
838 | while (board_mux->reg_offset != OMAP_MUX_TERMINATOR) { | ||
839 | omap_mux_write(board_mux->value, board_mux->reg_offset); | ||
840 | board_mux++; | ||
841 | } | ||
842 | } | ||
843 | |||
844 | static int __init omap_mux_copy_names(struct omap_mux *src, | ||
845 | struct omap_mux *dst) | ||
846 | { | ||
847 | int i; | ||
848 | |||
849 | for (i = 0; i < OMAP_MUX_NR_MODES; i++) { | ||
850 | if (src->muxnames[i]) { | ||
851 | dst->muxnames[i] = | ||
852 | kmalloc(strlen(src->muxnames[i]) + 1, | ||
853 | GFP_KERNEL); | ||
854 | if (!dst->muxnames[i]) | ||
855 | goto free; | ||
856 | strcpy(dst->muxnames[i], src->muxnames[i]); | ||
857 | } | ||
858 | } | ||
859 | |||
860 | #ifdef CONFIG_DEBUG_FS | ||
861 | for (i = 0; i < OMAP_MUX_NR_SIDES; i++) { | ||
862 | if (src->balls[i]) { | ||
863 | dst->balls[i] = | ||
864 | kmalloc(strlen(src->balls[i]) + 1, | ||
865 | GFP_KERNEL); | ||
866 | if (!dst->balls[i]) | ||
867 | goto free; | ||
868 | strcpy(dst->balls[i], src->balls[i]); | ||
869 | } | ||
870 | } | ||
871 | #endif | ||
872 | |||
873 | return 0; | ||
874 | |||
875 | free: | ||
876 | omap_mux_free_names(dst); | ||
877 | return -ENOMEM; | ||
878 | |||
879 | } | ||
880 | |||
881 | #endif /* CONFIG_OMAP_MUX */ | ||
882 | |||
883 | static u16 omap_mux_get_by_gpio(int gpio) | ||
884 | { | ||
885 | struct omap_mux_entry *e; | ||
886 | u16 offset = OMAP_MUX_TERMINATOR; | ||
887 | |||
888 | list_for_each_entry(e, &muxmodes, node) { | ||
889 | struct omap_mux *m = &e->mux; | ||
890 | if (m->gpio == gpio) { | ||
891 | offset = m->reg_offset; | ||
892 | break; | ||
893 | } | ||
894 | } | ||
895 | |||
896 | return offset; | ||
897 | } | ||
898 | |||
899 | /* Needed for dynamic muxing of GPIO pins for off-idle */ | ||
900 | u16 omap_mux_get_gpio(int gpio) | ||
901 | { | ||
902 | u16 offset; | ||
903 | |||
904 | offset = omap_mux_get_by_gpio(gpio); | ||
905 | if (offset == OMAP_MUX_TERMINATOR) { | ||
906 | printk(KERN_ERR "mux: Could not get gpio%i\n", gpio); | ||
907 | return offset; | ||
908 | } | ||
909 | |||
910 | return omap_mux_read(offset); | ||
911 | } | ||
912 | |||
913 | /* Needed for dynamic muxing of GPIO pins for off-idle */ | ||
914 | void omap_mux_set_gpio(u16 val, int gpio) | ||
915 | { | ||
916 | u16 offset; | ||
917 | |||
918 | offset = omap_mux_get_by_gpio(gpio); | ||
919 | if (offset == OMAP_MUX_TERMINATOR) { | ||
920 | printk(KERN_ERR "mux: Could not set gpio%i\n", gpio); | ||
921 | return; | ||
922 | } | ||
923 | |||
924 | omap_mux_write(val, offset); | ||
925 | } | ||
926 | |||
927 | static struct omap_mux * __init omap_mux_list_add(struct omap_mux *src) | ||
928 | { | ||
929 | struct omap_mux_entry *entry; | ||
930 | struct omap_mux *m; | ||
931 | |||
932 | entry = kzalloc(sizeof(struct omap_mux_entry), GFP_KERNEL); | ||
933 | if (!entry) | ||
934 | return NULL; | ||
935 | |||
936 | m = &entry->mux; | ||
937 | memcpy(m, src, sizeof(struct omap_mux_entry)); | ||
938 | |||
939 | #ifdef CONFIG_OMAP_MUX | ||
940 | if (omap_mux_copy_names(src, m)) { | ||
941 | kfree(entry); | ||
942 | return NULL; | ||
655 | } | 943 | } |
944 | #endif | ||
945 | |||
946 | mutex_lock(&muxmode_mutex); | ||
947 | list_add_tail(&entry->node, &muxmodes); | ||
948 | mutex_unlock(&muxmode_mutex); | ||
656 | 949 | ||
657 | return omap_mux_register(&arch_mux_cfg); | 950 | return m; |
658 | } | 951 | } |
659 | 952 | ||
953 | /* | ||
954 | * Note if CONFIG_OMAP_MUX is not selected, we will only initialize | ||
955 | * the GPIO to mux offset mapping that is needed for dynamic muxing | ||
956 | * of GPIO pins for off-idle. | ||
957 | */ | ||
958 | static void __init omap_mux_init_list(struct omap_mux *superset) | ||
959 | { | ||
960 | while (superset->reg_offset != OMAP_MUX_TERMINATOR) { | ||
961 | struct omap_mux *entry; | ||
962 | |||
963 | #ifndef CONFIG_OMAP_MUX | ||
964 | /* Skip pins that are not muxed as GPIO by bootloader */ | ||
965 | if (!OMAP_MODE_GPIO(omap_mux_read(superset->reg_offset))) { | ||
966 | superset++; | ||
967 | continue; | ||
968 | } | ||
660 | #endif | 969 | #endif |
970 | |||
971 | entry = omap_mux_list_add(superset); | ||
972 | if (!entry) { | ||
973 | printk(KERN_ERR "mux: Could not add entry\n"); | ||
974 | return; | ||
975 | } | ||
976 | superset++; | ||
977 | } | ||
978 | } | ||
979 | |||
980 | int __init omap_mux_init(u32 mux_pbase, u32 mux_size, | ||
981 | struct omap_mux *superset, | ||
982 | struct omap_mux *package_subset, | ||
983 | struct omap_board_mux *board_mux, | ||
984 | struct omap_ball *package_balls) | ||
985 | { | ||
986 | if (mux_base) | ||
987 | return -EBUSY; | ||
988 | |||
989 | mux_phys = mux_pbase; | ||
990 | mux_base = ioremap(mux_pbase, mux_size); | ||
991 | if (!mux_base) { | ||
992 | printk(KERN_ERR "mux: Could not ioremap\n"); | ||
993 | return -ENODEV; | ||
994 | } | ||
995 | |||
996 | #ifdef CONFIG_OMAP_MUX | ||
997 | omap_mux_package_fixup(package_subset, superset); | ||
998 | omap_mux_package_init_balls(package_balls, superset); | ||
999 | omap_mux_set_cmdline_signals(); | ||
1000 | omap_mux_set_board_signals(board_mux); | ||
1001 | #endif | ||
1002 | |||
1003 | omap_mux_init_list(superset); | ||
1004 | |||
1005 | return 0; | ||
1006 | } | ||
1007 | |||
1008 | #endif /* CONFIG_ARCH_OMAP34XX */ | ||
1009 | |||