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 | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/button-imx31.c b/firmware/target/arm/imx31/gigabeat-s/button-imx31.c index e80166bca7..746883d010 100644 --- a/firmware/target/arm/imx31/gigabeat-s/button-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/button-imx31.c | |||
@@ -29,11 +29,16 @@ | |||
29 | 29 | ||
30 | /* Most code in here is taken from the Linux BSP provided by Freescale | 30 | /* Most code in here is taken from the Linux BSP provided by Freescale |
31 | * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. */ | 31 | * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. */ |
32 | 32 | #ifdef HAVE_HEADPHONE_DETECTION | |
33 | static bool headphones_detect = false; | 33 | static bool headphones_detect = false; |
34 | #endif | ||
34 | static uint32_t int_btn = BUTTON_NONE; | 35 | static uint32_t int_btn = BUTTON_NONE; |
35 | static bool hold_button = false; | 36 | static bool hold_button = false; |
37 | #ifdef BOOTLOADER | ||
38 | static bool initialized = false; | ||
39 | #else | ||
36 | static bool hold_button_old = false; | 40 | static bool hold_button_old = false; |
41 | #endif | ||
37 | #define _button_hold() (GPIO3_DR & 0x10) | 42 | #define _button_hold() (GPIO3_DR & 0x10) |
38 | 43 | ||
39 | static __attribute__((interrupt("IRQ"))) void KPP_HANDLER(void) | 44 | static __attribute__((interrupt("IRQ"))) void KPP_HANDLER(void) |
@@ -116,6 +121,14 @@ static __attribute__((interrupt("IRQ"))) void KPP_HANDLER(void) | |||
116 | 121 | ||
117 | void button_init_device(void) | 122 | void button_init_device(void) |
118 | { | 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 | |||
119 | /* Enable keypad clock */ | 132 | /* Enable keypad clock */ |
120 | imx31_clkctl_module_clock_gating(CG_KPP, CGM_ON_ALL); | 133 | imx31_clkctl_module_clock_gating(CG_KPP, CGM_ON_ALL); |
121 | 134 | ||
@@ -136,15 +149,26 @@ void button_init_device(void) | |||
136 | KPP_KDDR = (KPP_KDDR | (0x7 << 8)) & ~0x1f; | 149 | KPP_KDDR = (KPP_KDDR | (0x7 << 8)) & ~0x1f; |
137 | 150 | ||
138 | /* 5. Clear the KPKD Status Flag and Synchronizer chain. | 151 | /* 5. Clear the KPKD Status Flag and Synchronizer chain. |
139 | * 6. Set the KDIE control bit, and set the KRIE control | 152 | * 6. Set the KDIE control bit bit. */ |
140 | * bit (to force immediate scan). */ | 153 | KPP_KPSR = KPP_KPSR_KDIE | KPP_KPSR_KRSS | KPP_KPSR_KDSC | KPP_KPSR_KPKD; |
141 | KPP_KPSR = KPP_KPSR_KRIE | KPP_KPSR_KDIE | KPP_KPSR_KRSS | | ||
142 | KPP_KPSR_KDSC | KPP_KPSR_KPKR | KPP_KPSR_KPKD; | ||
143 | 154 | ||
144 | /* KPP IRQ at priority 3 */ | 155 | /* KPP IRQ at priority 3 */ |
145 | avic_enable_int(KPP, IRQ, 3, KPP_HANDLER); | 156 | avic_enable_int(KPP, IRQ, 3, KPP_HANDLER); |
146 | } | 157 | } |
147 | 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 | |||
148 | bool button_hold(void) | 172 | bool button_hold(void) |
149 | { | 173 | { |
150 | return _button_hold(); | 174 | return _button_hold(); |
@@ -155,12 +179,14 @@ int button_read_device(void) | |||
155 | /* Simple poll of GPIO status */ | 179 | /* Simple poll of GPIO status */ |
156 | hold_button = _button_hold(); | 180 | hold_button = _button_hold(); |
157 | 181 | ||
182 | #ifndef BOOTLOADER | ||
158 | /* Backlight hold handling */ | 183 | /* Backlight hold handling */ |
159 | if (hold_button != hold_button_old) | 184 | if (hold_button != hold_button_old) |
160 | { | 185 | { |
161 | hold_button_old = hold_button; | 186 | hold_button_old = hold_button; |
162 | backlight_hold_changed(hold_button); | 187 | backlight_hold_changed(hold_button); |
163 | } | 188 | } |
189 | #endif | ||
164 | 190 | ||
165 | /* Enable the keypad interrupt to cause it to fire if a key is down. | 191 | /* Enable the keypad interrupt to cause it to fire if a key is down. |
166 | * KPP_HANDLER will clear and disable it after the scan. If no key | 192 | * KPP_HANDLER will clear and disable it after the scan. If no key |
@@ -190,6 +216,7 @@ void button_power_set_state(bool pressed) | |||
190 | restore_irq(oldlevel); | 216 | restore_irq(oldlevel); |
191 | } | 217 | } |
192 | 218 | ||
219 | #ifdef HAVE_HEADPHONE_DETECTION | ||
193 | /* This is called from the mc13783 interrupt thread */ | 220 | /* This is called from the mc13783 interrupt thread */ |
194 | void set_headphones_inserted(bool inserted) | 221 | void set_headphones_inserted(bool inserted) |
195 | { | 222 | { |
@@ -203,3 +230,4 @@ bool headphones_inserted(void) | |||
203 | { | 230 | { |
204 | return headphones_detect; | 231 | return headphones_detect; |
205 | } | 232 | } |
233 | #endif /* HAVE_HEADPHONE_DETECTION */ | ||