xref: /openbmc/u-boot/drivers/gpio/mpc83xx_gpio.c (revision bfc93fb4)
1 /*
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 
47 static unsigned int gpio_output_value[MPC83XX_GPIO_CTRLRS];
48 
49 /*
50  * Generic_GPIO primitives.
51  */
52 
53 int gpio_request(unsigned gpio, const char *label)
54 {
55 	if (gpio >= MAX_NUM_GPIOS)
56 		return -1;
57 
58 	return 0;
59 }
60 
61 int gpio_free(unsigned gpio)
62 {
63 	/* Do not set to input */
64 	return 0;
65 }
66 
67 /* set GPIO pin 'gpio' as an input */
68 int 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' */
88 int 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' */
116 int 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' */
135 int 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 */
166 void 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 */
190 void 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 }
200