diff options
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/button-imx31.c')
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/button-imx31.c | 123 |
1 files changed, 67 insertions, 56 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/button-imx31.c b/firmware/target/arm/imx31/gigabeat-s/button-imx31.c index 746883d010..ad1e2b7e49 100644 --- a/firmware/target/arm/imx31/gigabeat-s/button-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/button-imx31.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "backlight-target.h" | 26 | #include "backlight-target.h" |
27 | #include "avic-imx31.h" | 27 | #include "avic-imx31.h" |
28 | #include "clkctl-imx31.h" | 28 | #include "clkctl-imx31.h" |
29 | #include "mc13783.h" | ||
29 | 30 | ||
30 | /* Most code in here is taken from the Linux BSP provided by Freescale | 31 | /* Most code in here is taken from the Linux BSP provided by Freescale |
31 | * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. */ | 32 | * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. */ |
@@ -119,56 +120,6 @@ static __attribute__((interrupt("IRQ"))) void KPP_HANDLER(void) | |||
119 | int_btn = button; | 120 | int_btn = button; |
120 | } | 121 | } |
121 | 122 | ||
122 | void button_init_device(void) | ||
123 | { | ||
124 | #ifdef BOOTLOADER | ||
125 | /* Can be called more than once in the bootloader */ | ||
126 | if (initialized) | ||
127 | return; | ||
128 | |||
129 | initialized = true; | ||
130 | #endif | ||
131 | |||
132 | /* Enable keypad clock */ | ||
133 | imx31_clkctl_module_clock_gating(CG_KPP, CGM_ON_ALL); | ||
134 | |||
135 | /* 1. Enable number of rows in keypad (KPCR[4:0]) | ||
136 | * | ||
137 | * Configure the rows/cols in KPP | ||
138 | * LSB nybble in KPP is for 5 rows | ||
139 | * MSB nybble in KPP is for 3 cols */ | ||
140 | KPP_KPCR |= 0x1f; | ||
141 | |||
142 | /* 2. Write 0's to KPDR[10:8] */ | ||
143 | KPP_KPDR &= ~(0x7 << 8); | ||
144 | |||
145 | /* 3. Configure the keypad columns as open-drain (KPCR[10:8]). */ | ||
146 | KPP_KPCR |= (0x7 << 8); | ||
147 | |||
148 | /* 4. Configure columns as output, rows as input (KDDR[10:8,4:0]) */ | ||
149 | KPP_KDDR = (KPP_KDDR | (0x7 << 8)) & ~0x1f; | ||
150 | |||
151 | /* 5. Clear the KPKD Status Flag and Synchronizer chain. | ||
152 | * 6. Set the KDIE control bit bit. */ | ||
153 | KPP_KPSR = KPP_KPSR_KDIE | KPP_KPSR_KRSS | KPP_KPSR_KDSC | KPP_KPSR_KPKD; | ||
154 | |||
155 | /* KPP IRQ at priority 3 */ | ||
156 | avic_enable_int(KPP, IRQ, 3, KPP_HANDLER); | ||
157 | } | ||
158 | |||
159 | #ifdef BUTTON_DRIVER_CLOSE | ||
160 | void button_close_device(void) | ||
161 | { | ||
162 | int oldlevel = disable_irq_save(); | ||
163 | |||
164 | avic_disable_int(KPP); | ||
165 | KPP_KPSR &= ~(KPP_KPSR_KRIE | KPP_KPSR_KDIE); | ||
166 | int_btn = BUTTON_NONE; | ||
167 | |||
168 | restore_irq(oldlevel); | ||
169 | } | ||
170 | #endif /* BUTTON_DRIVER_CLOSE */ | ||
171 | |||
172 | bool button_hold(void) | 123 | bool button_hold(void) |
173 | { | 124 | { |
174 | return _button_hold(); | 125 | return _button_hold(); |
@@ -199,8 +150,11 @@ int button_read_device(void) | |||
199 | } | 150 | } |
200 | 151 | ||
201 | /* This is called from the mc13783 interrupt thread */ | 152 | /* This is called from the mc13783 interrupt thread */ |
202 | void button_power_set_state(bool pressed) | 153 | void button_power_event(void) |
203 | { | 154 | { |
155 | bool pressed = | ||
156 | (mc13783_read(MC13783_INTERRUPT_SENSE1) & MC13783_ONOFD1S) == 0; | ||
157 | |||
204 | /* Prevent KPP_HANDLER from changing things */ | 158 | /* Prevent KPP_HANDLER from changing things */ |
205 | int oldlevel = disable_irq_save(); | 159 | int oldlevel = disable_irq_save(); |
206 | 160 | ||
@@ -218,16 +172,73 @@ void button_power_set_state(bool pressed) | |||
218 | 172 | ||
219 | #ifdef HAVE_HEADPHONE_DETECTION | 173 | #ifdef HAVE_HEADPHONE_DETECTION |
220 | /* This is called from the mc13783 interrupt thread */ | 174 | /* This is called from the mc13783 interrupt thread */ |
221 | void set_headphones_inserted(bool inserted) | 175 | void headphone_detect_event(void) |
222 | { | 176 | { |
223 | headphones_detect = inserted; | 177 | /* FIXME: Not really the correct method */ |
178 | headphones_detect = | ||
179 | (mc13783_read(MC13783_INTERRUPT_SENSE1) & MC13783_ONOFD2S) == 0; | ||
224 | } | 180 | } |
225 | 181 | ||
226 | /* This is called from the mc13783 interrupt thread */ | ||
227 | /* TODO: Just do a post to the button queue directly - implement the | ||
228 | * appropriate variant in the driver. */ | ||
229 | bool headphones_inserted(void) | 182 | bool headphones_inserted(void) |
230 | { | 183 | { |
231 | return headphones_detect; | 184 | return headphones_detect; |
232 | } | 185 | } |
233 | #endif /* HAVE_HEADPHONE_DETECTION */ | 186 | #endif /* HAVE_HEADPHONE_DETECTION */ |
187 | |||
188 | void button_init_device(void) | ||
189 | { | ||
190 | #ifdef BOOTLOADER | ||
191 | /* Can be called more than once in the bootloader */ | ||
192 | if (initialized) | ||
193 | return; | ||
194 | |||
195 | initialized = true; | ||
196 | #endif | ||
197 | |||
198 | /* Enable keypad clock */ | ||
199 | imx31_clkctl_module_clock_gating(CG_KPP, CGM_ON_ALL); | ||
200 | |||
201 | /* 1. Enable number of rows in keypad (KPCR[4:0]) | ||
202 | * | ||
203 | * Configure the rows/cols in KPP | ||
204 | * LSB nybble in KPP is for 5 rows | ||
205 | * MSB nybble in KPP is for 3 cols */ | ||
206 | KPP_KPCR |= 0x1f; | ||
207 | |||
208 | /* 2. Write 0's to KPDR[10:8] */ | ||
209 | KPP_KPDR &= ~(0x7 << 8); | ||
210 | |||
211 | /* 3. Configure the keypad columns as open-drain (KPCR[10:8]). */ | ||
212 | KPP_KPCR |= (0x7 << 8); | ||
213 | |||
214 | /* 4. Configure columns as output, rows as input (KDDR[10:8,4:0]) */ | ||
215 | KPP_KDDR = (KPP_KDDR | (0x7 << 8)) & ~0x1f; | ||
216 | |||
217 | /* 5. Clear the KPKD Status Flag and Synchronizer chain. | ||
218 | * 6. Set the KDIE control bit bit. */ | ||
219 | KPP_KPSR = KPP_KPSR_KDIE | KPP_KPSR_KRSS | KPP_KPSR_KDSC | KPP_KPSR_KPKD; | ||
220 | |||
221 | /* KPP IRQ at priority 3 */ | ||
222 | avic_enable_int(KPP, IRQ, 3, KPP_HANDLER); | ||
223 | |||
224 | button_power_event(); | ||
225 | mc13783_enable_event(MC13783_ONOFD1_EVENT); | ||
226 | |||
227 | #ifdef HAVE_HEADPHONE_DETECTION | ||
228 | headphone_detect_event(); | ||
229 | mc13783_enable_event(MC13783_ONOFD2_EVENT); | ||
230 | #endif | ||
231 | } | ||
232 | |||
233 | #ifdef BUTTON_DRIVER_CLOSE | ||
234 | void button_close_device(void) | ||
235 | { | ||
236 | int oldlevel = disable_irq_save(); | ||
237 | |||
238 | avic_disable_int(KPP); | ||
239 | KPP_KPSR &= ~(KPP_KPSR_KRIE | KPP_KPSR_KDIE); | ||
240 | int_btn = BUTTON_NONE; | ||
241 | |||
242 | restore_irq(oldlevel); | ||
243 | } | ||
244 | #endif /* BUTTON_DRIVER_CLOSE */ | ||