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