FS#8961 - Anti-Aliased Fonts.
[kugel-rb.git] / firmware / target / arm / ipod / button-mini1g.c
blob5831cdfc31e1b4c6b4b8a9e12a8636c9b500f2bf
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Daniel Stenberg
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)
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version 2
21 * of the License, or (at your option) any later version.
23 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
24 * KIND, either express or implied.
26 ****************************************************************************/
29 * Rockbox button functions
32 #include <stdlib.h>
33 #include "config.h"
34 #include "cpu.h"
35 #include "system.h"
36 #include "button.h"
37 #include "kernel.h"
38 #include "backlight.h"
39 #include "serial.h"
40 #include "power.h"
41 #include "powermgmt.h"
43 /* Variable to use for setting button status in interrupt handler */
44 int int_btn = BUTTON_NONE;
45 #ifdef HAVE_WHEEL_POSITION
46 static int wheel_position = -1;
47 static bool send_events = true;
48 #endif
50 static void handle_scroll_wheel(int new_scroll, int was_hold)
52 int wheel_keycode = BUTTON_NONE;
53 static int prev_scroll = -1;
54 static int direction = 0;
55 static int count = 0;
56 static int scroll_state[4][4] = {
57 {0, 1, -1, 0},
58 {-1, 0, 0, 1},
59 {1, 0, 0, -1},
60 {0, -1, 1, 0}
63 if ( prev_scroll == -1 ) {
64 prev_scroll = new_scroll;
66 else if (direction != scroll_state[prev_scroll][new_scroll]) {
67 direction = scroll_state[prev_scroll][new_scroll];
68 count = 0;
70 else if (!was_hold) {
71 backlight_on();
72 reset_poweroff_timer();
73 if (++count == 6) { /* reduce sensitivity */
74 count = 0;
75 /* Mini 1st Gen wheel has inverse direction mapping
76 * compared to 1st..3rd Gen wheel. */
77 switch (direction) {
78 case 1:
79 wheel_keycode = BUTTON_SCROLL_FWD;
80 break;
81 case -1:
82 wheel_keycode = BUTTON_SCROLL_BACK;
83 break;
84 default:
85 /* only happens if we get out of sync */
86 break;
90 if (wheel_keycode != BUTTON_NONE && queue_empty(&button_queue))
91 queue_post(&button_queue, wheel_keycode, 0);
92 prev_scroll = new_scroll;
95 /* mini 1 only, mini 2G uses iPod 4G code */
96 static int ipod_mini_button_read(void)
98 unsigned char source, wheel_source, state, wheel_state;
99 static bool was_hold = false;
100 int btn = BUTTON_NONE;
102 /* The ipodlinux source had a udelay(250) here, but testing has shown that
103 it is not needed - tested on mini 1g. */
104 /* udelay(250);*/
106 /* get source(s) of interupt */
107 source = GPIOA_INT_STAT & 0x3f;
108 wheel_source = GPIOB_INT_STAT & 0x30;
110 if (source == 0 && wheel_source == 0) {
111 return BUTTON_NONE; /* not for us */
114 /* get current keypad & wheel status */
115 state = GPIOA_INPUT_VAL & 0x3f;
116 wheel_state = GPIOB_INPUT_VAL & 0x30;
118 /* toggle interrupt level */
119 GPIOA_INT_LEV = ~state;
120 GPIOB_INT_LEV = ~wheel_state;
122 /* hold switch causes all outputs to go low */
123 /* we shouldn't interpret these as key presses */
124 if ((state & 0x20)) {
125 if (!(state & 0x1))
126 btn |= BUTTON_SELECT;
127 if (!(state & 0x2))
128 btn |= BUTTON_MENU;
129 if (!(state & 0x4))
130 btn |= BUTTON_PLAY;
131 if (!(state & 0x8))
132 btn |= BUTTON_RIGHT;
133 if (!(state & 0x10))
134 btn |= BUTTON_LEFT;
136 if (wheel_source & 0x30) {
137 handle_scroll_wheel((wheel_state & 0x30) >> 4, was_hold);
141 was_hold = button_hold();
143 /* ack any active interrupts */
144 if (source)
145 GPIOA_INT_CLR = source;
146 if (wheel_source)
147 GPIOB_INT_CLR = wheel_source;
149 return btn;
152 void ipod_mini_button_int(void)
154 CPU_HI_INT_DIS = GPIO0_MASK;
155 int_btn = ipod_mini_button_read();
156 //CPU_INT_EN = 0x40000000;
157 CPU_HI_INT_EN = GPIO0_MASK;
160 void button_init_device(void)
162 /* iPod Mini G1 */
163 /* buttons - enable as input */
164 GPIOA_ENABLE |= 0x3f;
165 GPIOA_OUTPUT_EN &= ~0x3f;
166 /* scroll wheel- enable as input */
167 GPIOB_ENABLE |= 0x30; /* port b 4,5 */
168 GPIOB_OUTPUT_EN &= ~0x30; /* port b 4,5 */
169 /* buttons - set interrupt levels */
170 GPIOA_INT_LEV = ~(GPIOA_INPUT_VAL & 0x3f);
171 GPIOA_INT_CLR = GPIOA_INT_STAT & 0x3f;
172 /* scroll wheel - set interrupt levels */
173 GPIOB_INT_LEV = ~(GPIOB_INPUT_VAL & 0x30);
174 GPIOB_INT_CLR = GPIOB_INT_STAT & 0x30;
175 /* enable interrupts */
176 GPIOA_INT_EN = 0x3f;
177 GPIOB_INT_EN = 0x30;
178 /* unmask interrupt */
179 CPU_INT_EN = 0x40000000;
180 CPU_HI_INT_EN = GPIO0_MASK;
184 * Get button pressed from hardware
186 int button_read_device(void)
188 static bool hold_button = false;
189 bool hold_button_old;
191 /* normal buttons */
192 hold_button_old = hold_button;
193 hold_button = button_hold();
195 if (hold_button != hold_button_old)
196 backlight_hold_changed(hold_button);
198 /* The int_btn variable is set in the button interrupt handler */
199 return int_btn;
202 bool button_hold(void)
204 return (GPIOA_INPUT_VAL & 0x20)?false:true;
207 bool headphones_inserted(void)
209 return (GPIOA_INPUT_VAL & 0x80)?true:false;