1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
Pandora hold switch support

diff --git a/firmware/SOURCES b/firmware/SOURCES
index 85705cb..f76d34e 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -99,6 +99,11 @@ target/hosted/ypr0/gpio_ypr0.c
 target/hosted/maemo/maemo-thread.c
 #endif
 
+/* Pandora specific files */
+#if (CONFIG_PLATFORM & PLATFORM_PANDORA)
+target/hosted/pandora/hold-switch.c
+#endif
+
 /* Standard library */
 #if (CONFIG_PLATFORM & PLATFORM_NATIVE) || defined(__MINGW32__) || defined(__CYGWIN__)
 libc/errno.c
diff --git a/firmware/export/config/pandora.h b/firmware/export/config/pandora.h
index a1a2ecb..5b73d66 100644
--- a/firmware/export/config/pandora.h
+++ b/firmware/export/config/pandora.h
@@ -44,6 +44,7 @@
 /* define this to indicate your device's keypad */
 #define HAVE_TOUCHSCREEN
 #define HAVE_BUTTON_DATA
+#define HAS_BUTTON_HOLD
 
 /* define this if you have RTC RAM available for settings */
 //#define HAVE_RTC_RAM
diff --git a/firmware/target/hosted/pandora/hold-switch.c b/firmware/target/hosted/pandora/hold-switch.c
new file mode 100644
index 0000000..39edee7
--- /dev/null
+++ b/firmware/target/hosted/pandora/hold-switch.c
@@ -0,0 +1,95 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * Copyright (C) 2012 Thomas Jarosch
+ *
+ * Pandora hold switch support (not provided by the SDL layer).
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "logf.h"
+
+#include <linux/input.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "button-sdl.h"
+#include <SDL_thread.h>
+
+static int gpio_keys_fd = -1;
+
+static bool find_input_device(void)
+{
+    char name[256];
+
+    /* Find correct input device */
+    for (int i = 0; i < 100; i++)
+    {
+        sprintf(name, "/dev/input/event%i", i);
+        gpio_keys_fd = open(name, O_RDONLY);
+        if (gpio_keys_fd < 0)
+            break;
+
+        ioctl(gpio_keys_fd, EVIOCGNAME(sizeof(name)), name);
+        if (strcmp(name, "gpio-keys") == 0)
+            return true;
+
+        close(gpio_keys_fd);
+    }
+
+    return false;
+}
+
+static int hold_switch_thread(void *dummy)
+{
+    struct input_event ev;
+    int rd;
+
+    while(1)
+    {
+        rd = read(gpio_keys_fd, &ev, sizeof(struct input_event));
+        if (rd < (int) sizeof(struct input_event))
+        {
+            logf("Input read error. Ignoring.\n");
+            continue;
+        }
+
+        if (ev.type != EV_KEY || ev.code != KEY_COFFEE)
+            continue;
+
+        if (ev.value == 1 || ev.value == 2)
+            sdl_hold_button_state = true;
+        else
+            sdl_hold_button_state = false;
+    }
+
+    return 0;
+}
+
+void pandora_hold_switch_init(void)
+{
+    if (!find_input_device())
+    {
+        logf("Can't find gpio-keys input device\n");
+        return;
+    }
+
+    SDL_CreateThread(hold_switch_thread, NULL);
+
+    /* Note: No explicit thread shutdown needed,
+       we don't share any complex data structures. */
+}
diff --git a/firmware/target/hosted/pandora/hold-switch.h b/firmware/target/hosted/pandora/hold-switch.h
new file mode 100644
index 0000000..2d112a1
--- /dev/null
+++ b/firmware/target/hosted/pandora/hold-switch.h
@@ -0,0 +1,24 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * Copyright (C) 2012 by Thomas Jarosch
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef __PANDORA_HOLD_SWITCH_H__
+#define __PANDORA_HOLD_SWITCH_H__
+
+void pandora_hold_switch_init(void);
+
+#endif
diff --git a/firmware/target/hosted/sdl/button-sdl.c b/firmware/target/hosted/sdl/button-sdl.c
index 4bd4b8d..c7aee4d 100644
--- a/firmware/target/hosted/sdl/button-sdl.c
+++ b/firmware/target/hosted/sdl/button-sdl.c
@@ -75,9 +75,9 @@ static int n900_updown_key_pressed = 0;
 #endif
 
 #ifdef HAS_BUTTON_HOLD
-bool hold_button_state = false;
+bool sdl_hold_button_state = false;
 bool button_hold(void) {
-    return hold_button_state;
+    return sdl_hold_button_state;
 }
 #endif
 
@@ -328,16 +328,20 @@ static void button_event(int key, bool pressed)
         sys_poweroff();
         break;
 #endif
-#ifdef HAS_BUTTON_HOLD
+
+#if (CONFIG_PLATFORM & PLATFORM_PANDORA)
+/*  No hold button via 'h' key on pandora,
+    we have a hardware button for that */
+#elif HAS_BUTTON_HOLD
     case SDLK_h:
         if(pressed)
         {
-            hold_button_state = !hold_button_state;
-            DEBUGF("Hold button is %s\n", hold_button_state?"ON":"OFF");
+            sdl_hold_button_state = !sdl_hold_button_state;
+            DEBUGF("Hold button is %s\n", sdl_hold_button_state?"ON":"OFF");
         }
         return;
 #endif
-        
+
 #ifdef HAS_REMOTE_BUTTON_HOLD
     case SDLK_j:
         if(pressed)
diff --git a/firmware/target/hosted/sdl/button-sdl.h b/firmware/target/hosted/sdl/button-sdl.h
index 6b7f632..de0dca8 100644
--- a/firmware/target/hosted/sdl/button-sdl.h
+++ b/firmware/target/hosted/sdl/button-sdl.h
@@ -27,6 +27,7 @@
 #include "config.h"
 
 extern int sdl_app_has_input_focus;
+extern bool sdl_hold_button_state;
 
 bool button_hold(void);
 #undef button_init_device
diff --git a/firmware/target/hosted/sdl/system-sdl.c b/firmware/target/hosted/sdl/system-sdl.c
index 87b2e0c..0345924 100644
--- a/firmware/target/hosted/sdl/system-sdl.c
+++ b/firmware/target/hosted/sdl/system-sdl.c
@@ -47,6 +47,11 @@
 
 #endif
 
+#if (CONFIG_PLATFORM & PLATFORM_PANDORA)
+#include "hold-switch.h"
+#endif
+
+
 SDL_Surface    *gui_surface;
 
 bool            background = true;          /* use backgrounds by default */
@@ -163,6 +168,10 @@ static int sdl_event_thread(void * param)
     SDL_Thread *maemo_thread = SDL_CreateThread(maemo_thread_func, wait_for_maemo_startup);
 #endif
 
+#if (CONFIG_PLATFORM & PLATFORM_PANDORA)
+    pandora_hold_switch_init();
+#endif
+
     /*
      * finally enter the button loop */
     gui_message_loop();