blob: dcd78e7e88e5356bb6a5ee8bc02de5ce692a93dd [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Joe Hershberger4b565792011-11-11 15:55:37 -06002/*
3 * Freescale MPC83xx GPIO handling.
Joe Hershberger4b565792011-11-11 15:55:37 -06004 */
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
30static unsigned int gpio_output_value[MPC83XX_GPIO_CTRLRS];
31
32/*
33 * Generic_GPIO primitives.
34 */
35
36int gpio_request(unsigned gpio, const char *label)
37{
38 if (gpio >= MAX_NUM_GPIOS)
39 return -1;
40
41 return 0;
42}
43
44int gpio_free(unsigned gpio)
45{
46 /* Do not set to input */
47 return 0;
48}
49
50/* set GPIO pin 'gpio' as an input */
51int 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' */
71int 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' */
99int 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' */
118int 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 */
Kim Phillips8121d3c2012-10-29 13:34:41 +0000149void mpc83xx_gpio_init_f(void)
Joe Hershberger4b565792011-11-11 15:55:37 -0600150{
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 */
Kim Phillips8121d3c2012-10-29 13:34:41 +0000173void mpc83xx_gpio_init_r(void)
Joe Hershberger4b565792011-11-11 15:55:37 -0600174{
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}