xref: /openbmc/u-boot/drivers/gpio/mpc83xx_gpio.c (revision ee7bb5be)
1 /*
2  * Freescale MPC83xx GPIO handling.
3  *
4  * SPDX-License-Identifier:	GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <mpc83xx.h>
9 #include <asm/gpio.h>
10 #include <asm/io.h>
11 
12 #ifndef CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION
13 #define CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION 0
14 #endif
15 #ifndef CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION
16 #define CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION 0
17 #endif
18 #ifndef CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN
19 #define CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN 0
20 #endif
21 #ifndef CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN
22 #define CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN 0
23 #endif
24 #ifndef CONFIG_MPC83XX_GPIO_0_INIT_VALUE
25 #define CONFIG_MPC83XX_GPIO_0_INIT_VALUE 0
26 #endif
27 #ifndef CONFIG_MPC83XX_GPIO_1_INIT_VALUE
28 #define CONFIG_MPC83XX_GPIO_1_INIT_VALUE 0
29 #endif
30 
31 static unsigned int gpio_output_value[MPC83XX_GPIO_CTRLRS];
32 
33 /*
34  * Generic_GPIO primitives.
35  */
36 
37 int gpio_request(unsigned gpio, const char *label)
38 {
39 	if (gpio >= MAX_NUM_GPIOS)
40 		return -1;
41 
42 	return 0;
43 }
44 
45 int gpio_free(unsigned gpio)
46 {
47 	/* Do not set to input */
48 	return 0;
49 }
50 
51 /* set GPIO pin 'gpio' as an input */
52 int gpio_direction_input(unsigned gpio)
53 {
54 	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
55 	unsigned int ctrlr;
56 	unsigned int line;
57 	unsigned int line_mask;
58 
59 	/* 32-bits per controller */
60 	ctrlr = gpio >> 5;
61 	line = gpio & (0x1F);
62 
63 	/* Big endian */
64 	line_mask = 1 << (31 - line);
65 
66 	clrbits_be32(&im->gpio[ctrlr].dir, line_mask);
67 
68 	return 0;
69 }
70 
71 /* set GPIO pin 'gpio' as an output, with polarity 'value' */
72 int gpio_direction_output(unsigned gpio, int value)
73 {
74 	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
75 	unsigned int ctrlr;
76 	unsigned int line;
77 	unsigned int line_mask;
78 
79 	if (value != 0 && value != 1) {
80 		printf("Error: Value parameter must be 0 or 1.\n");
81 		return -1;
82 	}
83 
84 	gpio_set_value(gpio, value);
85 
86 	/* 32-bits per controller */
87 	ctrlr = gpio >> 5;
88 	line = gpio & (0x1F);
89 
90 	/* Big endian */
91 	line_mask = 1 << (31 - line);
92 
93 	/* Make the line output */
94 	setbits_be32(&im->gpio[ctrlr].dir, line_mask);
95 
96 	return 0;
97 }
98 
99 /* read GPIO IN value of pin 'gpio' */
100 int gpio_get_value(unsigned gpio)
101 {
102 	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
103 	unsigned int ctrlr;
104 	unsigned int line;
105 	unsigned int line_mask;
106 
107 	/* 32-bits per controller */
108 	ctrlr = gpio >> 5;
109 	line = gpio & (0x1F);
110 
111 	/* Big endian */
112 	line_mask = 1 << (31 - line);
113 
114 	/* Read the value and mask off the bit */
115 	return (in_be32(&im->gpio[ctrlr].dat) & line_mask) != 0;
116 }
117 
118 /* write GPIO OUT value to pin 'gpio' */
119 int gpio_set_value(unsigned gpio, int value)
120 {
121 	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
122 	unsigned int ctrlr;
123 	unsigned int line;
124 	unsigned int line_mask;
125 
126 	if (value != 0 && value != 1) {
127 		printf("Error: Value parameter must be 0 or 1.\n");
128 		return -1;
129 	}
130 
131 	/* 32-bits per controller */
132 	ctrlr = gpio >> 5;
133 	line = gpio & (0x1F);
134 
135 	/* Big endian */
136 	line_mask = 1 << (31 - line);
137 
138 	/* Update the local output buffer soft copy */
139 	gpio_output_value[ctrlr] =
140 		(gpio_output_value[ctrlr] & ~line_mask) | \
141 			(value ? line_mask : 0);
142 
143 	/* Write the output */
144 	out_be32(&im->gpio[ctrlr].dat, gpio_output_value[ctrlr]);
145 
146 	return 0;
147 }
148 
149 /* Configure GPIO registers early */
150 void mpc83xx_gpio_init_f(void)
151 {
152 	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
153 
154 #if MPC83XX_GPIO_CTRLRS >= 1
155 	out_be32(&im->gpio[0].dir, CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION);
156 	out_be32(&im->gpio[0].odr, CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN);
157 	out_be32(&im->gpio[0].dat, CONFIG_MPC83XX_GPIO_0_INIT_VALUE);
158 	out_be32(&im->gpio[0].ier, 0xFFFFFFFF); /* Clear all events */
159 	out_be32(&im->gpio[0].imr, 0);
160 	out_be32(&im->gpio[0].icr, 0);
161 #endif
162 
163 #if MPC83XX_GPIO_CTRLRS >= 2
164 	out_be32(&im->gpio[1].dir, CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION);
165 	out_be32(&im->gpio[1].odr, CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN);
166 	out_be32(&im->gpio[1].dat, CONFIG_MPC83XX_GPIO_1_INIT_VALUE);
167 	out_be32(&im->gpio[1].ier, 0xFFFFFFFF); /* Clear all events */
168 	out_be32(&im->gpio[1].imr, 0);
169 	out_be32(&im->gpio[1].icr, 0);
170 #endif
171 }
172 
173 /* Initialize GPIO soft-copies */
174 void mpc83xx_gpio_init_r(void)
175 {
176 #if MPC83XX_GPIO_CTRLRS >= 1
177 	gpio_output_value[0] = CONFIG_MPC83XX_GPIO_0_INIT_VALUE;
178 #endif
179 
180 #if MPC83XX_GPIO_CTRLRS >= 2
181 	gpio_output_value[1] = CONFIG_MPC83XX_GPIO_1_INIT_VALUE;
182 #endif
183 }
184