summaryrefslogtreecommitdiff
path: root/firmware/target/arm/ipod/3g/button-3g.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/ipod/3g/button-3g.c')
-rw-r--r--firmware/target/arm/ipod/3g/button-3g.c189
1 files changed, 189 insertions, 0 deletions
diff --git a/firmware/target/arm/ipod/3g/button-3g.c b/firmware/target/arm/ipod/3g/button-3g.c
new file mode 100644
index 0000000000..7244dd597b
--- /dev/null
+++ b/firmware/target/arm/ipod/3g/button-3g.c
@@ -0,0 +1,189 @@
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 if (++count == 6) { /* reduce sensitivity */
67 count = 0;
68 switch (direction) {
69 case 1:
70 if (reverse) {
71 /* 'r' keypress */
72 wheel_keycode = BUTTON_SCROLL_FWD;
73 }
74 else {
75 /* 'l' keypress */
76 wheel_keycode = BUTTON_SCROLL_BACK;
77 }
78 break;
79 case -1:
80 if (reverse) {
81 /* 'l' keypress */
82 wheel_keycode = BUTTON_SCROLL_BACK;
83 }
84 else {
85 /* 'r' keypress */
86 wheel_keycode = BUTTON_SCROLL_FWD;
87 }
88 break;
89 default:
90 /* only happens if we get out of sync */
91 break;
92 }
93 }
94 }
95 if (wheel_keycode != BUTTON_NONE && queue_empty(&button_queue))
96 queue_post(&button_queue, wheel_keycode, NULL);
97 prev_scroll = new_scroll;
98}
99
100static int ipod_3g_button_read(void)
101{
102 unsigned char source, state;
103 static int was_hold = 0;
104 int btn = BUTTON_NONE;
105 /*
106 * we need some delay for g3, cause hold generates several interrupts,
107 * some of them delayed
108 */
109 udelay(250);
110
111 /* get source of interupts */
112 source = GPIOA_INT_STAT;
113
114
115 /* get current keypad status */
116 state = GPIOA_INPUT_VAL;
117 GPIOA_INT_LEV = ~state;
118
119 if (was_hold && source == 0x40 && state == 0xbf) {
120 /* ack any active interrupts */
121 GPIOA_INT_CLR = source;
122 return BUTTON_NONE;
123 }
124 was_hold = 0;
125
126
127 if ((state & 0x20) == 0) {
128 /* 3g hold switch is active low */
129 was_hold = 1;
130 /* hold switch on 3g causes all outputs to go low */
131 /* we shouldn't interpret these as key presses */
132 GPIOA_INT_CLR = source;
133 return BUTTON_NONE;
134 }
135 if ((state & 0x1) == 0) {
136 btn |= BUTTON_RIGHT;
137 }
138 if ((state & 0x2) == 0) {
139 btn |= BUTTON_SELECT;
140 }
141 if ((state & 0x4) == 0) {
142 btn |= BUTTON_PLAY;
143 }
144 if ((state & 0x8) == 0) {
145 btn |= BUTTON_LEFT;
146 }
147 if ((state & 0x10) == 0) {
148 btn |= BUTTON_MENU;
149 }
150
151 if (source & 0xc0) {
152 handle_scroll_wheel((state & 0xc0) >> 6, was_hold, 0);
153 }
154
155 /* ack any active interrupts */
156 GPIOA_INT_CLR = source;
157
158 return btn;
159}
160
161void button_init_device(void)
162{
163 GPIOA_INT_LEV = ~GPIOA_INPUT_VAL;
164 GPIOA_INT_CLR = GPIOA_INT_STAT;
165 GPIOA_INT_EN = 0xff;
166}
167
168/*
169 * Get button pressed from hardware
170 */
171int button_read_device(void)
172{
173 static bool hold_button = false;
174 bool hold_button_old;
175
176 /* normal buttons */
177 hold_button_old = hold_button;
178 hold_button = button_hold();
179
180 if (hold_button != hold_button_old)
181 backlight_hold_changed(hold_button);
182
183 return ipod_3g_button_read();
184}
185
186bool button_hold(void)
187{
188 return (GPIOA_INPUT_VAL & 0x20)?false:true;
189}