diff options
Diffstat (limited to 'arch/arm/mach-omap1/mux.c')
-rw-r--r-- | arch/arm/mach-omap1/mux.c | 146 |
1 files changed, 133 insertions, 13 deletions
diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c index 52c70e5fcf65..e207bf7cb853 100644 --- a/arch/arm/mach-omap1/mux.c +++ b/arch/arm/mach-omap1/mux.c | |||
@@ -3,9 +3,9 @@ | |||
3 | * | 3 | * |
4 | * OMAP1 pin multiplexing configurations | 4 | * OMAP1 pin multiplexing configurations |
5 | * | 5 | * |
6 | * Copyright (C) 2003 - 2005 Nokia Corporation | 6 | * Copyright (C) 2003 - 2008 Nokia Corporation |
7 | * | 7 | * |
8 | * Written by Tony Lindgren <tony.lindgren@nokia.com> | 8 | * Written by Tony Lindgren |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
@@ -32,8 +32,10 @@ | |||
32 | 32 | ||
33 | #ifdef CONFIG_OMAP_MUX | 33 | #ifdef CONFIG_OMAP_MUX |
34 | 34 | ||
35 | static struct omap_mux_cfg arch_mux_cfg; | ||
36 | |||
35 | #ifdef CONFIG_ARCH_OMAP730 | 37 | #ifdef CONFIG_ARCH_OMAP730 |
36 | struct pin_config __initdata_or_module omap730_pins[] = { | 38 | static struct pin_config __initdata_or_module omap730_pins[] = { |
37 | MUX_CFG_730("E2_730_KBR0", 12, 21, 0, 20, 1, 0) | 39 | MUX_CFG_730("E2_730_KBR0", 12, 21, 0, 20, 1, 0) |
38 | MUX_CFG_730("J7_730_KBR1", 12, 25, 0, 24, 1, 0) | 40 | MUX_CFG_730("J7_730_KBR1", 12, 25, 0, 24, 1, 0) |
39 | MUX_CFG_730("E1_730_KBR2", 12, 29, 0, 28, 1, 0) | 41 | MUX_CFG_730("E1_730_KBR2", 12, 29, 0, 28, 1, 0) |
@@ -49,10 +51,14 @@ MUX_CFG_730("AA17_730_USB_DM", 2, 21, 0, 20, 0, 0) | |||
49 | MUX_CFG_730("W16_730_USB_PU_EN", 2, 25, 0, 24, 0, 0) | 51 | MUX_CFG_730("W16_730_USB_PU_EN", 2, 25, 0, 24, 0, 0) |
50 | MUX_CFG_730("W17_730_USB_VBUSI", 2, 29, 0, 28, 0, 0) | 52 | MUX_CFG_730("W17_730_USB_VBUSI", 2, 29, 0, 28, 0, 0) |
51 | }; | 53 | }; |
52 | #endif | 54 | #define OMAP730_PINS_SZ ARRAY_SIZE(omap730_pins) |
55 | #else | ||
56 | #define omap730_pins NULL | ||
57 | #define OMAP730_PINS_SZ 0 | ||
58 | #endif /* CONFIG_ARCH_OMAP730 */ | ||
53 | 59 | ||
54 | #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) | 60 | #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) |
55 | struct pin_config __initdata_or_module omap1xxx_pins[] = { | 61 | static struct pin_config __initdata_or_module omap1xxx_pins[] = { |
56 | /* | 62 | /* |
57 | * description mux mode mux pull pull pull pu_pd pu dbg | 63 | * description mux mode mux pull pull pull pu_pd pu dbg |
58 | * reg offset mode reg bit ena reg | 64 | * reg offset mode reg bit ena reg |
@@ -306,22 +312,136 @@ MUX_CFG("Y12_1610_CCP_CLKP", 8, 18, 6, 1, 24, 1, 1, 0, 0) | |||
306 | MUX_CFG("W13_1610_CCP_CLKM", 9, 0, 6, 1, 28, 1, 1, 0, 0) | 312 | MUX_CFG("W13_1610_CCP_CLKM", 9, 0, 6, 1, 28, 1, 1, 0, 0) |
307 | MUX_CFG("W14_1610_CCP_DATAP", 9, 24, 6, 2, 4, 1, 2, 0, 0) | 313 | MUX_CFG("W14_1610_CCP_DATAP", 9, 24, 6, 2, 4, 1, 2, 0, 0) |
308 | MUX_CFG("Y14_1610_CCP_DATAM", 9, 21, 6, 2, 3, 1, 2, 0, 0) | 314 | MUX_CFG("Y14_1610_CCP_DATAM", 9, 21, 6, 2, 3, 1, 2, 0, 0) |
309 | |||
310 | }; | 315 | }; |
316 | #define OMAP1XXX_PINS_SZ ARRAY_SIZE(omap1xxx_pins) | ||
317 | #else | ||
318 | #define omap1xxx_pins NULL | ||
319 | #define OMAP1XXX_PINS_SZ 0 | ||
311 | #endif /* CONFIG_ARCH_OMAP15XX || CONFIG_ARCH_OMAP16XX */ | 320 | #endif /* CONFIG_ARCH_OMAP15XX || CONFIG_ARCH_OMAP16XX */ |
312 | 321 | ||
313 | int __init omap1_mux_init(void) | 322 | int __init_or_module omap1_cfg_reg(const struct pin_config *cfg) |
314 | { | 323 | { |
315 | 324 | static DEFINE_SPINLOCK(mux_spin_lock); | |
316 | #ifdef CONFIG_ARCH_OMAP730 | 325 | unsigned long flags; |
317 | omap_mux_register(omap730_pins, ARRAY_SIZE(omap730_pins)); | 326 | unsigned int reg_orig = 0, reg = 0, pu_pd_orig = 0, pu_pd = 0, |
327 | pull_orig = 0, pull = 0; | ||
328 | unsigned int mask, warn = 0; | ||
329 | |||
330 | /* Check the mux register in question */ | ||
331 | if (cfg->mux_reg) { | ||
332 | unsigned tmp1, tmp2; | ||
333 | |||
334 | spin_lock_irqsave(&mux_spin_lock, flags); | ||
335 | reg_orig = omap_readl(cfg->mux_reg); | ||
336 | |||
337 | /* The mux registers always seem to be 3 bits long */ | ||
338 | mask = (0x7 << cfg->mask_offset); | ||
339 | tmp1 = reg_orig & mask; | ||
340 | reg = reg_orig & ~mask; | ||
341 | |||
342 | tmp2 = (cfg->mask << cfg->mask_offset); | ||
343 | reg |= tmp2; | ||
344 | |||
345 | if (tmp1 != tmp2) | ||
346 | warn = 1; | ||
347 | |||
348 | omap_writel(reg, cfg->mux_reg); | ||
349 | spin_unlock_irqrestore(&mux_spin_lock, flags); | ||
350 | } | ||
351 | |||
352 | /* Check for pull up or pull down selection on 1610 */ | ||
353 | if (!cpu_is_omap15xx()) { | ||
354 | if (cfg->pu_pd_reg && cfg->pull_val) { | ||
355 | spin_lock_irqsave(&mux_spin_lock, flags); | ||
356 | pu_pd_orig = omap_readl(cfg->pu_pd_reg); | ||
357 | mask = 1 << cfg->pull_bit; | ||
358 | |||
359 | if (cfg->pu_pd_val) { | ||
360 | if (!(pu_pd_orig & mask)) | ||
361 | warn = 1; | ||
362 | /* Use pull up */ | ||
363 | pu_pd = pu_pd_orig | mask; | ||
364 | } else { | ||
365 | if (pu_pd_orig & mask) | ||
366 | warn = 1; | ||
367 | /* Use pull down */ | ||
368 | pu_pd = pu_pd_orig & ~mask; | ||
369 | } | ||
370 | omap_writel(pu_pd, cfg->pu_pd_reg); | ||
371 | spin_unlock_irqrestore(&mux_spin_lock, flags); | ||
372 | } | ||
373 | } | ||
374 | |||
375 | /* Check for an associated pull down register */ | ||
376 | if (cfg->pull_reg) { | ||
377 | spin_lock_irqsave(&mux_spin_lock, flags); | ||
378 | pull_orig = omap_readl(cfg->pull_reg); | ||
379 | mask = 1 << cfg->pull_bit; | ||
380 | |||
381 | if (cfg->pull_val) { | ||
382 | if (pull_orig & mask) | ||
383 | warn = 1; | ||
384 | /* Low bit = pull enabled */ | ||
385 | pull = pull_orig & ~mask; | ||
386 | } else { | ||
387 | if (!(pull_orig & mask)) | ||
388 | warn = 1; | ||
389 | /* High bit = pull disabled */ | ||
390 | pull = pull_orig | mask; | ||
391 | } | ||
392 | |||
393 | omap_writel(pull, cfg->pull_reg); | ||
394 | spin_unlock_irqrestore(&mux_spin_lock, flags); | ||
395 | } | ||
396 | |||
397 | if (warn) { | ||
398 | #ifdef CONFIG_OMAP_MUX_WARNINGS | ||
399 | printk(KERN_WARNING "MUX: initialized %s\n", cfg->name); | ||
318 | #endif | 400 | #endif |
319 | 401 | } | |
320 | #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) | 402 | |
321 | omap_mux_register(omap1xxx_pins, ARRAY_SIZE(omap1xxx_pins)); | 403 | #ifdef CONFIG_OMAP_MUX_DEBUG |
404 | if (cfg->debug || warn) { | ||
405 | printk("MUX: Setting register %s\n", cfg->name); | ||
406 | printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n", | ||
407 | cfg->mux_reg_name, cfg->mux_reg, reg_orig, reg); | ||
408 | |||
409 | if (!cpu_is_omap15xx()) { | ||
410 | if (cfg->pu_pd_reg && cfg->pull_val) { | ||
411 | printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n", | ||
412 | cfg->pu_pd_name, cfg->pu_pd_reg, | ||
413 | pu_pd_orig, pu_pd); | ||
414 | } | ||
415 | } | ||
416 | |||
417 | if (cfg->pull_reg) | ||
418 | printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n", | ||
419 | cfg->pull_name, cfg->pull_reg, pull_orig, pull); | ||
420 | } | ||
322 | #endif | 421 | #endif |
323 | 422 | ||
423 | #ifdef CONFIG_OMAP_MUX_ERRORS | ||
424 | return warn ? -ETXTBSY : 0; | ||
425 | #else | ||
324 | return 0; | 426 | return 0; |
427 | #endif | ||
428 | } | ||
429 | |||
430 | int __init omap1_mux_init(void) | ||
431 | { | ||
432 | if (cpu_is_omap730()) { | ||
433 | arch_mux_cfg.pins = omap730_pins; | ||
434 | arch_mux_cfg.size = OMAP730_PINS_SZ; | ||
435 | arch_mux_cfg.cfg_reg = omap1_cfg_reg; | ||
436 | } | ||
437 | |||
438 | if (cpu_is_omap15xx() || cpu_is_omap16xx()) { | ||
439 | arch_mux_cfg.pins = omap1xxx_pins; | ||
440 | arch_mux_cfg.size = OMAP1XXX_PINS_SZ; | ||
441 | arch_mux_cfg.cfg_reg = omap1_cfg_reg; | ||
442 | } | ||
443 | |||
444 | return omap_mux_register(&arch_mux_cfg); | ||
325 | } | 445 | } |
326 | 446 | ||
327 | #endif | 447 | #endif |