summaryrefslogtreecommitdiff
path: root/firmware/target/arm/ipod/button-1g-3g.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/ipod/button-1g-3g.c')
-rw-r--r--firmware/target/arm/ipod/button-1g-3g.c207
1 files changed, 207 insertions, 0 deletions
diff --git a/firmware/target/arm/ipod/button-1g-3g.c b/firmware/target/arm/ipod/button-1g-3g.c
new file mode 100644
index 0000000000..a546bea9b6
--- /dev/null
+++ b/firmware/target/arm/ipod/button-1g-3g.c
@@ -0,0 +1,207 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Daniel Stenberg
11 *
12 * iPod driver based on code from the ipodlinux project - http://ipodlinux.org
13 * Adapted for Rockbox in December 2005
14 * Original file: linux/arch/armnommu/mach-ipod/keyboard.c
15 * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org)
16 *
17 *
18 * All files in this archive are subject to the GNU General Public License.
19 * See the file COPYING in the source tree root for full license agreement.
20 *
21 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22 * KIND, either express or implied.
23 *
24 ****************************************************************************/
25
26/*
27 * Rockbox button functions
28 */
29
30#include <stdlib.h>
31#include "config.h"
32#include "cpu.h"
33#include "system.h"
34#include "button.h"
35#include "kernel.h"
36#include "backlight.h"
37#include "adc.h"
38#include "serial.h"
39#include "power.h"
40#include "system.h"
41#include "powermgmt.h"
42
43/* iPod 3G and mini 1G, mini 2G uses iPod 4G code */
44void handle_scroll_wheel(int new_scroll, int was_hold, int reverse)
45{
46 int wheel_keycode = BUTTON_NONE;
47 static int prev_scroll = -1;
48 static int direction = 0;
49 static int count = 0;
50 static int scroll_state[4][4] = {
51 {0, 1, -1, 0},
52 {-1, 0, 0, 1},
53 {1, 0, 0, -1},
54 {0, -1, 1, 0}
55 };
56
57 if ( prev_scroll == -1 ) {
58 prev_scroll = new_scroll;
59 }
60 else if (direction != scroll_state[prev_scroll][new_scroll]) {
61 direction = scroll_state[prev_scroll][new_scroll];
62 count = 0;
63 }
64 else if (!was_hold) {
65 backlight_on();
66 reset_poweroff_timer();
67 if (++count == 6) { /* reduce sensitivity */
68 count = 0;
69 switch (direction) {
70 case 1:
71 if (reverse) {
72 /* 'r' keypress */
73 wheel_keycode = BUTTON_SCROLL_FWD;
74 }
75 else {
76 /* 'l' keypress */
77 wheel_keycode = BUTTON_SCROLL_BACK;
78 }
79 break;
80 case -1:
81 if (reverse) {
82 /* 'l' keypress */
83 wheel_keycode = BUTTON_SCROLL_BACK;
84 }
85 else {
86 /* 'r' keypress */
87 wheel_keycode = BUTTON_SCROLL_FWD;
88 }
89 break;
90 default:
91 /* only happens if we get out of sync */
92 break;
93 }
94 }
95 }
96 if (wheel_keycode != BUTTON_NONE && queue_empty(&button_queue))
97 queue_post(&button_queue, wheel_keycode, 0);
98 prev_scroll = new_scroll;
99}
100
101static int ipod_3g_button_read(void)
102{
103 unsigned char source, state;
104 static int was_hold = 0;
105 int btn = BUTTON_NONE;
106
107#ifdef IPOD_3G
108 /* we need some delay for g3, cause hold generates several interrupts,
109 * some of them delayed */
110 udelay(250);
111#endif
112
113 /* get source of interupts */
114 source = GPIOA_INT_STAT;
115
116
117 /* get current keypad status */
118 state = GPIOA_INPUT_VAL;
119 GPIOA_INT_LEV = ~state;
120
121#ifdef IPOD_3G
122 if (was_hold && source == 0x40 && state == 0xbf) {
123 /* ack any active interrupts */
124 GPIOA_INT_CLR = source;
125 return BUTTON_NONE;
126 }
127 was_hold = 0;
128
129 if ((state & 0x20) == 0) {
130 /* 3g hold switch is active low */
131 was_hold = 1;
132 /* hold switch on 3g causes all outputs to go low */
133 /* we shouldn't interpret these as key presses */
134 GPIOA_INT_CLR = source;
135 return BUTTON_NONE;
136 }
137#elif defined IPOD_1G2G
138 if (state & 0x20)
139 was_hold = 1;
140 else
141 was_hold = 0;
142#endif
143 if ((state & 0x1) == 0) {
144 btn |= BUTTON_RIGHT;
145 }
146 if ((state & 0x2) == 0) {
147 btn |= BUTTON_SELECT;
148 }
149 if ((state & 0x4) == 0) {
150 btn |= BUTTON_PLAY;
151 }
152 if ((state & 0x8) == 0) {
153 btn |= BUTTON_LEFT;
154 }
155 if ((state & 0x10) == 0) {
156 btn |= BUTTON_MENU;
157 }
158
159 if (source & 0xc0) {
160 handle_scroll_wheel((state & 0xc0) >> 6, was_hold, 0);
161 }
162
163 /* ack any active interrupts */
164 GPIOA_INT_CLR = source;
165
166 return btn;
167}
168
169void button_init_device(void)
170{
171 GPIOA_INT_LEV = ~GPIOA_INPUT_VAL;
172 GPIOA_INT_CLR = GPIOA_INT_STAT;
173 /* TODO: put additional G1 code here */
174 GPIOA_INT_EN = 0xff;
175}
176
177/*
178 * Get button pressed from hardware
179 */
180int button_read_device(void)
181{
182 static bool hold_button = false;
183 bool hold_button_old;
184
185 /* normal buttons */
186 hold_button_old = hold_button;
187 hold_button = button_hold();
188
189 if (hold_button != hold_button_old)
190 backlight_hold_changed(hold_button);
191
192 return ipod_3g_button_read();
193}
194
195bool button_hold(void)
196{
197#ifdef IPOD_1G2G
198 return (GPIOA_INPUT_VAL & 0x20);
199#else
200 return !(GPIOA_INPUT_VAL & 0x20);
201#endif
202}
203
204bool headphones_inserted(void)
205{
206 return (GPIOC_INPUT_VAL & 0x1)?true:false;
207}