diff options
author | Cástor Muñoz <cmvidal@gmail.com> | 2016-05-22 01:12:35 +0200 |
---|---|---|
committer | Cástor Muñoz <cmvidal@gmail.com> | 2016-05-25 12:44:55 +0200 |
commit | 88caf222ed1da8f88114b4aa3a615e72e3649ca1 (patch) | |
tree | b5fa90da7324e77972569956f1bd0ab83353f5af /firmware/target | |
parent | 3f17745930ab0bee11555ab35318121dbec8fab1 (diff) | |
download | rockbox-88caf222ed1da8f88114b4aa3a615e72e3649ca1.tar.gz rockbox-88caf222ed1da8f88114b4aa3a615e72e3649ca1.zip |
iPod Classic: rework on external interrupts
Change-Id: I5be450adeb12b16070d9bfa31503e2ef350b2981
Diffstat (limited to 'firmware/target')
-rw-r--r-- | firmware/target/arm/s5l8702/gpio-s5l8702.c | 193 | ||||
-rw-r--r-- | firmware/target/arm/s5l8702/gpio-s5l8702.h | 126 | ||||
-rw-r--r-- | firmware/target/arm/s5l8702/system-s5l8702.c | 1 |
3 files changed, 164 insertions, 156 deletions
diff --git a/firmware/target/arm/s5l8702/gpio-s5l8702.c b/firmware/target/arm/s5l8702/gpio-s5l8702.c index 3b2c02861f..0f7a029fb6 100644 --- a/firmware/target/arm/s5l8702/gpio-s5l8702.c +++ b/firmware/target/arm/s5l8702/gpio-s5l8702.c | |||
@@ -23,11 +23,30 @@ | |||
23 | 23 | ||
24 | #include "config.h" | 24 | #include "config.h" |
25 | #include "system.h" | 25 | #include "system.h" |
26 | #include "gpio-s5l8702.h" | ||
27 | #include "panic.h" | 26 | #include "panic.h" |
28 | 27 | ||
28 | #include "gpio-s5l8702.h" | ||
29 | |||
30 | |||
29 | int rec_hw_ver; | 31 | int rec_hw_ver; |
30 | 32 | ||
33 | static uint32_t gpio_data[] = | ||
34 | { | ||
35 | 0x5322222F, 0xEEEEEE00, 0x2332EEEE, 0x3333E222, | ||
36 | 0x33333333, 0x33333333, 0x3F000E33, 0xEEEEEEEE, | ||
37 | 0xEEEEEEEE, 0xEEEEEEEE, 0xE0EEEEEE, 0xEE00EE0E, | ||
38 | 0xEEEE0EEE, 0xEEEEEEEE, 0xEE2222EE, 0xEEEE0EEE | ||
39 | }; | ||
40 | |||
41 | void INIT_ATTR gpio_preinit(void) | ||
42 | { | ||
43 | for (int i = 0; i < 16; i++) { | ||
44 | PCON(i) = gpio_data[i]; | ||
45 | PUNB(i) = 0; | ||
46 | PUNC(i) = 0; | ||
47 | } | ||
48 | } | ||
49 | |||
31 | void INIT_ATTR gpio_init(void) | 50 | void INIT_ATTR gpio_init(void) |
32 | { | 51 | { |
33 | /* Capture hardware versions: | 52 | /* Capture hardware versions: |
@@ -44,9 +63,8 @@ void INIT_ATTR gpio_init(void) | |||
44 | */ | 63 | */ |
45 | GPIOCMD = 0xe0700; | 64 | GPIOCMD = 0xe0700; |
46 | rec_hw_ver = (PDAT(14) & (1 << 7)) ? 0 : 1; | 65 | rec_hw_ver = (PDAT(14) & (1 << 7)) ? 0 : 1; |
66 | GPIOCMD = 0xe070e; /* restore default configuration */ | ||
47 | 67 | ||
48 | /* default GPIO configuration */ | ||
49 | GPIOCMD = 0xe070e; | ||
50 | if (rec_hw_ver == 0) { | 68 | if (rec_hw_ver == 0) { |
51 | GPIOCMD = 0xe060e; | 69 | GPIOCMD = 0xe060e; |
52 | } | 70 | } |
@@ -56,31 +74,9 @@ void INIT_ATTR gpio_init(void) | |||
56 | GPIOCMD = 0xe0600; | 74 | GPIOCMD = 0xe0600; |
57 | PUNB(14) |= (1 << 6); | 75 | PUNB(14) |= (1 << 6); |
58 | } | 76 | } |
59 | |||
60 | /* TODO: initialize GPIO ports for minimum power consumption */ | ||
61 | } | 77 | } |
62 | 78 | ||
63 | |||
64 | /* | ||
65 | * XXX: disabled, not used and never tested! | ||
66 | */ | ||
67 | #if 0 | 79 | #if 0 |
68 | /* handlers list */ | ||
69 | #define GPIOIC_MAX_HANDLERS 2 | ||
70 | |||
71 | #define FLAG_TYPE_LEVEL (1 << 0) | ||
72 | #define FLAG_AUTOFLIP (1 << 1) | ||
73 | |||
74 | struct gpio_handler { | ||
75 | int gpio_n; | ||
76 | void (*isr)(void); | ||
77 | int flags; | ||
78 | }; | ||
79 | static struct gpio_handler l_handlers[GPIOIC_MAX_HANDLERS] IDATA_ATTR; | ||
80 | static int n_handlers = 0; | ||
81 | |||
82 | |||
83 | /* API */ | ||
84 | uint32_t gpio_group_get(int group) | 80 | uint32_t gpio_group_get(int group) |
85 | { | 81 | { |
86 | uint32_t pcon = PCON(group); | 82 | uint32_t pcon = PCON(group); |
@@ -103,131 +99,128 @@ void gpio_group_set(int group, uint32_t mask, uint32_t cfg) | |||
103 | { | 99 | { |
104 | PCON(group) = (PCON(group) & ~mask) | (cfg & mask); | 100 | PCON(group) = (PCON(group) & ~mask) | (cfg & mask); |
105 | } | 101 | } |
102 | #endif | ||
106 | 103 | ||
107 | void gpio_int_register(int gpio_n, void *isr, int type, int level, int autoflip) | ||
108 | { | ||
109 | if (n_handlers >= GPIOIC_MAX_HANDLERS) | ||
110 | panicf("gpio_int_register(): too many handlers!"); | ||
111 | 104 | ||
112 | int group = IC_GROUP(gpio_n); | 105 | /* |
113 | int index = IC_IDX(gpio_n); | 106 | * eINT API |
107 | */ | ||
108 | #ifndef EINT_MAX_HANDLERS | ||
109 | #define EINT_MAX_HANDLERS 1 | ||
110 | #endif | ||
111 | static struct eint_handler* l_handlers[EINT_MAX_HANDLERS] IDATA_ATTR; | ||
114 | 112 | ||
113 | void INIT_ATTR eint_init(void) | ||
114 | { | ||
115 | /* disable external interrupts */ | ||
116 | for (int i = 0; i < EIC_N_GROUPS; i++) | ||
117 | EIC_INTEN(i) = 0; | ||
118 | } | ||
119 | |||
120 | void eint_register(struct eint_handler *h) | ||
121 | { | ||
122 | int i; | ||
115 | int flags = disable_irq_save(); | 123 | int flags = disable_irq_save(); |
116 | 124 | ||
117 | /* fill handler struct */ | 125 | for (i = 0; i < EINT_MAX_HANDLERS; i++) { |
118 | struct gpio_handler *handler = &l_handlers[n_handlers++]; | 126 | if (!l_handlers[i]) { |
127 | int group = EIC_GROUP(h->gpio_n); | ||
128 | int index = EIC_INDEX(h->gpio_n); | ||
119 | 129 | ||
120 | handler->gpio_n = gpio_n; | 130 | EIC_INTTYPE(group) |= (h->type << index); |
121 | handler->isr = isr; | 131 | EIC_INTLEVEL(group) |= (h->level << index); |
122 | handler->flags = (type ? FLAG_TYPE_LEVEL : 0) | 132 | EIC_INTSTAT(group) = (1 << index); /* clear */ |
123 | | (autoflip ? FLAG_AUTOFLIP : 0); | 133 | EIC_INTEN(group) |= (1 << index); /* enable */ |
124 | 134 | ||
125 | /* configure */ | 135 | /* XXX: valid only for gpio_n = 0..127 (IRQ_EXT0..IRQ_EXT3) */ |
126 | GPIOIC_INTTYPE(group) |= | 136 | VIC0INTENABLE = 1 << (IRQ_EXT0 + (h->gpio_n >> 5)); |
127 | (type ? GPIOIC_INTTYPE_LEVEL : GPIOIC_INTTYPE_EDGE) << index; | 137 | |
128 | GPIOIC_INTLEVEL(group) |= | 138 | l_handlers[i] = h; |
129 | (level ? GPIOIC_INTLEVEL_HIGH : GPIOIC_INTLEVEL_LOW) << index; | 139 | break; |
140 | } | ||
141 | } | ||
130 | 142 | ||
131 | restore_irq(flags); | 143 | restore_irq(flags); |
132 | 144 | ||
133 | /* XXX: valid only for gpio_n = 0..127 (IRQ_EXT0..IRQ_EXT3) */ | 145 | if (i == EINT_MAX_HANDLERS) |
134 | VIC0INTENABLE = 1 << (IRQ_EXT0 + (gpio_n >> 5)); | 146 | panicf("%s(): too many handlers!", __func__); |
135 | } | 147 | } |
136 | 148 | ||
137 | void gpio_int_enable(int gpio_n) | 149 | void eint_unregister(struct eint_handler *h) |
138 | { | 150 | { |
139 | int group = IC_GROUP(gpio_n); | ||
140 | uint32_t bit_mask = 1 << IC_IDX(gpio_n); | ||
141 | |||
142 | int flags = disable_irq_save(); | 151 | int flags = disable_irq_save(); |
143 | GPIOIC_INTSTAT(group) = bit_mask; /* clear */ | ||
144 | GPIOIC_INTEN(group) |= bit_mask; /* enable */ | ||
145 | restore_irq(flags); | ||
146 | } | ||
147 | 152 | ||
148 | void gpio_int_disable(int gpio_n) | 153 | for (int i = 0; i < EINT_MAX_HANDLERS; i++) { |
149 | { | 154 | if (l_handlers[i] == h) { |
150 | int group = IC_GROUP(gpio_n); | 155 | int group = EIC_GROUP(h->gpio_n); |
151 | uint32_t bit_mask = 1 << IC_IDX(gpio_n); | 156 | int index = EIC_INDEX(h->gpio_n); |
157 | |||
158 | EIC_INTEN(group) &= ~(1 << index); /* disable */ | ||
159 | |||
160 | /* XXX: valid only for gpio_n = 0..127 (IRQ_EXT0..IRQ_EXT3) */ | ||
161 | if (EIC_INTEN(group) == 0) | ||
162 | VIC0INTENCLEAR = 1 << (IRQ_EXT0 + (h->gpio_n >> 5)); | ||
163 | |||
164 | l_handlers[i] = NULL; | ||
165 | break; | ||
166 | } | ||
167 | } | ||
152 | 168 | ||
153 | int flags = disable_irq_save(); | ||
154 | GPIOIC_INTEN(group) &= ~bit_mask; /* disable */ | ||
155 | GPIOIC_INTSTAT(group) = bit_mask; /* clear */ | ||
156 | restore_irq(flags); | 169 | restore_irq(flags); |
157 | } | 170 | } |
158 | 171 | ||
159 | |||
160 | /* ISR */ | 172 | /* ISR */ |
161 | void ICODE_ATTR gpio_handler(int group) | 173 | void ICODE_ATTR eint_handler(int group) |
162 | { | 174 | { |
163 | int i; | 175 | int i; |
164 | struct gpio_handler *handler; | 176 | uint32_t ints; |
165 | uint32_t ints, bit_mask; | ||
166 | 177 | ||
167 | ints = GPIOIC_INTSTAT(group) & GPIOIC_INTEN(group); | 178 | ints = EIC_INTSTAT(group) & EIC_INTEN(group); |
168 | 179 | ||
169 | for (i = 0; i < n_handlers; i++) { | 180 | for (i = 0; i < EINT_MAX_HANDLERS; i++) { |
170 | handler = &l_handlers[i]; | 181 | struct eint_handler *h = l_handlers[i]; |
171 | 182 | ||
172 | if (IC_GROUP(handler->gpio_n) != group) | 183 | if (!h || (EIC_GROUP(h->gpio_n) != group)) |
173 | continue; | 184 | continue; |
174 | 185 | ||
175 | bit_mask = 1 << IC_IDX(handler->gpio_n); | 186 | uint32_t bit = 1 << EIC_INDEX(h->gpio_n); |
176 | 187 | ||
177 | if (ints & bit_mask) { | 188 | if (ints & bit) { |
178 | if ((handler->flags & FLAG_TYPE_LEVEL) == 0) | 189 | /* Clear INTTYPE_EDGE interrupt, to clear INTTYPE_LEVEL |
179 | GPIOIC_INTSTAT(group) = bit_mask; /* clear */ | 190 | interrupts the source (line level) must be "cleared" */ |
191 | if (h->type == EIC_INTTYPE_EDGE) | ||
192 | EIC_INTSTAT(group) = bit; /* clear */ | ||
180 | 193 | ||
181 | if (handler->flags & FLAG_AUTOFLIP) | 194 | if (h->autoflip) |
182 | GPIOIC_INTLEVEL(group) ^= bit_mask; /* swap level */ | 195 | EIC_INTLEVEL(group) ^= bit; /* swap level */ |
183 | 196 | ||
184 | if (handler->isr) | 197 | if (h->isr) |
185 | handler->isr(); /* exec GPIO handler */ | 198 | h->isr(h); /* exec GPIO handler */ |
186 | |||
187 | GPIOIC_INTSTAT(group) = bit_mask; /* clear */ | ||
188 | } | 199 | } |
189 | } | 200 | } |
190 | } | 201 | } |
191 | 202 | ||
192 | void ICODE_ATTR INT_EXT0(void) | 203 | void ICODE_ATTR INT_EXT0(void) |
193 | { | 204 | { |
194 | gpio_handler(6); | 205 | eint_handler(6); |
195 | } | 206 | } |
196 | 207 | ||
197 | void ICODE_ATTR INT_EXT1(void) | 208 | void ICODE_ATTR INT_EXT1(void) |
198 | { | 209 | { |
199 | gpio_handler(5); | 210 | eint_handler(5); |
200 | } | 211 | } |
201 | 212 | ||
202 | void ICODE_ATTR INT_EXT2(void) | 213 | void ICODE_ATTR INT_EXT2(void) |
203 | { | 214 | { |
204 | gpio_handler(4); | 215 | eint_handler(4); |
205 | } | 216 | } |
206 | 217 | ||
207 | void ICODE_ATTR INT_EXT3(void) | 218 | void ICODE_ATTR INT_EXT3(void) |
208 | { | 219 | { |
209 | gpio_handler(3); | 220 | eint_handler(3); |
210 | } | 221 | } |
211 | 222 | ||
212 | void ICODE_ATTR INT_EXT6(void) | 223 | void ICODE_ATTR INT_EXT6(void) |
213 | { | 224 | { |
214 | gpio_handler(0); | 225 | eint_handler(0); |
215 | } | ||
216 | #endif | ||
217 | |||
218 | static uint32_t gpio_data[16] = | ||
219 | { | ||
220 | 0x5322222F, 0xEEEEEE00, 0x2332EEEE, 0x3333E222, | ||
221 | 0x33333333, 0x33333333, 0x3F000E33, 0xEEEEEEEE, | ||
222 | 0xEEEEEEEE, 0xEEEEEEEE, 0xE0EEEEEE, 0xEE00EE0E, | ||
223 | 0xEEEE0EEE, 0xEEEEEEEE, 0xEE2222EE, 0xEEEE0EEE | ||
224 | }; | ||
225 | |||
226 | void gpio_preinit(void) | ||
227 | { | ||
228 | for (int i = 0; i < 16; i++) { | ||
229 | PCON(i) = gpio_data[i]; | ||
230 | PUNB(i) = 0; | ||
231 | PUNC(i) = 0; | ||
232 | } | ||
233 | } | 226 | } |
diff --git a/firmware/target/arm/s5l8702/gpio-s5l8702.h b/firmware/target/arm/s5l8702/gpio-s5l8702.h index 19bc36a139..9259fb05ef 100644 --- a/firmware/target/arm/s5l8702/gpio-s5l8702.h +++ b/firmware/target/arm/s5l8702/gpio-s5l8702.h | |||
@@ -23,6 +23,69 @@ | |||
23 | #define __GPIO_S5L8702_H__ | 23 | #define __GPIO_S5L8702_H__ |
24 | #include <stdint.h> | 24 | #include <stdint.h> |
25 | 25 | ||
26 | |||
27 | #define REG32_PTR_T volatile uint32_t * | ||
28 | |||
29 | /* | ||
30 | * s5l8702 External (GPIO) Interrupt Controller | ||
31 | * | ||
32 | * 7 groups of 32 interrupts, GPIO pins are seen as 'wired' | ||
33 | * to groups 6..3 in reverse order. | ||
34 | * On group 3, last four bits are dissbled (GPIO 124..127). | ||
35 | * All bits in groups 1 and 2 are disabled (not used). | ||
36 | * On group 0, all bits are masked except bits 0 and 2: | ||
37 | * bit 0: if unmasked, EINT6 is generated when ALVTCNT | ||
38 | * reachs ALVTEND. | ||
39 | * bit 2: if unmasked, EINT6 is generated when USB cable | ||
40 | * is plugged and/or(TBC) unplugged. | ||
41 | * | ||
42 | * IC_GROUP0..6 are connected to EINT6..0 of the VIC. | ||
43 | */ | ||
44 | #define EIC_N_GROUPS 7 | ||
45 | |||
46 | /* get EIC group and bit for a given GPIO port */ | ||
47 | #define EIC_GROUP(n) (6 - (n >> 5)) | ||
48 | #define EIC_INDEX(n) ((0x18 - (n & 0x18)) | (n & 0x7)) | ||
49 | |||
50 | /* SoC EINTs uses these 'gpio' numbers */ | ||
51 | #define GPIO_EINT_USB 0xd8 | ||
52 | #define GPIO_EINT_ALIVE 0xda | ||
53 | |||
54 | /* probably a part of the system controller */ | ||
55 | #define EIC_BASE 0x39a00000 | ||
56 | |||
57 | #define EIC_INTLEVEL(g) (*((REG32_PTR_T)(EIC_BASE + 0x80 + 4*(g)))) | ||
58 | #define EIC_INTSTAT(g) (*((REG32_PTR_T)(EIC_BASE + 0xA0 + 4*(g)))) | ||
59 | #define EIC_INTEN(g) (*((REG32_PTR_T)(EIC_BASE + 0xC0 + 4*(g)))) | ||
60 | #define EIC_INTTYPE(g) (*((REG32_PTR_T)(EIC_BASE + 0xE0 + 4*(g)))) | ||
61 | |||
62 | #define EIC_INTLEVEL_LOW 0 | ||
63 | #define EIC_INTLEVEL_HIGH 1 | ||
64 | |||
65 | #define EIC_INTTYPE_EDGE 0 | ||
66 | #define EIC_INTTYPE_LEVEL 1 | ||
67 | |||
68 | |||
69 | struct eint_handler { | ||
70 | uint8_t gpio_n; | ||
71 | uint8_t type; /* EIC_INTTYPE_ */ | ||
72 | uint8_t level; /* EIC_INTLEVEL_ */ | ||
73 | uint8_t autoflip; | ||
74 | void (*isr)(struct eint_handler*); | ||
75 | }; | ||
76 | |||
77 | void eint_register(struct eint_handler *h); | ||
78 | void eint_unregister(struct eint_handler *h); | ||
79 | void eint_init(void); | ||
80 | |||
81 | void gpio_init(void); | ||
82 | /* get/set configuration for GPIO groups (0..15) */ | ||
83 | uint32_t gpio_group_get(int group); | ||
84 | void gpio_group_set(int group, uint32_t mask, uint32_t cfg); | ||
85 | |||
86 | void gpio_preinit(void); | ||
87 | |||
88 | |||
26 | /* This is very preliminary work in progress, ATM this region is called | 89 | /* This is very preliminary work in progress, ATM this region is called |
27 | * system 'alive' because it seems there are similiarities when mixing | 90 | * system 'alive' because it seems there are similiarities when mixing |
28 | * concepts from: | 91 | * concepts from: |
@@ -47,9 +110,6 @@ | |||
47 | * +-->| 1/UNKDIV |--> Unknown | 110 | * +-->| 1/UNKDIV |--> Unknown |
48 | * |___________| | 111 | * |___________| |
49 | */ | 112 | */ |
50 | |||
51 | #define REG32_PTR_T volatile uint32_t * | ||
52 | |||
53 | #define SYSALV_BASE 0x39a00000 | 113 | #define SYSALV_BASE 0x39a00000 |
54 | 114 | ||
55 | #define ALVCON (*((REG32_PTR_T)(SYSALV_BASE + 0x0))) | 115 | #define ALVCON (*((REG32_PTR_T)(SYSALV_BASE + 0x0))) |
@@ -81,67 +141,21 @@ | |||
81 | 141 | ||
82 | /* | 142 | /* |
83 | * System Alive timer | 143 | * System Alive timer |
84 | */ | 144 | * |
85 | /* ALVCOM_RUN_BIT starts/stops count on ALVTCNT, counter frequency | 145 | * ALVCOM_RUN_BIT starts/stops count on ALVTCNT, counter frequency |
86 | * is SClk / ALVTDIV. When count reachs ALVTEND then ALVTSTAT[0] | 146 | * is SClk / ALVTDIV. When count reachs ALVTEND then ALVTSTAT[0] |
87 | * and ALVUNK4[0] are set, optionally an interrupt is generated (see | 147 | * and ALVUNK4[0] are set, optionally an interrupt is generated (see |
88 | * GPIO_IC below). Writing 1 to ALVTCOM_RST_BIT clears ALVSTAT[0] | 148 | * GPIO_IC below). Writing 1 to ALVTCOM_RST_BIT clears ALVSTAT[0] |
89 | * and ALVUNK4[0] and initializes ALVTCNT to zero. | 149 | * and ALVUNK4[0] and initializes ALVTCNT to zero. |
90 | */ | 150 | */ |
91 | #define ALVTCOM (*((REG32_PTR_T)(SYSALV_BASE + 0x6c))) | 151 | #define ALVTCOM (*((REG32_PTR_T)(SYSALV_BASE + 0x6c))) |
92 | #define ALVTCOM_RUN_BIT (1 << 0) /* 0 -> Stop, 1 -> Start */ | 152 | #define ALVTCOM_RUN_BIT (1 << 0) /* 0 -> Stop, 1 -> Start */ |
93 | #define ALVTCOM_RST_BIT (1 << 1) /* 1 -> Reset */ | 153 | #define ALVTCOM_RST_BIT (1 << 1) /* 1 -> Reset */ |
94 | 154 | ||
95 | #define ALVTEND (*((REG32_PTR_T)(SYSALV_BASE + 0x70))) | 155 | #define ALVTEND (*((REG32_PTR_T)(SYSALV_BASE + 0x70))) |
96 | #define ALVTDIV (*((REG32_PTR_T)(SYSALV_BASE + 0x74))) | 156 | #define ALVTDIV (*((REG32_PTR_T)(SYSALV_BASE + 0x74))) |
97 | 157 | ||
98 | #define ALVTCNT (*((REG32_PTR_T)(SYSALV_BASE + 0x78))) | 158 | #define ALVTCNT (*((REG32_PTR_T)(SYSALV_BASE + 0x78))) |
99 | #define ALVTSTAT (*((REG32_PTR_T)(SYSALV_BASE + 0x7c))) | 159 | #define ALVTSTAT (*((REG32_PTR_T)(SYSALV_BASE + 0x7c))) |
100 | |||
101 | |||
102 | /* | ||
103 | * s5l8702 GPIO Interrupt Controller | ||
104 | */ | ||
105 | #define GPIOIC_BASE 0x39a00000 /* probably a part of the system controller */ | ||
106 | |||
107 | #define GPIOIC_INTLEVEL(g) (*((REG32_PTR_T)(GPIOIC_BASE + 0x80 + 4*(g)))) | ||
108 | #define GPIOIC_INTSTAT(g) (*((REG32_PTR_T)(GPIOIC_BASE + 0xA0 + 4*(g)))) | ||
109 | #define GPIOIC_INTEN(g) (*((REG32_PTR_T)(GPIOIC_BASE + 0xC0 + 4*(g)))) | ||
110 | #define GPIOIC_INTTYPE(g) (*((REG32_PTR_T)(GPIOIC_BASE + 0xE0 + 4*(g)))) | ||
111 | |||
112 | #define GPIOIC_INTLEVEL_LOW 0 | ||
113 | #define GPIOIC_INTLEVEL_HIGH 1 | ||
114 | |||
115 | #define GPIOIC_INTTYPE_EDGE 0 | ||
116 | #define GPIOIC_INTTYPE_LEVEL 1 | ||
117 | |||
118 | /* 7 groups of 32 interrupts, GPIO pins are seen as 'wired' | ||
119 | * to groups 6..3 in reverse order. | ||
120 | * On group 3, last four bits are dissbled (GPIO 124..127). | ||
121 | * All bits in groups 1 and 2 are disabled (not used). | ||
122 | * On group 0, all bits are masked except bits 0 and 2: | ||
123 | * bit 0: if unmasked, EINT6 is generated when ALVTCNT | ||
124 | * reachs ALVTEND. | ||
125 | * bit 2: if unmasked, EINT6 is generated when USB cable | ||
126 | * is plugged and/or(TBC) unplugged. | ||
127 | * | ||
128 | * IC_GROUP0..6 are connected to EINT6..0 of the VIC. | ||
129 | */ | ||
130 | |||
131 | /* get GPIOIC group and bit for a given GPIO port */ | ||
132 | #define IC_GROUP(n) (6 - (n >> 5)) | ||
133 | #define IC_IDX(n) ((0x18 - (n & 0x18)) | (n & 0x7)) | ||
134 | |||
135 | void gpio_init(void); | ||
136 | void gpio_int_register(int gpio_n, void *isr, | ||
137 | int type, int level, int autoflip); | ||
138 | void gpio_int_enable(int gpio_n); | ||
139 | void gpio_int_disable(int gpio_n); | ||
140 | |||
141 | /* get/set configuration for GPIO groups (0..15) */ | ||
142 | uint32_t gpio_group_get(int group); | ||
143 | void gpio_group_set(int group, uint32_t mask, uint32_t cfg); | ||
144 | |||
145 | void gpio_preinit(void); | ||
146 | 160 | ||
147 | #endif /* __GPIO_S5L8702_H__ */ | 161 | #endif /* __GPIO_S5L8702_H__ */ |
diff --git a/firmware/target/arm/s5l8702/system-s5l8702.c b/firmware/target/arm/s5l8702/system-s5l8702.c index e94e12a153..cbe8bfcaf7 100644 --- a/firmware/target/arm/s5l8702/system-s5l8702.c +++ b/firmware/target/arm/s5l8702/system-s5l8702.c | |||
@@ -206,6 +206,7 @@ void system_init(void) | |||
206 | pmu_preinit(); | 206 | pmu_preinit(); |
207 | #endif | 207 | #endif |
208 | gpio_init(); | 208 | gpio_init(); |
209 | eint_init(); | ||
209 | pmu_init(); | 210 | pmu_init(); |
210 | dma_init(); | 211 | dma_init(); |
211 | #ifdef HAVE_SERIAL | 212 | #ifdef HAVE_SERIAL |