summaryrefslogtreecommitdiff
path: root/firmware/drivers/button.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/button.c')
-rw-r--r--firmware/drivers/button.c234
1 files changed, 8 insertions, 226 deletions
diff --git a/firmware/drivers/button.c b/firmware/drivers/button.c
index 01b9174dae..deaf7f2fdd 100644
--- a/firmware/drivers/button.c
+++ b/firmware/drivers/button.c
@@ -9,12 +9,6 @@
9 * 9 *
10 * Copyright (C) 2002 by Daniel Stenberg 10 * Copyright (C) 2002 by Daniel Stenberg
11 * 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. 12 * 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. 13 * See the file COPYING in the source tree root for full license agreement.
20 * 14 *
@@ -29,25 +23,19 @@
29 23
30#include <stdlib.h> 24#include <stdlib.h>
31#include "config.h" 25#include "config.h"
32#include "cpu.h"
33#include "system.h" 26#include "system.h"
34#include "button.h" 27#include "button.h"
35#include "kernel.h" 28#include "kernel.h"
36#include "backlight.h" 29#include "backlight.h"
37#include "adc.h"
38#include "serial.h" 30#include "serial.h"
39#include "power.h" 31#include "power.h"
40#include "system.h"
41#include "powermgmt.h" 32#include "powermgmt.h"
33#include "button-target.h"
42 34
43#ifdef HAVE_REMOTE_LCD 35#ifdef HAVE_REMOTE_LCD
44#include "lcd-remote.h" 36#include "lcd-remote.h"
45#endif 37#endif
46 38
47#ifdef TARGET_TREE
48#include "button-target.h"
49#endif
50
51struct event_queue button_queue; 39struct event_queue button_queue;
52 40
53static long lastbtn; /* Last valid button status */ 41static long lastbtn; /* Last valid button status */
@@ -60,6 +48,9 @@ static bool filter_first_keypress;
60#ifdef HAVE_REMOTE_LCD 48#ifdef HAVE_REMOTE_LCD
61static bool remote_filter_first_keypress; 49static bool remote_filter_first_keypress;
62#endif 50#endif
51#endif /* CONFIG_BACKLIGHT */
52#ifdef HAVE_HEADPHONE_DETECTION
53bool phones_present = false;
63#endif 54#endif
64 55
65/* how long until repeat kicks in, in ticks */ 56/* how long until repeat kicks in, in ticks */
@@ -71,18 +62,8 @@ static bool remote_filter_first_keypress;
71/* speed repeat finishes at, in ticks */ 62/* speed repeat finishes at, in ticks */
72#define REPEAT_INTERVAL_FINISH 5 63#define REPEAT_INTERVAL_FINISH 5
73 64
74/* the power-off button and number of repeated keys before shutting off */
75#if !defined(TARGET_TREE)
76#define POWEROFF_BUTTON BUTTON_OFF
77#define POWEROFF_COUNT 10
78#endif
79
80static int button_read(void); 65static int button_read(void);
81 66
82#ifdef HAVE_HEADPHONE_DETECTION
83bool phones_present = false;
84#endif
85
86static void button_tick(void) 67static void button_tick(void)
87{ 68{
88 static int count = 0; 69 static int count = 0;
@@ -99,8 +80,7 @@ static void button_tick(void)
99 int diff; 80 int diff;
100 int btn; 81 int btn;
101 82
102#if (CONFIG_KEYPAD == PLAYER_PAD) || (CONFIG_KEYPAD == RECORDER_PAD) 83#ifdef HAS_SERIAL_REMOTE
103
104 /* Post events for the remote control */ 84 /* Post events for the remote control */
105 btn = remote_control_rx(); 85 btn = remote_control_rx();
106 if(btn) 86 if(btn)
@@ -180,9 +160,7 @@ static void button_tick(void)
180 key */ 160 key */
181#ifdef HAVE_SW_POWEROFF 161#ifdef HAVE_SW_POWEROFF
182 if ((btn == POWEROFF_BUTTON 162 if ((btn == POWEROFF_BUTTON
183#ifdef BUTTON_RC_STOP 163#ifdef RC_POWEROFF_BUTTON
184 || btn == BUTTON_RC_STOP
185#elif defined(RC_POWEROFF_BUTTON)
186 || btn == RC_POWEROFF_BUTTON 164 || btn == RC_POWEROFF_BUTTON
187#endif 165#endif
188 ) && 166 ) &&
@@ -299,22 +277,8 @@ long button_get_w_tmo(int ticks)
299void button_init(void) 277void button_init(void)
300{ 278{
301 /* hardware inits */ 279 /* hardware inits */
302#ifdef TARGET_TREE
303 button_init_device(); 280 button_init_device();
304 281
305#elif CONFIG_KEYPAD == RECORDER_PAD
306 /* Set PB4 and PB8 as input pins */
307 PBCR1 &= 0xfffc; /* PB8MD = 00 */
308 PBCR2 &= 0xfcff; /* PB4MD = 00 */
309 PBIOR &= ~0x0110; /* Inputs */
310#elif CONFIG_KEYPAD == PLAYER_PAD
311 /* set PA5 and PA11 as input pins */
312 PACR1 &= 0xff3f; /* PA11MD = 00 */
313 PACR2 &= 0xfbff; /* PA5MD = 0 */
314 PAIOR &= ~0x0820; /* Inputs */
315#elif CONFIG_KEYPAD == ONDIO_PAD
316 /* nothing to initialize here */
317#endif /* CONFIG_KEYPAD */
318 queue_init(&button_queue, true); 282 queue_init(&button_queue, true);
319 button_read(); 283 button_read();
320 lastbtn = button_read(); 284 lastbtn = button_read();
@@ -410,194 +374,12 @@ void set_remote_backlight_filter_keypress(bool value)
410#endif 374#endif
411 375
412/* 376/*
413 Archos hardware button hookup
414 =============================
415
416 Recorder / Recorder FM/V2
417 -------------------------
418 F1, F2, F3, UP: connected to AN4 through a resistor network
419 DOWN, PLAY, LEFT, RIGHT: likewise connected to AN5
420
421 The voltage on AN4/ AN5 depends on which keys (or key combo) is pressed
422 FM/V2 has PLAY and RIGHT switched compared to plain recorder
423
424 ON: PB8, low active (plain recorder) / AN3, low active (fm/v2)
425 OFF: PB4, low active (plain recorder) / AN2, high active (fm/v2)
426
427 Player
428 ------
429 LEFT: AN0
430 MENU: AN1
431 RIGHT: AN2
432 PLAY: AN3
433
434 STOP: PA11
435 ON: PA5
436
437 All buttons are low active
438
439 Ondio
440 -----
441 LEFT, RIGHT, UP, DOWN: connected to AN4 through a resistor network
442
443 The voltage on AN4 depends on which keys (or key combo) is pressed
444
445 OPTION: AN2, high active (assigned as MENU)
446 ON/OFF: AN3, low active (assigned as OFF)
447
448*/
449
450#if CONFIG_KEYPAD == RECORDER_PAD
451
452#ifdef HAVE_FMADC
453/* FM Recorder super-special levels */
454#define LEVEL1 150
455#define LEVEL2 385
456#define LEVEL3 545
457#define LEVEL4 700
458#define ROW2_BUTTON1 BUTTON_PLAY
459#define ROW2_BUTTON3 BUTTON_RIGHT
460
461#else
462/* plain bog standard Recorder levels */
463#define LEVEL1 250
464#define LEVEL2 500
465#define LEVEL3 700
466#define LEVEL4 900
467#define ROW2_BUTTON1 BUTTON_RIGHT
468#define ROW2_BUTTON3 BUTTON_PLAY
469#endif /* HAVE_FMADC */
470
471#elif CONFIG_KEYPAD == ONDIO_PAD
472/* Ondio levels */
473#define LEVEL1 165
474#define LEVEL2 415
475#define LEVEL3 585
476#define LEVEL4 755
477
478#endif /* CONFIG_KEYPAD */
479
480/*
481 * Get button pressed from hardware 377 * Get button pressed from hardware
482 */ 378 */
483static int button_read(void) 379static int button_read(void)
484{ 380{
485 int btn = BUTTON_NONE; 381 int btn = button_read_device();
486 int retval; 382 int retval;
487#ifndef TARGET_TREE
488 int data;
489#endif
490
491#ifdef TARGET_TREE
492 btn = button_read_device();
493
494#elif CONFIG_KEYPAD == RECORDER_PAD
495#ifndef HAVE_FMADC
496 static int off_button_count = 0;
497#endif
498
499 /* check F1..F3 and UP */
500 data = adc_read(ADC_BUTTON_ROW1);
501 if (data >= LEVEL1)
502 {
503 if (data >= LEVEL3)
504 if (data >= LEVEL4)
505 btn = BUTTON_F3;
506 else
507 btn = BUTTON_UP;
508 else
509 if (data >= LEVEL2)
510 btn = BUTTON_F2;
511 else
512 btn = BUTTON_F1;
513 }
514
515 /* Some units have mushy keypads, so pressing UP also activates
516 the Left/Right buttons. Let's combat that by skipping the AN5
517 checks when UP is pressed. */
518 if(!(btn & BUTTON_UP))
519 {
520 /* check DOWN, PLAY, LEFT, RIGHT */
521 data = adc_read(ADC_BUTTON_ROW2);
522 if (data >= LEVEL1)
523 {
524 if (data >= LEVEL3)
525 if (data >= LEVEL4)
526 btn |= BUTTON_DOWN;
527 else
528 btn |= ROW2_BUTTON3;
529 else
530 if (data >= LEVEL2)
531 btn |= BUTTON_LEFT;
532 else
533 btn |= ROW2_BUTTON1;
534 }
535 }
536
537#ifdef HAVE_FMADC
538 if ( adc_read(ADC_BUTTON_ON) < 512 )
539 btn |= BUTTON_ON;
540 if ( adc_read(ADC_BUTTON_OFF) > 512 )
541 btn |= BUTTON_OFF;
542#else
543 /* check port B pins for ON and OFF */
544 data = PBDR;
545 if ((data & 0x0100) == 0)
546 btn |= BUTTON_ON;
547
548 if ((data & 0x0010) == 0)
549 {
550 /* When the batteries are low, the low-battery shutdown logic causes
551 * spurious OFF events due to voltage fluctuation on some units.
552 * Only accept OFF when read several times in sequence. */
553 if (++off_button_count > 3)
554 btn |= BUTTON_OFF;
555 }
556 else
557 off_button_count = 0;
558#endif
559
560#elif CONFIG_KEYPAD == PLAYER_PAD
561 /* buttons are active low */
562 if (adc_read(0) < 0x180)
563 btn = BUTTON_LEFT;
564 if (adc_read(1) < 0x180)
565 btn |= BUTTON_MENU;
566 if(adc_read(2) < 0x180)
567 btn |= BUTTON_RIGHT;
568 if(adc_read(3) < 0x180)
569 btn |= BUTTON_PLAY;
570
571 /* check port A pins for ON and STOP */
572 data = PADR;
573 if ( !(data & 0x0020) )
574 btn |= BUTTON_ON;
575 if ( !(data & 0x0800) )
576 btn |= BUTTON_STOP;
577
578#elif CONFIG_KEYPAD == ONDIO_PAD
579 /* Check the 4 direction keys */
580 data = adc_read(ADC_BUTTON_ROW1);
581 if (data >= LEVEL1)
582 {
583 if (data >= LEVEL3)
584 if (data >= LEVEL4)
585 btn = BUTTON_LEFT;
586 else
587 btn = BUTTON_RIGHT;
588 else
589 if (data >= LEVEL2)
590 btn = BUTTON_UP;
591 else
592 btn = BUTTON_DOWN;
593 }
594
595 if(adc_read(ADC_BUTTON_OPTION) > 0x200) /* active high */
596 btn |= BUTTON_MENU;
597 if(adc_read(ADC_BUTTON_ONOFF) < 0x120) /* active low */
598 btn |= BUTTON_OFF;
599
600#endif /* CONFIG_KEYPAD */
601 383
602#ifdef HAVE_LCD_BITMAP 384#ifdef HAVE_LCD_BITMAP
603 if (btn && flipped) 385 if (btn && flipped)