summaryrefslogtreecommitdiff
path: root/firmware/target/arm/s5l8702/gpio-s5l8702.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/s5l8702/gpio-s5l8702.c')
-rw-r--r--firmware/target/arm/s5l8702/gpio-s5l8702.c187
1 files changed, 187 insertions, 0 deletions
diff --git a/firmware/target/arm/s5l8702/gpio-s5l8702.c b/firmware/target/arm/s5l8702/gpio-s5l8702.c
new file mode 100644
index 0000000000..d3ccb032bc
--- /dev/null
+++ b/firmware/target/arm/s5l8702/gpio-s5l8702.c
@@ -0,0 +1,187 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2014 Cástor Muñoz
11 * Code based on openiBoot project
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22#include <stdint.h>
23
24#include "config.h"
25#include "system.h"
26#include "gpio-s5l8702.h"
27#include "panic.h"
28
29
30/*
31 * XXX: disabled, not used and never tested!
32 */
33#if 0
34/* handlers list */
35#define GPIOIC_MAX_HANDLERS 2
36
37#define FLAG_TYPE_LEVEL (1 << 0)
38#define FLAG_AUTOFLIP (1 << 1)
39
40struct gpio_handler {
41 int gpio_n;
42 void (*isr)(void);
43 int flags;
44};
45static struct gpio_handler l_handlers[GPIOIC_MAX_HANDLERS] IDATA_ATTR;
46static int n_handlers = 0;
47
48
49/* API */
50void INIT_ATTR gpio_init(void)
51{
52 /* TODO: initialize GPIO ports for minimum power consumption */
53}
54
55uint32_t gpio_group_get(int group)
56{
57 uint32_t pcon = PCON(group);
58 uint32_t pdat = PDAT(group);
59 uint32_t group_cfg = 0;
60 int i;
61
62 for (i = 0; i < 8; i++) {
63 int pin_cfg = pcon & 0xF;
64 if (pin_cfg == 1) /* output */
65 pin_cfg = 0xE | ((pdat >> i) & 1);
66 group_cfg = (group_cfg >> 4) | (pin_cfg << 28);
67 pcon >>= 4;
68 }
69
70 return group_cfg;
71}
72
73void gpio_group_set(int group, uint32_t mask, uint32_t cfg)
74{
75 PCON(group) = (PCON(group) & ~mask) | (cfg & mask);
76}
77
78void gpio_int_register(int gpio_n, void *isr, int type, int level, int autoflip)
79{
80 if (n_handlers >= GPIOIC_MAX_HANDLERS)
81 panicf("gpio_int_register(): too many handlers!");
82
83 int group = IC_GROUP(gpio_n);
84 int index = IC_IDX(gpio_n);
85
86 int flags = disable_irq_save();
87
88 /* fill handler struct */
89 struct gpio_handler *handler = &l_handlers[n_handlers++];
90
91 handler->gpio_n = gpio_n;
92 handler->isr = isr;
93 handler->flags = (type ? FLAG_TYPE_LEVEL : 0)
94 | (autoflip ? FLAG_AUTOFLIP : 0);
95
96 /* configure */
97 GPIOIC_INTTYPE(group) |=
98 (type ? GPIOIC_INTTYPE_LEVEL : GPIOIC_INTTYPE_EDGE) << index;
99 GPIOIC_INTLEVEL(group) |=
100 (level ? GPIOIC_INTLEVEL_HIGH : GPIOIC_INTLEVEL_LOW) << index;
101
102 restore_irq(flags);
103
104 /* XXX: valid only for gpio_n = 0..127 (IRQ_EXT0..IRQ_EXT3) */
105 VIC0INTENABLE = 1 << (IRQ_EXT0 + (gpio_n >> 5));
106}
107
108void gpio_int_enable(int gpio_n)
109{
110 int group = IC_GROUP(gpio_n);
111 uint32_t bit_mask = 1 << IC_IDX(gpio_n);
112
113 int flags = disable_irq_save();
114 GPIOIC_INTSTAT(group) = bit_mask; /* clear */
115 GPIOIC_INTEN(group) |= bit_mask; /* enable */
116 restore_irq(flags);
117}
118
119void gpio_int_disable(int gpio_n)
120{
121 int group = IC_GROUP(gpio_n);
122 uint32_t bit_mask = 1 << IC_IDX(gpio_n);
123
124 int flags = disable_irq_save();
125 GPIOIC_INTEN(group) &= ~bit_mask; /* disable */
126 GPIOIC_INTSTAT(group) = bit_mask; /* clear */
127 restore_irq(flags);
128}
129
130
131/* ISR */
132void ICODE_ATTR gpio_handler(int group)
133{
134 int i;
135 struct gpio_handler *handler;
136 uint32_t ints, bit_mask;
137
138 ints = GPIOIC_INTSTAT(group) & GPIOIC_INTEN(group);
139
140 for (i = 0; i < n_handlers; i++) {
141 handler = &l_handlers[i];
142
143 if (IC_GROUP(handler->gpio_n) != group)
144 continue;
145
146 bit_mask = 1 << IC_IDX(handler->gpio_n);
147
148 if (ints & bit_mask) {
149 if ((handler->flags & FLAG_TYPE_LEVEL) == 0)
150 GPIOIC_INTSTAT(group) = bit_mask; /* clear */
151
152 if (handler->flags & FLAG_AUTOFLIP)
153 GPIOIC_INTLEVEL(group) ^= bit_mask; /* swap level */
154
155 if (handler->isr)
156 handler->isr(); /* exec GPIO handler */
157
158 GPIOIC_INTSTAT(group) = bit_mask; /* clear */
159 }
160 }
161}
162
163void ICODE_ATTR INT_EXT0(void)
164{
165 gpio_handler(6);
166}
167
168void ICODE_ATTR INT_EXT1(void)
169{
170 gpio_handler(5);
171}
172
173void ICODE_ATTR INT_EXT2(void)
174{
175 gpio_handler(4);
176}
177
178void ICODE_ATTR INT_EXT3(void)
179{
180 gpio_handler(3);
181}
182
183void ICODE_ATTR INT_EXT6(void)
184{
185 gpio_handler(0);
186}
187#endif