summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c140
-rw-r--r--firmware/target/arm/imx233/sansa-fuzeplus/button-target.h1
2 files changed, 90 insertions, 51 deletions
diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c b/firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c
index 1474e067c1..afabdd3bc3 100644
--- a/firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c
+++ b/firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c
@@ -42,7 +42,7 @@ bool button_debug_screen(void)
42 int sensor_resol = rmi_read_single(RMI_2D_SENSOR_RESOLUTION(0)); 42 int sensor_resol = rmi_read_single(RMI_2D_SENSOR_RESOLUTION(0));
43 int min_dist = rmi_read_single(RMI_2D_MIN_DIST); 43 int min_dist = rmi_read_single(RMI_2D_MIN_DIST);
44 int gesture_settings = rmi_read_single(RMI_2D_GESTURE_SETTINGS); 44 int gesture_settings = rmi_read_single(RMI_2D_GESTURE_SETTINGS);
45 int sensibility_counter = 0; 45 int volkeys_delay_counter = 0;
46 union 46 union
47 { 47 {
48 unsigned char data; 48 unsigned char data;
@@ -72,6 +72,7 @@ bool button_debug_screen(void)
72 72
73 while(1) 73 while(1)
74 { 74 {
75 unsigned char sleep_mode = rmi_read_single(RMI_DEVICE_CONTROL) & RMI_SLEEP_MODE_BM;
75 lcd_set_viewport(NULL); 76 lcd_set_viewport(NULL);
76 lcd_clear_display(); 77 lcd_clear_display();
77 int btns = button_read_device(); 78 int btns = button_read_device();
@@ -84,7 +85,7 @@ bool button_debug_screen(void)
84 rmi_read_single(RMI_INTERRUPT_REQUEST)); 85 rmi_read_single(RMI_INTERRUPT_REQUEST));
85 lcd_putsf(0, 4, "sensi: %d min_dist: %d", (int)sensitivity.value, min_dist); 86 lcd_putsf(0, 4, "sensi: %d min_dist: %d", (int)sensitivity.value, min_dist);
86 lcd_putsf(0, 5, "gesture: %x", gesture_settings); 87 lcd_putsf(0, 5, "gesture: %x", gesture_settings);
87 88
88 union 89 union
89 { 90 {
90 unsigned char data[10]; 91 unsigned char data[10];
@@ -100,12 +101,13 @@ bool button_debug_screen(void)
100 int nr_fingers = u.s.absolute.misc & 7; 101 int nr_fingers = u.s.absolute.misc & 7;
101 bool gesture = (u.s.absolute.misc & 8) == 8; 102 bool gesture = (u.s.absolute.misc & 8) == 8;
102 int palm_width = u.s.absolute.misc >> 4; 103 int palm_width = u.s.absolute.misc >> 4;
104
103 rmi_read(RMI_DATA_REGISTER(0), 10, u.data); 105 rmi_read(RMI_DATA_REGISTER(0), 10, u.data);
104 lcd_putsf(0, 6, "abs: %d %d %d", absolute_x, absolute_y, (int)u.s.absolute.z); 106 lcd_putsf(0, 6, "abs: %d %d %d", absolute_x, absolute_y, (int)u.s.absolute.z);
105 lcd_putsf(0, 7, "rel: %d %d", (int)u.s.relative.x, (int)u.s.relative.y); 107 lcd_putsf(0, 7, "rel: %d %d", (int)u.s.relative.x, (int)u.s.relative.y);
106 lcd_putsf(0, 8, "gesture: %x %x", u.s.gesture.misc, u.s.gesture.flick); 108 lcd_putsf(0, 8, "gesture: %x %x", u.s.gesture.misc, u.s.gesture.flick);
107 lcd_putsf(0, 9, "misc: w=%d g=%d f=%d", palm_width, gesture, nr_fingers); 109 lcd_putsf(0, 9, "misc: w=%d g=%d f=%d", palm_width, gesture, nr_fingers);
108 110 lcd_putsf(30, 7, "sleep_mode: %d", 1 - sleep_mode);
109 lcd_set_viewport(&report_vp); 111 lcd_set_viewport(&report_vp);
110 lcd_set_drawinfo(DRMODE_SOLID, LCD_RGBPACK(0xff, 0, 0), LCD_BLACK); 112 lcd_set_drawinfo(DRMODE_SOLID, LCD_RGBPACK(0xff, 0, 0), LCD_BLACK);
111 lcd_drawrect(0, 0, zone_w, zone_h); 113 lcd_drawrect(0, 0, zone_w, zone_h);
@@ -153,21 +155,22 @@ bool button_debug_screen(void)
153 } 155 }
154 } 156 }
155 lcd_update(); 157 lcd_update();
156
157 if(btns & BUTTON_POWER) 158 if(btns & BUTTON_POWER)
158 break; 159 break;
159 if(btns & BUTTON_VOL_DOWN || btns & BUTTON_VOL_UP) 160 if(btns & (BUTTON_VOL_DOWN|BUTTON_VOL_UP))
160 { 161 {
161 if(btns & BUTTON_VOL_UP) 162 volkeys_delay_counter++;
162 sensibility_counter++; 163 if(volkeys_delay_counter == 15)
163 if(btns & BUTTON_VOL_DOWN)
164 sensibility_counter--;
165 if((sensibility_counter == -15) || (sensibility_counter == 15))
166 { 164 {
167 sensitivity.value += (sensibility_counter / 15); 165 if(btns & BUTTON_VOL_UP)
168 sensibility_counter = 0; 166 if(sleep_mode > RMI_SLEEP_MODE_FORCE_FULLY_AWAKE)
167 sleep_mode--;
168 if(btns & BUTTON_VOL_DOWN)
169 if(sleep_mode < RMI_SLEEP_MODE_SENSOR_SLEEP)
170 sleep_mode++;
171 rmi_set_sleep_mode(sleep_mode);
172 volkeys_delay_counter = 0;
169 } 173 }
170 rmi_write(RMI_2D_SENSITIVITY_ADJ, 1, &sensitivity.data);
171 } 174 }
172 175
173 yield(); 176 yield();
@@ -200,11 +203,16 @@ static struct button_area_t button_areas[] =
200 203
201#define RMI_INTERRUPT 1 204#define RMI_INTERRUPT 1
202#define RMI_SET_SENSITIVITY 2 205#define RMI_SET_SENSITIVITY 2
206#define RMI_SET_SLEEP_MODE 3
207/* timeout before lowering touchpad power from lack of activity */
208#define ACTIVITY_TMO (5 * HZ)
203 209
204static int touchpad_btns = 0; 210static int touchpad_btns = 0;
205static long rmi_stack [DEFAULT_STACK_SIZE/sizeof(long)]; 211static long rmi_stack [DEFAULT_STACK_SIZE/sizeof(long)];
206static const char rmi_thread_name[] = "rmi"; 212static const char rmi_thread_name[] = "rmi";
207static struct event_queue rmi_queue; 213static struct event_queue rmi_queue;
214static unsigned last_activity = 0;
215static bool t_enable = true;
208 216
209static int find_button(int x, int y) 217static int find_button(int x, int y)
210{ 218{
@@ -233,6 +241,45 @@ static void rmi_attn_cb(int bank, int pin, intptr_t user)
233 queue_post(&rmi_queue, RMI_INTERRUPT, 0); 241 queue_post(&rmi_queue, RMI_INTERRUPT, 0);
234} 242}
235 243
244static void do_interrupt(void)
245{
246 /* rmi_set_sleep_mode() does not do anything if the value
247 * it is given is already the one setted */
248 rmi_set_sleep_mode(RMI_SLEEP_MODE_LOW_POWER);
249 last_activity = current_tick;
250 /* clear interrupt */
251 rmi_read_single(RMI_INTERRUPT_REQUEST);
252 /* read data */
253 union
254 {
255 unsigned char data[10];
256 struct
257 {
258 struct rmi_2d_absolute_data_t absolute;
259 struct rmi_2d_relative_data_t relative;
260 struct rmi_2d_gesture_data_t gesture;
261 }s;
262 }u;
263 rmi_read(RMI_DATA_REGISTER(0), 10, u.data);
264 int absolute_x = u.s.absolute.x_msb << 8 | u.s.absolute.x_lsb;
265 int absolute_y = u.s.absolute.y_msb << 8 | u.s.absolute.y_lsb;
266 int nr_fingers = u.s.absolute.misc & 7;
267
268 if(nr_fingers == 1)
269 touchpad_btns = find_button(absolute_x, absolute_y);
270 else
271 touchpad_btns = 0;
272
273 /* enable interrupt */
274 imx233_pinctrl_setup_irq(0, 27, true, true, false, &rmi_attn_cb, 0);
275}
276
277void touchdev_enable(bool en)
278{
279 t_enable = en;
280 queue_post(&rmi_queue, RMI_SET_SLEEP_MODE, en ? RMI_SLEEP_MODE_LOW_POWER : RMI_SLEEP_MODE_SENSOR_SLEEP);
281}
282
236void touchpad_set_sensitivity(int level) 283void touchpad_set_sensitivity(int level)
237{ 284{
238 queue_post(&rmi_queue, RMI_SET_SENSITIVITY, level); 285 queue_post(&rmi_queue, RMI_SET_SENSITIVITY, level);
@@ -244,47 +291,36 @@ static void rmi_thread(void)
244 291
245 while(1) 292 while(1)
246 { 293 {
247 queue_wait(&rmi_queue, &ev); 294 /* make sure to timeout often enough for the activity timeout to take place */
295 queue_wait_w_tmo(&rmi_queue, &ev, HZ);
248 /* handle usb connect and ignore all messages except rmi interrupts */ 296 /* handle usb connect and ignore all messages except rmi interrupts */
249 if(ev.id == SYS_USB_CONNECTED) 297 switch(ev.id)
250 {
251 usb_acknowledge(SYS_USB_CONNECTED_ACK);
252 continue;
253 }
254 else if(ev.id == RMI_SET_SENSITIVITY)
255 { 298 {
256 /* handle negative values as well ! */ 299 case SYS_USB_CONNECTED:
257 rmi_write_single(RMI_2D_SENSITIVITY_ADJ, (unsigned char)(int8_t)ev.data); 300 usb_acknowledge(SYS_USB_CONNECTED_ACK);
258 continue; 301 break;
302 case RMI_SET_SENSITIVITY:
303 /* handle negative values as well ! */
304 rmi_write_single(RMI_2D_SENSITIVITY_ADJ, (unsigned char)(int8_t)ev.data);
305 break;
306 case RMI_SET_SLEEP_MODE:
307 /* reset activity */
308 last_activity = current_tick;
309 rmi_set_sleep_mode(ev.data);
310 break;
311 case RMI_INTERRUPT:
312 do_interrupt();
313 break;
314 default:
315 /* activity timeout */
316 if(TIME_AFTER(current_tick, last_activity + ACTIVITY_TMO))
317 {
318 /* don't change power mode if touchpad is disabled, it's already in sleep mode */
319 if(t_enable)
320 rmi_set_sleep_mode(RMI_SLEEP_MODE_VERY_LOW_POWER);
321 }
322 break;
259 } 323 }
260 else if(ev.id != RMI_INTERRUPT)
261 continue;
262 /* clear interrupt */
263 rmi_read_single(RMI_INTERRUPT_REQUEST);
264 /* read data */
265 union
266 {
267 unsigned char data[10];
268 struct
269 {
270 struct rmi_2d_absolute_data_t absolute;
271 struct rmi_2d_relative_data_t relative;
272 struct rmi_2d_gesture_data_t gesture;
273 }s;
274 }u;
275 rmi_read(RMI_DATA_REGISTER(0), 10, u.data);
276 int absolute_x = u.s.absolute.x_msb << 8 | u.s.absolute.x_lsb;
277 int absolute_y = u.s.absolute.y_msb << 8 | u.s.absolute.y_lsb;
278 int nr_fingers = u.s.absolute.misc & 7;
279
280
281 if(nr_fingers == 1)
282 touchpad_btns = find_button(absolute_x, absolute_y);
283 else
284 touchpad_btns = 0;
285
286 /* enable interrupt */
287 imx233_pinctrl_setup_irq(0, 27, true, true, false, &rmi_attn_cb, 0);
288 } 324 }
289} 325}
290 326
@@ -337,6 +373,8 @@ void button_init_device(void)
337 queue_init(&rmi_queue, true); 373 queue_init(&rmi_queue, true);
338 create_thread(rmi_thread, rmi_stack, sizeof(rmi_stack), 0, 374 create_thread(rmi_thread, rmi_stack, sizeof(rmi_stack), 0,
339 rmi_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU)); 375 rmi_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
376 /* low power mode seems to be enough for normal use */
377 rmi_set_sleep_mode(RMI_SLEEP_MODE_LOW_POWER);
340 /* enable interrupt */ 378 /* enable interrupt */
341 imx233_pinctrl_acquire(0, 27, "touchpad int"); 379 imx233_pinctrl_acquire(0, 27, "touchpad int");
342 imx233_pinctrl_set_function(0, 27, PINCTRL_FUNCTION_GPIO); 380 imx233_pinctrl_set_function(0, 27, PINCTRL_FUNCTION_GPIO);
diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/button-target.h b/firmware/target/arm/imx233/sansa-fuzeplus/button-target.h
index 58e8d3179c..1c94b76cdc 100644
--- a/firmware/target/arm/imx233/sansa-fuzeplus/button-target.h
+++ b/firmware/target/arm/imx233/sansa-fuzeplus/button-target.h
@@ -24,6 +24,7 @@
24#include <stdbool.h> 24#include <stdbool.h>
25bool button_debug_screen(void); 25bool button_debug_screen(void);
26void touchpad_set_sensitivity(int level); 26void touchpad_set_sensitivity(int level);
27void touchdev_enable(bool en);
27 28
28/* Main unit's buttons */ 29/* Main unit's buttons */
29#define BUTTON_POWER 0x00000001 30#define BUTTON_POWER 0x00000001