summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/gpio-imx31.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx31/gpio-imx31.c')
-rw-r--r--firmware/target/arm/imx31/gpio-imx31.c125
1 files changed, 66 insertions, 59 deletions
diff --git a/firmware/target/arm/imx31/gpio-imx31.c b/firmware/target/arm/imx31/gpio-imx31.c
index 944f70eae3..42d0a42188 100644
--- a/firmware/target/arm/imx31/gpio-imx31.c
+++ b/firmware/target/arm/imx31/gpio-imx31.c
@@ -31,67 +31,85 @@ extern void UIE_VECTOR(void);
31/* Event lists are allocated for the specific target */ 31/* Event lists are allocated for the specific target */
32#if (GPIO_EVENT_MASK & USE_GPIO1_EVENTS) 32#if (GPIO_EVENT_MASK & USE_GPIO1_EVENTS)
33static __attribute__((interrupt("IRQ"))) void GPIO1_HANDLER(void); 33static __attribute__((interrupt("IRQ"))) void GPIO1_HANDLER(void);
34extern const struct gpio_event_list gpio1_event_list; 34extern const struct gpio_event gpio1_events[GPIO1_NUM_EVENTS];
35#endif 35#endif
36 36
37#if (GPIO_EVENT_MASK & USE_GPIO2_EVENTS) 37#if (GPIO_EVENT_MASK & USE_GPIO2_EVENTS)
38static __attribute__((interrupt("IRQ"))) void GPIO2_HANDLER(void); 38static __attribute__((interrupt("IRQ"))) void GPIO2_HANDLER(void);
39extern const struct gpio_event_list gpio2_event_list; 39extern const struct gpio_event gpio2_events[GPIO2_NUM_EVENTS];
40#endif 40#endif
41 41
42#if (GPIO_EVENT_MASK & USE_GPIO3_EVENTS) 42#if (GPIO_EVENT_MASK & USE_GPIO3_EVENTS)
43static __attribute__((interrupt("IRQ"))) void GPIO3_HANDLER(void); 43static __attribute__((interrupt("IRQ"))) void GPIO3_HANDLER(void);
44extern const struct gpio_event_list gpio3_event_list; 44extern const struct gpio_event gpio3_events[GPIO3_NUM_EVENTS];
45#endif 45#endif
46 46
47static struct gpio_module_descriptor 47#define DR (0x00 / sizeof (unsigned long)) /* 00h */
48#define GDIR (0x04 / sizeof (unsigned long)) /* 04h */
49#define PSR (0x08 / sizeof (unsigned long)) /* 08h */
50#define ICR (0x0C / sizeof (unsigned long)) /* 0Ch ICR1,2 */
51#define IMR (0x14 / sizeof (unsigned long)) /* 14h */
52#define ISR (0x18 / sizeof (unsigned long))
53
54static const struct gpio_module_desc
48{ 55{
49 struct gpio_map * const base; /* Module base address */ 56 volatile unsigned long * const base; /* Module base address */
50 enum IMX31_INT_LIST ints; /* AVIC int number */ 57 void (* const handler)(void); /* Interrupt function */
51 void (*handler)(void); /* Interrupt function */ 58 const struct gpio_event * const events; /* Event handler list */
52 const struct gpio_event_list *list; /* Event handler list */ 59 const uint8_t ints; /* AVIC int number */
60 const uint8_t int_priority; /* AVIC int priority */
61 const uint8_t count; /* Number of events */
53} gpio_descs[GPIO_NUM_GPIO] = 62} gpio_descs[GPIO_NUM_GPIO] =
54{ 63{
55#if (GPIO_EVENT_MASK & USE_GPIO1_EVENTS) 64#if (GPIO_EVENT_MASK & USE_GPIO1_EVENTS)
56 { 65 {
57 .base = (struct gpio_map *)GPIO1_BASE_ADDR, 66 .base = (unsigned long *)GPIO1_BASE_ADDR,
58 .ints = INT_GPIO1, 67 .ints = INT_GPIO1,
59 .handler = GPIO1_HANDLER, 68 .handler = GPIO1_HANDLER,
69 .events = gpio1_events,
70 .count = GPIO1_NUM_EVENTS,
71 .int_priority = GPIO1_INT_PRIO
60 }, 72 },
61#endif 73#endif
62#if (GPIO_EVENT_MASK & USE_GPIO2_EVENTS) 74#if (GPIO_EVENT_MASK & USE_GPIO2_EVENTS)
63 { 75 {
64 .base = (struct gpio_map *)GPIO2_BASE_ADDR, 76 .base = (unsigned long *)GPIO2_BASE_ADDR,
65 .ints = INT_GPIO2, 77 .ints = INT_GPIO2,
66 .handler = GPIO2_HANDLER, 78 .handler = GPIO2_HANDLER,
79 .events = gpio2_events,
80 .count = GPIO2_NUM_EVENTS,
81 .int_priority = GPIO2_INT_PRIO
67 }, 82 },
68#endif 83#endif
69#if (GPIO_EVENT_MASK & USE_GPIO3_EVENTS) 84#if (GPIO_EVENT_MASK & USE_GPIO3_EVENTS)
70 { 85 {
71 .base = (struct gpio_map *)GPIO3_BASE_ADDR, 86 .base = (unsigned long *)GPIO3_BASE_ADDR,
72 .ints = INT_GPIO3, 87 .ints = INT_GPIO3,
73 .handler = GPIO3_HANDLER, 88 .handler = GPIO3_HANDLER,
89 .events = gpio3_events,
90 .count = GPIO3_NUM_EVENTS,
91 .int_priority = GPIO3_INT_PRIO,
74 }, 92 },
75#endif 93#endif
76}; 94};
77 95
78static void gpio_call_events(const struct gpio_module_descriptor * const desc) 96static void gpio_call_events(enum gpio_module_number gpio)
79{ 97{
80 const struct gpio_event_list * const list = desc->list; 98 const struct gpio_module_desc * const desc = &gpio_descs[gpio];
81 struct gpio_map * const base = desc->base; 99 volatile unsigned long * const base = desc->base;
82 const struct gpio_event * event, *event_last; 100 const struct gpio_event * event, *event_last;
83 101
84 /* Intersect pending and unmasked bits */ 102 event = desc->events;
85 uint32_t pnd = base->isr & base->imr; 103 event_last = event + desc->count;
86 104
87 event = list->events; 105 /* Intersect pending and unmasked bits */
88 event_last = event + list->count; 106 unsigned long pnd = base[ISR] & base[IMR];
89 107
90 /* Call each event handler in order */ 108 /* Call each event handler in order */
91 /* .count is surely expected to be > 0 */ 109 /* .count is surely expected to be > 0 */
92 do 110 do
93 { 111 {
94 uint32_t mask = event->mask; 112 unsigned long mask = event->mask;
95 113
96 if (pnd & mask) 114 if (pnd & mask)
97 { 115 {
@@ -114,74 +132,63 @@ static void gpio_call_events(const struct gpio_module_descriptor * const desc)
114#if (GPIO_EVENT_MASK & USE_GPIO1_EVENTS) 132#if (GPIO_EVENT_MASK & USE_GPIO1_EVENTS)
115static __attribute__((interrupt("IRQ"))) void GPIO1_HANDLER(void) 133static __attribute__((interrupt("IRQ"))) void GPIO1_HANDLER(void)
116{ 134{
117 gpio_call_events(&gpio_descs[GPIO1_NUM]); 135 gpio_call_events(GPIO1_NUM);
118} 136}
119#endif 137#endif
120 138
121#if (GPIO_EVENT_MASK & USE_GPIO2_EVENTS) 139#if (GPIO_EVENT_MASK & USE_GPIO2_EVENTS)
122static __attribute__((interrupt("IRQ"))) void GPIO2_HANDLER(void) 140static __attribute__((interrupt("IRQ"))) void GPIO2_HANDLER(void)
123{ 141{
124 gpio_call_events(&gpio_descs[GPIO2_NUM]); 142 gpio_call_events(GPIO2_NUM);
125} 143}
126#endif 144#endif
127 145
128#if (GPIO_EVENT_MASK & USE_GPIO3_EVENTS) 146#if (GPIO_EVENT_MASK & USE_GPIO3_EVENTS)
129static __attribute__((interrupt("IRQ"))) void GPIO3_HANDLER(void) 147static __attribute__((interrupt("IRQ"))) void GPIO3_HANDLER(void)
130{ 148{
131 gpio_call_events(&gpio_descs[GPIO3_NUM]); 149 gpio_call_events(GPIO3_NUM);
132} 150}
133#endif 151#endif
134 152
135void gpio_init(void) 153void gpio_init(void)
136{ 154{
137 /* Mask-out GPIO interrupts - enable what's wanted later */ 155 /* Mask-out GPIO interrupts - enable what's wanted later */
138 GPIO1_IMR = 0; 156 int i;
139 GPIO2_IMR = 0; 157 for (i = 0; i < GPIO_NUM_GPIO; i++)
140 GPIO3_IMR = 0; 158 gpio_descs[i].base[IMR] = 0;
141
142 /* Init the externally-defined event lists for each port */
143#if (GPIO_EVENT_MASK & USE_GPIO1_EVENTS)
144 gpio_descs[GPIO1_NUM].list = &gpio1_event_list;
145#endif
146#if (GPIO_EVENT_MASK & USE_GPIO2_EVENTS)
147 gpio_descs[GPIO2_NUM].list = &gpio2_event_list;
148#endif
149#if (GPIO_EVENT_MASK & USE_GPIO3_EVENTS)
150 gpio_descs[GPIO3_NUM].list = &gpio3_event_list;
151#endif
152} 159}
153 160
154bool gpio_enable_event(enum gpio_event_ids id) 161bool gpio_enable_event(enum gpio_event_ids id)
155{ 162{
156 const struct gpio_module_descriptor * const desc = &gpio_descs[id >> 5]; 163 const struct gpio_module_desc * const desc = &gpio_descs[id >> 5];
157 const struct gpio_event * const event = &desc->list->events[id & 31]; 164 const struct gpio_event * const event = &desc->events[id & 31];
158 struct gpio_map * const base = desc->base; 165 volatile unsigned long * const base = desc->base;
159 volatile uint32_t *icr; 166 volatile unsigned long *icr;
160 uint32_t mask, line; 167 unsigned long mask, line;
161 uint32_t imr; 168 unsigned long imr;
162 int shift; 169 int shift;
163 170
164 int oldlevel = disable_irq_save(); 171 int oldlevel = disable_irq_save();
165 172
166 imr = base->imr; 173 imr = base[IMR];
167 174
168 if (imr == 0) 175 if (imr == 0)
169 { 176 {
170 /* First enabled interrupt for this GPIO */ 177 /* First enabled interrupt for this GPIO */
171 avic_enable_int(desc->ints, INT_TYPE_IRQ, desc->list->ints_priority, 178 avic_enable_int(desc->ints, INT_TYPE_IRQ, desc->int_priority,
172 desc->handler); 179 desc->handler);
173 } 180 }
174 181
175 /* Set the line sense */ 182 /* Set the line sense */
176 line = find_first_set_bit(event->mask); 183 line = find_first_set_bit(event->mask);
177 icr = &base->icr[line >> 4]; 184 icr = &base[ICR + (line >> 4)];
178 shift = (line & 15) << 1; 185 shift = 2*(line & 15);
179 mask = GPIO_SENSE_CONFIG_MASK << shift; 186 mask = GPIO_SENSE_CONFIG_MASK << shift;
180 187
181 *icr = (*icr & ~mask) | ((event->sense << shift) & mask); 188 *icr = (*icr & ~mask) | ((event->sense << shift) & mask);
182 189
183 /* Unmask the line */ 190 /* Unmask the line */
184 base->imr = imr | event->mask; 191 base[IMR] = imr | event->mask;
185 192
186 restore_irq(oldlevel); 193 restore_irq(oldlevel);
187 194
@@ -190,18 +197,18 @@ bool gpio_enable_event(enum gpio_event_ids id)
190 197
191void gpio_disable_event(enum gpio_event_ids id) 198void gpio_disable_event(enum gpio_event_ids id)
192{ 199{
193 const struct gpio_module_descriptor * const desc = &gpio_descs[id >> 5]; 200 const struct gpio_module_desc * const desc = &gpio_descs[id >> 5];
194 const struct gpio_event * const event = &desc->list->events[id & 31]; 201 const struct gpio_event * const event = &desc->events[id & 31];
195 struct gpio_map * const base = desc->base; 202 volatile unsigned long * const base = desc->base;
196 uint32_t imr; 203 unsigned long imr;
197 204
198 int oldlevel = disable_irq_save(); 205 int oldlevel = disable_irq_save();
199 206
200 /* Remove bit from mask */ 207 /* Remove bit from mask */
201 imr = base->imr & ~event->mask; 208 imr = base[IMR] & ~event->mask;
202 209
203 /* Mask the line */ 210 /* Mask the line */
204 base->imr = imr; 211 base[IMR] = imr;
205 212
206 if (imr == 0) 213 if (imr == 0)
207 { 214 {