summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/gigabeat-s/button-imx31.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/button-imx31.c')
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/button-imx31.c38
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
33static bool headphones_detect = false; 33static bool headphones_detect = false;
34#endif
34static uint32_t int_btn = BUTTON_NONE; 35static uint32_t int_btn = BUTTON_NONE;
35static bool hold_button = false; 36static bool hold_button = false;
37#ifdef BOOTLOADER
38static bool initialized = false;
39#else
36static bool hold_button_old = false; 40static bool hold_button_old = false;
41#endif
37#define _button_hold() (GPIO3_DR & 0x10) 42#define _button_hold() (GPIO3_DR & 0x10)
38 43
39static __attribute__((interrupt("IRQ"))) void KPP_HANDLER(void) 44static __attribute__((interrupt("IRQ"))) void KPP_HANDLER(void)
@@ -116,6 +121,14 @@ static __attribute__((interrupt("IRQ"))) void KPP_HANDLER(void)
116 121
117void button_init_device(void) 122void 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
160void 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
148bool button_hold(void) 172bool 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 */
194void set_headphones_inserted(bool inserted) 221void 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 */