]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - cpu/arm926ejs/mx28/pinctrl.c
imported Ka-Ro specific additions to U-Boot 2009.08 for TX28
[karo-tx-uboot.git] / cpu / arm926ejs / mx28 / pinctrl.c
1 /*
2  *
3  * (C) Copyright 2009-2010 Freescale Semiconductor, Inc.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19 #include <common.h>
20 #include <asm/arch/regs-pinctrl.h>
21 #include <asm/arch/pinctrl.h>
22
23 void pin_gpio_direction(u32 id, u32 output)
24 {
25         u32 addr;
26         u32 bank = PINID_2_BANK(id);
27         u32 pin = PINID_2_PIN(id);
28
29         addr = REGS_PINCTRL_BASE + HW_PINCTRL_DOE0;
30         addr += 0x10 * bank;
31         if (output)
32                 REG_SET_ADDR(addr, 1 << pin);
33         else
34                 REG_CLR_ADDR(addr, 1 << pin);
35 }
36
37 u32 pin_gpio_get(u32 id)
38 {
39         u32 addr, val;
40         u32 bank = PINID_2_BANK(id);
41         u32 pin = PINID_2_PIN(id);
42
43         addr = REGS_PINCTRL_BASE + HW_PINCTRL_DIN0;
44         addr += 0x10 * bank;
45         val = REG_RD_ADDR(addr);
46
47         return !!(val & (1 << pin));
48 }
49
50 void pin_gpio_set(u32 id, u32 val)
51 {
52         u32 addr;
53         u32 bank = PINID_2_BANK(id);
54         u32 pin = PINID_2_PIN(id);
55
56         addr = REGS_PINCTRL_BASE + HW_PINCTRL_DOUT0;
57         addr += 0x10 * bank;
58         if (val)
59                 REG_SET_ADDR(addr, 1 << pin);
60         else
61                 REG_CLR_ADDR(addr, 1 << pin);
62 }
63
64 void pin_set_strength(u32 id, enum pad_strength strength)
65 {
66         u32 addr;
67         u32 bank = PINID_2_BANK(id);
68         u32 pin = PINID_2_PIN(id);
69         u32 val;
70
71         addr = REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE0;
72         addr += 0x40 * bank + 0x10 * (pin >> 3);
73         pin &= 0x7;
74
75         /* Don't use REG_CLR_ADDR/REG_SET_ADDR to prevent unwanted pin state transitions */
76         val = REG_RD_ADDR(addr);
77         val &= ~(0x7 << (pin * 4));
78         val |= (strength & 0x7) << (pin * 4);
79         REG_WR_ADDR(addr, val);
80 }
81
82 void pin_set_voltage(u32 id, enum pad_voltage volt)
83 {
84         u32 addr;
85         u32 bank = PINID_2_BANK(id);
86         u32 pin = PINID_2_PIN(id);
87
88         addr = REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE0;
89         addr += 0x40 * bank + 0x10 * (pin >> 3);
90         pin &= 0x7;
91         if (volt == PAD_1V8)
92                 REG_CLR_ADDR(addr, 1 << (pin * 4 + 2));
93         else
94                 REG_SET_ADDR(addr, 1 << (pin * 4 + 2));
95 }
96
97 void pin_set_pullup(u32 id, u32 pullup)
98 {
99         u32 addr;
100         u32 bank = PINID_2_BANK(id);
101         u32 pin = PINID_2_PIN(id);
102
103         addr = REGS_PINCTRL_BASE + HW_PINCTRL_PULL0;
104         addr += 0x10 * bank;
105         if (pullup)
106                 REG_SET_ADDR(addr, 1 << pin);
107         else
108                 REG_CLR_ADDR(addr, 1 << pin);
109 }
110
111 void pin_set_type(u32 id, enum pin_fun cfg)
112 {
113         u32 addr;
114         u32 bank = PINID_2_BANK(id);
115         u32 pin = PINID_2_PIN(id);
116         u32 val;
117
118         addr = REGS_PINCTRL_BASE + HW_PINCTRL_MUXSEL0;
119         addr += 0x20 * bank + 0x10 * (pin >> 4);
120         pin &= 0xf;
121
122         /* Don't use _CLR/_SET to prevent unwanted pin state transitions */
123         val = REG_RD_ADDR(addr);
124         val &= ~(0x3 << (pin * 2));
125         val |= (cfg & 0x3) << (pin * 2);
126         REG_WR_ADDR(addr, val);
127 }
128
129 void pin_set_group(struct pin_group *pin_group)
130 {
131         u32 p;
132         struct pin_desc *pin;
133
134         for (p = 0; p < pin_group->nr_pins; p++) {
135                 pin = &pin_group->pins[p];
136                 pin_set_type(pin->id, pin->fun);
137                 pin_set_strength(pin->id, pin->strength);
138                 pin_set_voltage(pin->id, pin->voltage);
139                 pin_set_pullup(pin->id, pin->pullup);
140         }
141 }