]>
Commit | Line | Data |
---|---|---|
d91a672b MV |
1 | /* |
2 | * Copyright 2004-2006,2010 Freescale Semiconductor, Inc. All Rights Reserved. | |
3 | * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de> | |
4 | * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH, | |
5 | * <armlinux@phytec.de> | |
6 | * | |
1a459660 | 7 | * SPDX-License-Identifier: GPL-2.0+ |
d91a672b MV |
8 | */ |
9 | ||
10 | #include <common.h> | |
11 | #include <asm/errno.h> | |
12 | #include <asm/io.h> | |
13 | #include <asm/arch/clock.h> | |
14 | #include <asm/arch/iomux.h> | |
15 | #include <asm/arch/imx-regs.h> | |
16 | ||
17 | #if defined(CONFIG_MX23) | |
18 | #define DRIVE_OFFSET 0x200 | |
19 | #define PULL_OFFSET 0x400 | |
20 | #elif defined(CONFIG_MX28) | |
21 | #define DRIVE_OFFSET 0x300 | |
22 | #define PULL_OFFSET 0x600 | |
23 | #else | |
24 | #error "Please select CONFIG_MX23 or CONFIG_MX28" | |
25 | #endif | |
26 | ||
27 | /* | |
28 | * configures a single pad in the iomuxer | |
29 | */ | |
30 | int mxs_iomux_setup_pad(iomux_cfg_t pad) | |
31 | { | |
32 | u32 reg, ofs, bp, bm; | |
33 | void *iomux_base = (void *)MXS_PINCTRL_BASE; | |
ddcf13b1 | 34 | struct mxs_register_32 *mxs_reg; |
d91a672b MV |
35 | |
36 | /* muxsel */ | |
37 | ofs = 0x100; | |
38 | ofs += PAD_BANK(pad) * 0x20 + PAD_PIN(pad) / 16 * 0x10; | |
39 | bp = PAD_PIN(pad) % 16 * 2; | |
40 | bm = 0x3 << bp; | |
41 | reg = readl(iomux_base + ofs); | |
42 | reg &= ~bm; | |
43 | reg |= PAD_MUXSEL(pad) << bp; | |
44 | writel(reg, iomux_base + ofs); | |
45 | ||
46 | /* drive */ | |
47 | ofs = DRIVE_OFFSET; | |
48 | ofs += PAD_BANK(pad) * 0x40 + PAD_PIN(pad) / 8 * 0x10; | |
49 | /* mA */ | |
50 | if (PAD_MA_VALID(pad)) { | |
51 | bp = PAD_PIN(pad) % 8 * 4; | |
52 | bm = 0x3 << bp; | |
53 | reg = readl(iomux_base + ofs); | |
54 | reg &= ~bm; | |
55 | reg |= PAD_MA(pad) << bp; | |
56 | writel(reg, iomux_base + ofs); | |
57 | } | |
58 | /* vol */ | |
59 | if (PAD_VOL_VALID(pad)) { | |
60 | bp = PAD_PIN(pad) % 8 * 4 + 2; | |
ddcf13b1 | 61 | mxs_reg = (struct mxs_register_32 *)(iomux_base + ofs); |
d91a672b MV |
62 | if (PAD_VOL(pad)) |
63 | writel(1 << bp, &mxs_reg->reg_set); | |
64 | else | |
65 | writel(1 << bp, &mxs_reg->reg_clr); | |
66 | } | |
67 | ||
68 | /* pull */ | |
69 | if (PAD_PULL_VALID(pad)) { | |
70 | ofs = PULL_OFFSET; | |
71 | ofs += PAD_BANK(pad) * 0x10; | |
72 | bp = PAD_PIN(pad); | |
ddcf13b1 | 73 | mxs_reg = (struct mxs_register_32 *)(iomux_base + ofs); |
d91a672b MV |
74 | if (PAD_PULL(pad)) |
75 | writel(1 << bp, &mxs_reg->reg_set); | |
76 | else | |
77 | writel(1 << bp, &mxs_reg->reg_clr); | |
78 | } | |
79 | ||
80 | return 0; | |
81 | } | |
82 | ||
83 | int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count) | |
84 | { | |
85 | const iomux_cfg_t *p = pad_list; | |
86 | int i; | |
87 | int ret; | |
88 | ||
89 | for (i = 0; i < count; i++) { | |
90 | ret = mxs_iomux_setup_pad(*p); | |
91 | if (ret) | |
92 | return ret; | |
93 | p++; | |
94 | } | |
95 | ||
96 | return 0; | |
97 | } |