diff options
Diffstat (limited to 'arch/arm/mach-omap2/mux.c')
-rw-r--r-- | arch/arm/mach-omap2/mux.c | 1086 |
1 files changed, 742 insertions, 344 deletions
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index b5fac32aae70..8b3d26935a39 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c | |||
@@ -26,20 +26,62 @@ | |||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/io.h> | 28 | #include <linux/io.h> |
29 | #include <linux/slab.h> | ||
29 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
31 | #include <linux/list.h> | ||
32 | #include <linux/ctype.h> | ||
33 | #include <linux/debugfs.h> | ||
34 | #include <linux/seq_file.h> | ||
35 | #include <linux/uaccess.h> | ||
30 | 36 | ||
31 | #include <asm/system.h> | 37 | #include <asm/system.h> |
32 | 38 | ||
33 | #include <mach/control.h> | 39 | #include <plat/control.h> |
34 | #include <mach/mux.h> | 40 | #include <plat/mux.h> |
35 | 41 | ||
36 | #ifdef CONFIG_OMAP_MUX | 42 | #include "mux.h" |
43 | |||
44 | #define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */ | ||
45 | #define OMAP_MUX_BASE_SZ 0x5ca | ||
46 | |||
47 | struct omap_mux_entry { | ||
48 | struct omap_mux mux; | ||
49 | struct list_head node; | ||
50 | }; | ||
51 | |||
52 | static unsigned long mux_phys; | ||
53 | static void __iomem *mux_base; | ||
54 | |||
55 | u16 omap_mux_read(u16 reg) | ||
56 | { | ||
57 | if (cpu_is_omap24xx()) | ||
58 | return __raw_readb(mux_base + reg); | ||
59 | else | ||
60 | return __raw_readw(mux_base + reg); | ||
61 | } | ||
62 | |||
63 | void omap_mux_write(u16 val, u16 reg) | ||
64 | { | ||
65 | if (cpu_is_omap24xx()) | ||
66 | __raw_writeb(val, mux_base + reg); | ||
67 | else | ||
68 | __raw_writew(val, mux_base + reg); | ||
69 | } | ||
70 | |||
71 | void omap_mux_write_array(struct omap_board_mux *board_mux) | ||
72 | { | ||
73 | while (board_mux->reg_offset != OMAP_MUX_TERMINATOR) { | ||
74 | omap_mux_write(board_mux->value, board_mux->reg_offset); | ||
75 | board_mux++; | ||
76 | } | ||
77 | } | ||
78 | |||
79 | #if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_OMAP_MUX) | ||
37 | 80 | ||
38 | static struct omap_mux_cfg arch_mux_cfg; | 81 | static struct omap_mux_cfg arch_mux_cfg; |
39 | 82 | ||
40 | /* NOTE: See mux.h for the enumeration */ | 83 | /* NOTE: See mux.h for the enumeration */ |
41 | 84 | ||
42 | #ifdef CONFIG_ARCH_OMAP24XX | ||
43 | static struct pin_config __initdata_or_module omap24xx_pins[] = { | 85 | static struct pin_config __initdata_or_module omap24xx_pins[] = { |
44 | /* | 86 | /* |
45 | * description mux mux pull pull debug | 87 | * description mux mux pull pull debug |
@@ -249,327 +291,14 @@ MUX_CFG_24XX("AF19_2430_GPIO_85", 0x0113, 3, 0, 0, 1) | |||
249 | 291 | ||
250 | #define OMAP24XX_PINS_SZ ARRAY_SIZE(omap24xx_pins) | 292 | #define OMAP24XX_PINS_SZ ARRAY_SIZE(omap24xx_pins) |
251 | 293 | ||
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 | |||
536 | /* MMC3 */ | ||
537 | MUX_CFG_34XX("AF10_3430_MMC3_CLK", 0x5d8, | ||
538 | OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP) | ||
539 | MUX_CFG_34XX("AC3_3430_MMC3_CMD", 0x1d0, | ||
540 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLUP) | ||
541 | MUX_CFG_34XX("AE11_3430_MMC3_DAT0", 0x5e4, | ||
542 | OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP) | ||
543 | MUX_CFG_34XX("AH9_3430_MMC3_DAT1", 0x5e6, | ||
544 | OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP) | ||
545 | MUX_CFG_34XX("AF13_3430_MMC3_DAT2", 0x5e8, | ||
546 | OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP) | ||
547 | MUX_CFG_34XX("AF13_3430_MMC3_DAT3", 0x5e2, | ||
548 | OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP) | ||
549 | |||
550 | /* SYS_NIRQ T2 INT1 */ | ||
551 | MUX_CFG_34XX("AF26_34XX_SYS_NIRQ", 0x1E0, | ||
552 | OMAP3_WAKEUP_EN | OMAP34XX_PIN_INPUT_PULLUP | | ||
553 | OMAP34XX_MUX_MODE0) | ||
554 | }; | ||
555 | |||
556 | #define OMAP34XX_PINS_SZ ARRAY_SIZE(omap34xx_pins) | ||
557 | |||
558 | #else | ||
559 | #define omap34xx_pins NULL | ||
560 | #define OMAP34XX_PINS_SZ 0 | ||
561 | #endif /* CONFIG_ARCH_OMAP34XX */ | ||
562 | |||
563 | #if defined(CONFIG_OMAP_MUX_DEBUG) || defined(CONFIG_OMAP_MUX_WARNINGS) | 294 | #if defined(CONFIG_OMAP_MUX_DEBUG) || defined(CONFIG_OMAP_MUX_WARNINGS) |
295 | |||
564 | static void __init_or_module omap2_cfg_debug(const struct pin_config *cfg, u16 reg) | 296 | static void __init_or_module omap2_cfg_debug(const struct pin_config *cfg, u16 reg) |
565 | { | 297 | { |
566 | u16 orig; | 298 | u16 orig; |
567 | u8 warn = 0, debug = 0; | 299 | u8 warn = 0, debug = 0; |
568 | 300 | ||
569 | if (cpu_is_omap24xx()) | 301 | orig = omap_mux_read(cfg->mux_reg - OMAP_MUX_BASE_OFFSET); |
570 | orig = omap_ctrl_readb(cfg->mux_reg); | ||
571 | else | ||
572 | orig = omap_ctrl_readw(cfg->mux_reg); | ||
573 | 302 | ||
574 | #ifdef CONFIG_OMAP_MUX_DEBUG | 303 | #ifdef CONFIG_OMAP_MUX_DEBUG |
575 | debug = cfg->debug; | 304 | debug = cfg->debug; |
@@ -585,7 +314,6 @@ static void __init_or_module omap2_cfg_debug(const struct pin_config *cfg, u16 r | |||
585 | #define omap2_cfg_debug(x, y) do {} while (0) | 314 | #define omap2_cfg_debug(x, y) do {} while (0) |
586 | #endif | 315 | #endif |
587 | 316 | ||
588 | #ifdef CONFIG_ARCH_OMAP24XX | ||
589 | static int __init_or_module omap24xx_cfg_reg(const struct pin_config *cfg) | 317 | static int __init_or_module omap24xx_cfg_reg(const struct pin_config *cfg) |
590 | { | 318 | { |
591 | static DEFINE_SPINLOCK(mux_spin_lock); | 319 | static DEFINE_SPINLOCK(mux_spin_lock); |
@@ -599,47 +327,717 @@ static int __init_or_module omap24xx_cfg_reg(const struct pin_config *cfg) | |||
599 | if (cfg->pu_pd_val) | 327 | if (cfg->pu_pd_val) |
600 | reg |= OMAP2_PULL_UP; | 328 | reg |= OMAP2_PULL_UP; |
601 | omap2_cfg_debug(cfg, reg); | 329 | omap2_cfg_debug(cfg, reg); |
602 | omap_ctrl_writeb(reg, cfg->mux_reg); | 330 | omap_mux_write(reg, cfg->mux_reg - OMAP_MUX_BASE_OFFSET); |
603 | spin_unlock_irqrestore(&mux_spin_lock, flags); | 331 | spin_unlock_irqrestore(&mux_spin_lock, flags); |
604 | 332 | ||
605 | return 0; | 333 | return 0; |
606 | } | 334 | } |
335 | |||
336 | int __init omap2_mux_init(void) | ||
337 | { | ||
338 | u32 mux_pbase; | ||
339 | |||
340 | if (cpu_is_omap2420()) | ||
341 | mux_pbase = OMAP2420_CTRL_BASE + OMAP_MUX_BASE_OFFSET; | ||
342 | else if (cpu_is_omap2430()) | ||
343 | mux_pbase = OMAP243X_CTRL_BASE + OMAP_MUX_BASE_OFFSET; | ||
344 | else | ||
345 | return -ENODEV; | ||
346 | |||
347 | mux_base = ioremap(mux_pbase, OMAP_MUX_BASE_SZ); | ||
348 | if (!mux_base) { | ||
349 | printk(KERN_ERR "mux: Could not ioremap\n"); | ||
350 | return -ENODEV; | ||
351 | } | ||
352 | |||
353 | if (cpu_is_omap24xx()) { | ||
354 | arch_mux_cfg.pins = omap24xx_pins; | ||
355 | arch_mux_cfg.size = OMAP24XX_PINS_SZ; | ||
356 | arch_mux_cfg.cfg_reg = omap24xx_cfg_reg; | ||
357 | |||
358 | return omap_mux_register(&arch_mux_cfg); | ||
359 | } | ||
360 | |||
361 | return 0; | ||
362 | } | ||
363 | |||
607 | #else | 364 | #else |
608 | #define omap24xx_cfg_reg NULL | 365 | int __init omap2_mux_init(void) |
609 | #endif | 366 | { |
367 | return 0; | ||
368 | } | ||
369 | #endif /* CONFIG_OMAP_MUX */ | ||
370 | |||
371 | /*----------------------------------------------------------------------------*/ | ||
610 | 372 | ||
611 | #ifdef CONFIG_ARCH_OMAP34XX | 373 | #ifdef CONFIG_ARCH_OMAP3 |
612 | static int __init_or_module omap34xx_cfg_reg(const struct pin_config *cfg) | 374 | static LIST_HEAD(muxmodes); |
375 | static DEFINE_MUTEX(muxmode_mutex); | ||
376 | |||
377 | #ifdef CONFIG_OMAP_MUX | ||
378 | |||
379 | static char *omap_mux_options; | ||
380 | |||
381 | int __init omap_mux_init_gpio(int gpio, int val) | ||
613 | { | 382 | { |
614 | static DEFINE_SPINLOCK(mux_spin_lock); | 383 | struct omap_mux_entry *e; |
615 | unsigned long flags; | 384 | int found = 0; |
616 | u16 reg = 0; | 385 | |
386 | if (!gpio) | ||
387 | return -EINVAL; | ||
388 | |||
389 | list_for_each_entry(e, &muxmodes, node) { | ||
390 | struct omap_mux *m = &e->mux; | ||
391 | if (gpio == m->gpio) { | ||
392 | u16 old_mode; | ||
393 | u16 mux_mode; | ||
394 | |||
395 | old_mode = omap_mux_read(m->reg_offset); | ||
396 | mux_mode = val & ~(OMAP_MUX_NR_MODES - 1); | ||
397 | mux_mode |= OMAP_MUX_MODE4; | ||
398 | printk(KERN_DEBUG "mux: Setting signal " | ||
399 | "%s.gpio%i 0x%04x -> 0x%04x\n", | ||
400 | m->muxnames[0], gpio, old_mode, mux_mode); | ||
401 | omap_mux_write(mux_mode, m->reg_offset); | ||
402 | found++; | ||
403 | } | ||
404 | } | ||
617 | 405 | ||
618 | spin_lock_irqsave(&mux_spin_lock, flags); | 406 | if (found == 1) |
619 | reg |= cfg->mux_val; | 407 | return 0; |
620 | omap2_cfg_debug(cfg, reg); | 408 | |
621 | omap_ctrl_writew(reg, cfg->mux_reg); | 409 | if (found > 1) { |
622 | spin_unlock_irqrestore(&mux_spin_lock, flags); | 410 | printk(KERN_ERR "mux: Multiple gpio paths for gpio%i\n", gpio); |
411 | return -EINVAL; | ||
412 | } | ||
413 | |||
414 | printk(KERN_ERR "mux: Could not set gpio%i\n", gpio); | ||
415 | |||
416 | return -ENODEV; | ||
417 | } | ||
418 | |||
419 | int __init omap_mux_init_signal(char *muxname, int val) | ||
420 | { | ||
421 | struct omap_mux_entry *e; | ||
422 | char *m0_name = NULL, *mode_name = NULL; | ||
423 | int found = 0; | ||
424 | |||
425 | mode_name = strchr(muxname, '.'); | ||
426 | if (mode_name) { | ||
427 | *mode_name = '\0'; | ||
428 | mode_name++; | ||
429 | m0_name = muxname; | ||
430 | } else { | ||
431 | mode_name = muxname; | ||
432 | } | ||
433 | |||
434 | list_for_each_entry(e, &muxmodes, node) { | ||
435 | struct omap_mux *m = &e->mux; | ||
436 | char *m0_entry = m->muxnames[0]; | ||
437 | int i; | ||
438 | |||
439 | if (m0_name && strcmp(m0_name, m0_entry)) | ||
440 | continue; | ||
441 | |||
442 | for (i = 0; i < OMAP_MUX_NR_MODES; i++) { | ||
443 | char *mode_cur = m->muxnames[i]; | ||
444 | |||
445 | if (!mode_cur) | ||
446 | continue; | ||
447 | |||
448 | if (!strcmp(mode_name, mode_cur)) { | ||
449 | u16 old_mode; | ||
450 | u16 mux_mode; | ||
451 | |||
452 | old_mode = omap_mux_read(m->reg_offset); | ||
453 | mux_mode = val | i; | ||
454 | printk(KERN_DEBUG "mux: Setting signal " | ||
455 | "%s.%s 0x%04x -> 0x%04x\n", | ||
456 | m0_entry, muxname, old_mode, mux_mode); | ||
457 | omap_mux_write(mux_mode, m->reg_offset); | ||
458 | found++; | ||
459 | } | ||
460 | } | ||
461 | } | ||
462 | |||
463 | if (found == 1) | ||
464 | return 0; | ||
465 | |||
466 | if (found > 1) { | ||
467 | printk(KERN_ERR "mux: Multiple signal paths (%i) for %s\n", | ||
468 | found, muxname); | ||
469 | return -EINVAL; | ||
470 | } | ||
471 | |||
472 | printk(KERN_ERR "mux: Could not set signal %s\n", muxname); | ||
473 | |||
474 | return -ENODEV; | ||
475 | } | ||
476 | |||
477 | #ifdef CONFIG_DEBUG_FS | ||
478 | |||
479 | #define OMAP_MUX_MAX_NR_FLAGS 10 | ||
480 | #define OMAP_MUX_TEST_FLAG(val, mask) \ | ||
481 | if (((val) & (mask)) == (mask)) { \ | ||
482 | i++; \ | ||
483 | flags[i] = #mask; \ | ||
484 | } | ||
485 | |||
486 | /* REVISIT: Add checking for non-optimal mux settings */ | ||
487 | static inline void omap_mux_decode(struct seq_file *s, u16 val) | ||
488 | { | ||
489 | char *flags[OMAP_MUX_MAX_NR_FLAGS]; | ||
490 | char mode[sizeof("OMAP_MUX_MODE") + 1]; | ||
491 | int i = -1; | ||
492 | |||
493 | sprintf(mode, "OMAP_MUX_MODE%d", val & 0x7); | ||
494 | i++; | ||
495 | flags[i] = mode; | ||
496 | |||
497 | OMAP_MUX_TEST_FLAG(val, OMAP_PIN_OFF_WAKEUPENABLE); | ||
498 | if (val & OMAP_OFF_EN) { | ||
499 | if (!(val & OMAP_OFFOUT_EN)) { | ||
500 | if (!(val & OMAP_OFF_PULL_UP)) { | ||
501 | OMAP_MUX_TEST_FLAG(val, | ||
502 | OMAP_PIN_OFF_INPUT_PULLDOWN); | ||
503 | } else { | ||
504 | OMAP_MUX_TEST_FLAG(val, | ||
505 | OMAP_PIN_OFF_INPUT_PULLUP); | ||
506 | } | ||
507 | } else { | ||
508 | if (!(val & OMAP_OFFOUT_VAL)) { | ||
509 | OMAP_MUX_TEST_FLAG(val, | ||
510 | OMAP_PIN_OFF_OUTPUT_LOW); | ||
511 | } else { | ||
512 | OMAP_MUX_TEST_FLAG(val, | ||
513 | OMAP_PIN_OFF_OUTPUT_HIGH); | ||
514 | } | ||
515 | } | ||
516 | } | ||
517 | |||
518 | if (val & OMAP_INPUT_EN) { | ||
519 | if (val & OMAP_PULL_ENA) { | ||
520 | if (!(val & OMAP_PULL_UP)) { | ||
521 | OMAP_MUX_TEST_FLAG(val, | ||
522 | OMAP_PIN_INPUT_PULLDOWN); | ||
523 | } else { | ||
524 | OMAP_MUX_TEST_FLAG(val, OMAP_PIN_INPUT_PULLUP); | ||
525 | } | ||
526 | } else { | ||
527 | OMAP_MUX_TEST_FLAG(val, OMAP_PIN_INPUT); | ||
528 | } | ||
529 | } else { | ||
530 | i++; | ||
531 | flags[i] = "OMAP_PIN_OUTPUT"; | ||
532 | } | ||
533 | |||
534 | do { | ||
535 | seq_printf(s, "%s", flags[i]); | ||
536 | if (i > 0) | ||
537 | seq_printf(s, " | "); | ||
538 | } while (i-- > 0); | ||
539 | } | ||
540 | |||
541 | #define OMAP_MUX_DEFNAME_LEN 16 | ||
542 | |||
543 | static int omap_mux_dbg_board_show(struct seq_file *s, void *unused) | ||
544 | { | ||
545 | struct omap_mux_entry *e; | ||
546 | |||
547 | list_for_each_entry(e, &muxmodes, node) { | ||
548 | struct omap_mux *m = &e->mux; | ||
549 | char m0_def[OMAP_MUX_DEFNAME_LEN]; | ||
550 | char *m0_name = m->muxnames[0]; | ||
551 | u16 val; | ||
552 | int i, mode; | ||
553 | |||
554 | if (!m0_name) | ||
555 | continue; | ||
556 | |||
557 | /* REVISIT: Needs to be updated if mode0 names get longer */ | ||
558 | for (i = 0; i < OMAP_MUX_DEFNAME_LEN; i++) { | ||
559 | if (m0_name[i] == '\0') { | ||
560 | m0_def[i] = m0_name[i]; | ||
561 | break; | ||
562 | } | ||
563 | m0_def[i] = toupper(m0_name[i]); | ||
564 | } | ||
565 | val = omap_mux_read(m->reg_offset); | ||
566 | mode = val & OMAP_MUX_MODE7; | ||
567 | |||
568 | seq_printf(s, "OMAP%i_MUX(%s, ", | ||
569 | cpu_is_omap34xx() ? 3 : 0, m0_def); | ||
570 | omap_mux_decode(s, val); | ||
571 | seq_printf(s, "),\n"); | ||
572 | } | ||
573 | |||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | static int omap_mux_dbg_board_open(struct inode *inode, struct file *file) | ||
578 | { | ||
579 | return single_open(file, omap_mux_dbg_board_show, &inode->i_private); | ||
580 | } | ||
581 | |||
582 | static const struct file_operations omap_mux_dbg_board_fops = { | ||
583 | .open = omap_mux_dbg_board_open, | ||
584 | .read = seq_read, | ||
585 | .llseek = seq_lseek, | ||
586 | .release = single_release, | ||
587 | }; | ||
588 | |||
589 | static int omap_mux_dbg_signal_show(struct seq_file *s, void *unused) | ||
590 | { | ||
591 | struct omap_mux *m = s->private; | ||
592 | const char *none = "NA"; | ||
593 | u16 val; | ||
594 | int mode; | ||
595 | |||
596 | val = omap_mux_read(m->reg_offset); | ||
597 | mode = val & OMAP_MUX_MODE7; | ||
598 | |||
599 | seq_printf(s, "name: %s.%s (0x%08lx/0x%03x = 0x%04x), b %s, t %s\n", | ||
600 | m->muxnames[0], m->muxnames[mode], | ||
601 | mux_phys + m->reg_offset, m->reg_offset, val, | ||
602 | m->balls[0] ? m->balls[0] : none, | ||
603 | m->balls[1] ? m->balls[1] : none); | ||
604 | seq_printf(s, "mode: "); | ||
605 | omap_mux_decode(s, val); | ||
606 | seq_printf(s, "\n"); | ||
607 | seq_printf(s, "signals: %s | %s | %s | %s | %s | %s | %s | %s\n", | ||
608 | m->muxnames[0] ? m->muxnames[0] : none, | ||
609 | m->muxnames[1] ? m->muxnames[1] : none, | ||
610 | m->muxnames[2] ? m->muxnames[2] : none, | ||
611 | m->muxnames[3] ? m->muxnames[3] : none, | ||
612 | m->muxnames[4] ? m->muxnames[4] : none, | ||
613 | m->muxnames[5] ? m->muxnames[5] : none, | ||
614 | m->muxnames[6] ? m->muxnames[6] : none, | ||
615 | m->muxnames[7] ? m->muxnames[7] : none); | ||
623 | 616 | ||
624 | return 0; | 617 | return 0; |
625 | } | 618 | } |
619 | |||
620 | #define OMAP_MUX_MAX_ARG_CHAR 7 | ||
621 | |||
622 | static ssize_t omap_mux_dbg_signal_write(struct file *file, | ||
623 | const char __user *user_buf, | ||
624 | size_t count, loff_t *ppos) | ||
625 | { | ||
626 | char buf[OMAP_MUX_MAX_ARG_CHAR]; | ||
627 | struct seq_file *seqf; | ||
628 | struct omap_mux *m; | ||
629 | unsigned long val; | ||
630 | int buf_size, ret; | ||
631 | |||
632 | if (count > OMAP_MUX_MAX_ARG_CHAR) | ||
633 | return -EINVAL; | ||
634 | |||
635 | memset(buf, 0, sizeof(buf)); | ||
636 | buf_size = min(count, sizeof(buf) - 1); | ||
637 | |||
638 | if (copy_from_user(buf, user_buf, buf_size)) | ||
639 | return -EFAULT; | ||
640 | |||
641 | ret = strict_strtoul(buf, 0x10, &val); | ||
642 | if (ret < 0) | ||
643 | return ret; | ||
644 | |||
645 | if (val > 0xffff) | ||
646 | return -EINVAL; | ||
647 | |||
648 | seqf = file->private_data; | ||
649 | m = seqf->private; | ||
650 | |||
651 | omap_mux_write((u16)val, m->reg_offset); | ||
652 | *ppos += count; | ||
653 | |||
654 | return count; | ||
655 | } | ||
656 | |||
657 | static int omap_mux_dbg_signal_open(struct inode *inode, struct file *file) | ||
658 | { | ||
659 | return single_open(file, omap_mux_dbg_signal_show, inode->i_private); | ||
660 | } | ||
661 | |||
662 | static const struct file_operations omap_mux_dbg_signal_fops = { | ||
663 | .open = omap_mux_dbg_signal_open, | ||
664 | .read = seq_read, | ||
665 | .write = omap_mux_dbg_signal_write, | ||
666 | .llseek = seq_lseek, | ||
667 | .release = single_release, | ||
668 | }; | ||
669 | |||
670 | static struct dentry *mux_dbg_dir; | ||
671 | |||
672 | static void __init omap_mux_dbg_init(void) | ||
673 | { | ||
674 | struct omap_mux_entry *e; | ||
675 | |||
676 | mux_dbg_dir = debugfs_create_dir("omap_mux", NULL); | ||
677 | if (!mux_dbg_dir) | ||
678 | return; | ||
679 | |||
680 | (void)debugfs_create_file("board", S_IRUGO, mux_dbg_dir, | ||
681 | NULL, &omap_mux_dbg_board_fops); | ||
682 | |||
683 | list_for_each_entry(e, &muxmodes, node) { | ||
684 | struct omap_mux *m = &e->mux; | ||
685 | |||
686 | (void)debugfs_create_file(m->muxnames[0], S_IWUGO, mux_dbg_dir, | ||
687 | m, &omap_mux_dbg_signal_fops); | ||
688 | } | ||
689 | } | ||
690 | |||
626 | #else | 691 | #else |
627 | #define omap34xx_cfg_reg NULL | 692 | static inline void omap_mux_dbg_init(void) |
693 | { | ||
694 | } | ||
695 | #endif /* CONFIG_DEBUG_FS */ | ||
696 | |||
697 | static void __init omap_mux_free_names(struct omap_mux *m) | ||
698 | { | ||
699 | int i; | ||
700 | |||
701 | for (i = 0; i < OMAP_MUX_NR_MODES; i++) | ||
702 | kfree(m->muxnames[i]); | ||
703 | |||
704 | #ifdef CONFIG_DEBUG_FS | ||
705 | for (i = 0; i < OMAP_MUX_NR_SIDES; i++) | ||
706 | kfree(m->balls[i]); | ||
628 | #endif | 707 | #endif |
629 | 708 | ||
630 | int __init omap2_mux_init(void) | 709 | } |
710 | |||
711 | /* Free all data except for GPIO pins unless CONFIG_DEBUG_FS is set */ | ||
712 | static int __init omap_mux_late_init(void) | ||
631 | { | 713 | { |
632 | if (cpu_is_omap24xx()) { | 714 | struct omap_mux_entry *e, *tmp; |
633 | arch_mux_cfg.pins = omap24xx_pins; | 715 | |
634 | arch_mux_cfg.size = OMAP24XX_PINS_SZ; | 716 | list_for_each_entry_safe(e, tmp, &muxmodes, node) { |
635 | arch_mux_cfg.cfg_reg = omap24xx_cfg_reg; | 717 | struct omap_mux *m = &e->mux; |
636 | } else if (cpu_is_omap34xx()) { | 718 | u16 mode = omap_mux_read(m->reg_offset); |
637 | arch_mux_cfg.pins = omap34xx_pins; | 719 | |
638 | arch_mux_cfg.size = OMAP34XX_PINS_SZ; | 720 | if (OMAP_MODE_GPIO(mode)) |
639 | arch_mux_cfg.cfg_reg = omap34xx_cfg_reg; | 721 | continue; |
722 | |||
723 | #ifndef CONFIG_DEBUG_FS | ||
724 | mutex_lock(&muxmode_mutex); | ||
725 | list_del(&e->node); | ||
726 | mutex_unlock(&muxmode_mutex); | ||
727 | omap_mux_free_names(m); | ||
728 | kfree(m); | ||
729 | #endif | ||
730 | |||
731 | } | ||
732 | |||
733 | omap_mux_dbg_init(); | ||
734 | |||
735 | return 0; | ||
736 | } | ||
737 | late_initcall(omap_mux_late_init); | ||
738 | |||
739 | static void __init omap_mux_package_fixup(struct omap_mux *p, | ||
740 | struct omap_mux *superset) | ||
741 | { | ||
742 | while (p->reg_offset != OMAP_MUX_TERMINATOR) { | ||
743 | struct omap_mux *s = superset; | ||
744 | int found = 0; | ||
745 | |||
746 | while (s->reg_offset != OMAP_MUX_TERMINATOR) { | ||
747 | if (s->reg_offset == p->reg_offset) { | ||
748 | *s = *p; | ||
749 | found++; | ||
750 | break; | ||
751 | } | ||
752 | s++; | ||
753 | } | ||
754 | if (!found) | ||
755 | printk(KERN_ERR "mux: Unknown entry offset 0x%x\n", | ||
756 | p->reg_offset); | ||
757 | p++; | ||
758 | } | ||
759 | } | ||
760 | |||
761 | #ifdef CONFIG_DEBUG_FS | ||
762 | |||
763 | static void __init omap_mux_package_init_balls(struct omap_ball *b, | ||
764 | struct omap_mux *superset) | ||
765 | { | ||
766 | while (b->reg_offset != OMAP_MUX_TERMINATOR) { | ||
767 | struct omap_mux *s = superset; | ||
768 | int found = 0; | ||
769 | |||
770 | while (s->reg_offset != OMAP_MUX_TERMINATOR) { | ||
771 | if (s->reg_offset == b->reg_offset) { | ||
772 | s->balls[0] = b->balls[0]; | ||
773 | s->balls[1] = b->balls[1]; | ||
774 | found++; | ||
775 | break; | ||
776 | } | ||
777 | s++; | ||
778 | } | ||
779 | if (!found) | ||
780 | printk(KERN_ERR "mux: Unknown ball offset 0x%x\n", | ||
781 | b->reg_offset); | ||
782 | b++; | ||
783 | } | ||
784 | } | ||
785 | |||
786 | #else /* CONFIG_DEBUG_FS */ | ||
787 | |||
788 | static inline void omap_mux_package_init_balls(struct omap_ball *b, | ||
789 | struct omap_mux *superset) | ||
790 | { | ||
791 | } | ||
792 | |||
793 | #endif /* CONFIG_DEBUG_FS */ | ||
794 | |||
795 | static int __init omap_mux_setup(char *options) | ||
796 | { | ||
797 | if (!options) | ||
798 | return 0; | ||
799 | |||
800 | omap_mux_options = options; | ||
801 | |||
802 | return 1; | ||
803 | } | ||
804 | __setup("omap_mux=", omap_mux_setup); | ||
805 | |||
806 | /* | ||
807 | * Note that the omap_mux=some.signal1=0x1234,some.signal2=0x1234 | ||
808 | * cmdline options only override the bootloader values. | ||
809 | * During development, please enable CONFIG_DEBUG_FS, and use the | ||
810 | * signal specific entries under debugfs. | ||
811 | */ | ||
812 | static void __init omap_mux_set_cmdline_signals(void) | ||
813 | { | ||
814 | char *options, *next_opt, *token; | ||
815 | |||
816 | if (!omap_mux_options) | ||
817 | return; | ||
818 | |||
819 | options = kmalloc(strlen(omap_mux_options) + 1, GFP_KERNEL); | ||
820 | if (!options) | ||
821 | return; | ||
822 | |||
823 | strcpy(options, omap_mux_options); | ||
824 | next_opt = options; | ||
825 | |||
826 | while ((token = strsep(&next_opt, ",")) != NULL) { | ||
827 | char *keyval, *name; | ||
828 | unsigned long val; | ||
829 | |||
830 | keyval = token; | ||
831 | name = strsep(&keyval, "="); | ||
832 | if (name) { | ||
833 | int res; | ||
834 | |||
835 | res = strict_strtoul(keyval, 0x10, &val); | ||
836 | if (res < 0) | ||
837 | continue; | ||
838 | |||
839 | omap_mux_init_signal(name, (u16)val); | ||
840 | } | ||
841 | } | ||
842 | |||
843 | kfree(options); | ||
844 | } | ||
845 | |||
846 | static int __init omap_mux_copy_names(struct omap_mux *src, | ||
847 | struct omap_mux *dst) | ||
848 | { | ||
849 | int i; | ||
850 | |||
851 | for (i = 0; i < OMAP_MUX_NR_MODES; i++) { | ||
852 | if (src->muxnames[i]) { | ||
853 | dst->muxnames[i] = | ||
854 | kmalloc(strlen(src->muxnames[i]) + 1, | ||
855 | GFP_KERNEL); | ||
856 | if (!dst->muxnames[i]) | ||
857 | goto free; | ||
858 | strcpy(dst->muxnames[i], src->muxnames[i]); | ||
859 | } | ||
860 | } | ||
861 | |||
862 | #ifdef CONFIG_DEBUG_FS | ||
863 | for (i = 0; i < OMAP_MUX_NR_SIDES; i++) { | ||
864 | if (src->balls[i]) { | ||
865 | dst->balls[i] = | ||
866 | kmalloc(strlen(src->balls[i]) + 1, | ||
867 | GFP_KERNEL); | ||
868 | if (!dst->balls[i]) | ||
869 | goto free; | ||
870 | strcpy(dst->balls[i], src->balls[i]); | ||
871 | } | ||
872 | } | ||
873 | #endif | ||
874 | |||
875 | return 0; | ||
876 | |||
877 | free: | ||
878 | omap_mux_free_names(dst); | ||
879 | return -ENOMEM; | ||
880 | |||
881 | } | ||
882 | |||
883 | #endif /* CONFIG_OMAP_MUX */ | ||
884 | |||
885 | static u16 omap_mux_get_by_gpio(int gpio) | ||
886 | { | ||
887 | struct omap_mux_entry *e; | ||
888 | u16 offset = OMAP_MUX_TERMINATOR; | ||
889 | |||
890 | list_for_each_entry(e, &muxmodes, node) { | ||
891 | struct omap_mux *m = &e->mux; | ||
892 | if (m->gpio == gpio) { | ||
893 | offset = m->reg_offset; | ||
894 | break; | ||
895 | } | ||
896 | } | ||
897 | |||
898 | return offset; | ||
899 | } | ||
900 | |||
901 | /* Needed for dynamic muxing of GPIO pins for off-idle */ | ||
902 | u16 omap_mux_get_gpio(int gpio) | ||
903 | { | ||
904 | u16 offset; | ||
905 | |||
906 | offset = omap_mux_get_by_gpio(gpio); | ||
907 | if (offset == OMAP_MUX_TERMINATOR) { | ||
908 | printk(KERN_ERR "mux: Could not get gpio%i\n", gpio); | ||
909 | return offset; | ||
910 | } | ||
911 | |||
912 | return omap_mux_read(offset); | ||
913 | } | ||
914 | |||
915 | /* Needed for dynamic muxing of GPIO pins for off-idle */ | ||
916 | void omap_mux_set_gpio(u16 val, int gpio) | ||
917 | { | ||
918 | u16 offset; | ||
919 | |||
920 | offset = omap_mux_get_by_gpio(gpio); | ||
921 | if (offset == OMAP_MUX_TERMINATOR) { | ||
922 | printk(KERN_ERR "mux: Could not set gpio%i\n", gpio); | ||
923 | return; | ||
924 | } | ||
925 | |||
926 | omap_mux_write(val, offset); | ||
927 | } | ||
928 | |||
929 | static struct omap_mux * __init omap_mux_list_add(struct omap_mux *src) | ||
930 | { | ||
931 | struct omap_mux_entry *entry; | ||
932 | struct omap_mux *m; | ||
933 | |||
934 | entry = kzalloc(sizeof(struct omap_mux_entry), GFP_KERNEL); | ||
935 | if (!entry) | ||
936 | return NULL; | ||
937 | |||
938 | m = &entry->mux; | ||
939 | memcpy(m, src, sizeof(struct omap_mux_entry)); | ||
940 | |||
941 | #ifdef CONFIG_OMAP_MUX | ||
942 | if (omap_mux_copy_names(src, m)) { | ||
943 | kfree(entry); | ||
944 | return NULL; | ||
945 | } | ||
946 | #endif | ||
947 | |||
948 | mutex_lock(&muxmode_mutex); | ||
949 | list_add_tail(&entry->node, &muxmodes); | ||
950 | mutex_unlock(&muxmode_mutex); | ||
951 | |||
952 | return m; | ||
953 | } | ||
954 | |||
955 | /* | ||
956 | * Note if CONFIG_OMAP_MUX is not selected, we will only initialize | ||
957 | * the GPIO to mux offset mapping that is needed for dynamic muxing | ||
958 | * of GPIO pins for off-idle. | ||
959 | */ | ||
960 | static void __init omap_mux_init_list(struct omap_mux *superset) | ||
961 | { | ||
962 | while (superset->reg_offset != OMAP_MUX_TERMINATOR) { | ||
963 | struct omap_mux *entry; | ||
964 | |||
965 | #ifdef CONFIG_OMAP_MUX | ||
966 | if (!superset->muxnames || !superset->muxnames[0]) { | ||
967 | superset++; | ||
968 | continue; | ||
969 | } | ||
970 | #else | ||
971 | /* Skip pins that are not muxed as GPIO by bootloader */ | ||
972 | if (!OMAP_MODE_GPIO(omap_mux_read(superset->reg_offset))) { | ||
973 | superset++; | ||
974 | continue; | ||
975 | } | ||
976 | #endif | ||
977 | |||
978 | entry = omap_mux_list_add(superset); | ||
979 | if (!entry) { | ||
980 | printk(KERN_ERR "mux: Could not add entry\n"); | ||
981 | return; | ||
982 | } | ||
983 | superset++; | ||
640 | } | 984 | } |
985 | } | ||
986 | |||
987 | #ifdef CONFIG_OMAP_MUX | ||
988 | |||
989 | static void omap_mux_init_package(struct omap_mux *superset, | ||
990 | struct omap_mux *package_subset, | ||
991 | struct omap_ball *package_balls) | ||
992 | { | ||
993 | if (package_subset) | ||
994 | omap_mux_package_fixup(package_subset, superset); | ||
995 | if (package_balls) | ||
996 | omap_mux_package_init_balls(package_balls, superset); | ||
997 | } | ||
641 | 998 | ||
642 | return omap_mux_register(&arch_mux_cfg); | 999 | static void omap_mux_init_signals(struct omap_board_mux *board_mux) |
1000 | { | ||
1001 | omap_mux_set_cmdline_signals(); | ||
1002 | omap_mux_write_array(board_mux); | ||
1003 | } | ||
1004 | |||
1005 | #else | ||
1006 | |||
1007 | static void omap_mux_init_package(struct omap_mux *superset, | ||
1008 | struct omap_mux *package_subset, | ||
1009 | struct omap_ball *package_balls) | ||
1010 | { | ||
1011 | } | ||
1012 | |||
1013 | static void omap_mux_init_signals(struct omap_board_mux *board_mux) | ||
1014 | { | ||
643 | } | 1015 | } |
644 | 1016 | ||
645 | #endif | 1017 | #endif |
1018 | |||
1019 | int __init omap_mux_init(u32 mux_pbase, u32 mux_size, | ||
1020 | struct omap_mux *superset, | ||
1021 | struct omap_mux *package_subset, | ||
1022 | struct omap_board_mux *board_mux, | ||
1023 | struct omap_ball *package_balls) | ||
1024 | { | ||
1025 | if (mux_base) | ||
1026 | return -EBUSY; | ||
1027 | |||
1028 | mux_phys = mux_pbase; | ||
1029 | mux_base = ioremap(mux_pbase, mux_size); | ||
1030 | if (!mux_base) { | ||
1031 | printk(KERN_ERR "mux: Could not ioremap\n"); | ||
1032 | return -ENODEV; | ||
1033 | } | ||
1034 | |||
1035 | omap_mux_init_package(superset, package_subset, package_balls); | ||
1036 | omap_mux_init_list(superset); | ||
1037 | omap_mux_init_signals(board_mux); | ||
1038 | |||
1039 | return 0; | ||
1040 | } | ||
1041 | |||
1042 | #endif /* CONFIG_ARCH_OMAP3 */ | ||
1043 | |||