blob: a9afcb2dd6f1a7356b302f6ab74b87bb8aa52e78 [file] [log] [blame]
Joe Hershberger4b565792011-11-11 15:55:37 -06001/*
2 * Freescale MPC83xx GPIO handling.
3 *
4 * See file CREDITS for list of people who contributed to this
5 * project.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 */
22
23#include <common.h>
24#include <mpc83xx.h>
25#include <asm/gpio.h>
26#include <asm/io.h>
27
28#ifndef CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION
29#define CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION 0
30#endif
31#ifndef CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION
32#define CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION 0
33#endif
34#ifndef CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN
35#define CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN 0
36#endif
37#ifndef CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN
38#define CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN 0
39#endif
40#ifndef CONFIG_MPC83XX_GPIO_0_INIT_VALUE
41#define CONFIG_MPC83XX_GPIO_0_INIT_VALUE 0
42#endif
43#ifndef CONFIG_MPC83XX_GPIO_1_INIT_VALUE
44#define CONFIG_MPC83XX_GPIO_1_INIT_VALUE 0
45#endif
46
47static unsigned int gpio_output_value[MPC83XX_GPIO_CTRLRS];
48
49/*
50 * Generic_GPIO primitives.
51 */
52
53int gpio_request(unsigned gpio, const char *label)
54{
55 if (gpio >= MAX_NUM_GPIOS)
56 return -1;
57
58 return 0;
59}
60
61int gpio_free(unsigned gpio)
62{
63 /* Do not set to input */
64 return 0;
65}
66
67/* set GPIO pin 'gpio' as an input */
68int gpio_direction_input(unsigned gpio)
69{
70 immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
71 unsigned int ctrlr;
72 unsigned int line;
73 unsigned int line_mask;
74
75 /* 32-bits per controller */
76 ctrlr = gpio >> 5;
77 line = gpio & (0x1F);
78
79 /* Big endian */
80 line_mask = 1 << (31 - line);
81
82 clrbits_be32(&im->gpio[ctrlr].dir, line_mask);
83
84 return 0;
85}
86
87/* set GPIO pin 'gpio' as an output, with polarity 'value' */
88int gpio_direction_output(unsigned gpio, int value)
89{
90 immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
91 unsigned int ctrlr;
92 unsigned int line;
93 unsigned int line_mask;
94
95 if (value != 0 && value != 1) {
96 printf("Error: Value parameter must be 0 or 1.\n");
97 return -1;
98 }
99
100 gpio_set_value(gpio, value);
101
102 /* 32-bits per controller */
103 ctrlr = gpio >> 5;
104 line = gpio & (0x1F);
105
106 /* Big endian */
107 line_mask = 1 << (31 - line);
108
109 /* Make the line output */
110 setbits_be32(&im->gpio[ctrlr].dir, line_mask);
111
112 return 0;
113}
114
115/* read GPIO IN value of pin 'gpio' */
116int gpio_get_value(unsigned gpio)
117{
118 immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
119 unsigned int ctrlr;
120 unsigned int line;
121 unsigned int line_mask;
122
123 /* 32-bits per controller */
124 ctrlr = gpio >> 5;
125 line = gpio & (0x1F);
126
127 /* Big endian */
128 line_mask = 1 << (31 - line);
129
130 /* Read the value and mask off the bit */
131 return (in_be32(&im->gpio[ctrlr].dat) & line_mask) != 0;
132}
133
134/* write GPIO OUT value to pin 'gpio' */
135int gpio_set_value(unsigned gpio, int value)
136{
137 immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
138 unsigned int ctrlr;
139 unsigned int line;
140 unsigned int line_mask;
141
142 if (value != 0 && value != 1) {
143 printf("Error: Value parameter must be 0 or 1.\n");
144 return -1;
145 }
146
147 /* 32-bits per controller */
148 ctrlr = gpio >> 5;
149 line = gpio & (0x1F);
150
151 /* Big endian */
152 line_mask = 1 << (31 - line);
153
154 /* Update the local output buffer soft copy */
155 gpio_output_value[ctrlr] =
156 (gpio_output_value[ctrlr] & ~line_mask) | \
157 (value ? line_mask : 0);
158
159 /* Write the output */
160 out_be32(&im->gpio[ctrlr].dat, gpio_output_value[ctrlr]);
161
162 return 0;
163}
164
165/* Configure GPIO registers early */
166void mpc83xx_gpio_init_f()
167{
168 immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
169
170#if MPC83XX_GPIO_CTRLRS >= 1
171 out_be32(&im->gpio[0].dir, CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION);
172 out_be32(&im->gpio[0].odr, CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN);
173 out_be32(&im->gpio[0].dat, CONFIG_MPC83XX_GPIO_0_INIT_VALUE);
174 out_be32(&im->gpio[0].ier, 0xFFFFFFFF); /* Clear all events */
175 out_be32(&im->gpio[0].imr, 0);
176 out_be32(&im->gpio[0].icr, 0);
177#endif
178
179#if MPC83XX_GPIO_CTRLRS >= 2
180 out_be32(&im->gpio[1].dir, CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION);
181 out_be32(&im->gpio[1].odr, CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN);
182 out_be32(&im->gpio[1].dat, CONFIG_MPC83XX_GPIO_1_INIT_VALUE);
183 out_be32(&im->gpio[1].ier, 0xFFFFFFFF); /* Clear all events */
184 out_be32(&im->gpio[1].imr, 0);
185 out_be32(&im->gpio[1].icr, 0);
186#endif
187}
188
189/* Initialize GPIO soft-copies */
190void mpc83xx_gpio_init_r()
191{
192#if MPC83XX_GPIO_CTRLRS >= 1
193 gpio_output_value[0] = CONFIG_MPC83XX_GPIO_0_INIT_VALUE;
194#endif
195
196#if MPC83XX_GPIO_CTRLRS >= 2
197 gpio_output_value[1] = CONFIG_MPC83XX_GPIO_1_INIT_VALUE;
198#endif
199}