diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/target/arm/as3525/sansa-clipzip/button-clipzip.c | 96 |
1 files changed, 55 insertions, 41 deletions
diff --git a/firmware/target/arm/as3525/sansa-clipzip/button-clipzip.c b/firmware/target/arm/as3525/sansa-clipzip/button-clipzip.c index e960b49b77..40b20cdce3 100644 --- a/firmware/target/arm/as3525/sansa-clipzip/button-clipzip.c +++ b/firmware/target/arm/as3525/sansa-clipzip/button-clipzip.c | |||
@@ -27,6 +27,59 @@ | |||
27 | #include "kernel.h" | 27 | #include "kernel.h" |
28 | #include "system-target.h" | 28 | #include "system-target.h" |
29 | 29 | ||
30 | static int keyscan(void) | ||
31 | { | ||
32 | static int buttons = 0; | ||
33 | static int row = 1; | ||
34 | |||
35 | switch (row) { | ||
36 | |||
37 | case 1: | ||
38 | /* read row 1 */ | ||
39 | buttons &= ~(BUTTON_RIGHT | BUTTON_SELECT | BUTTON_UP); | ||
40 | if (GPIOC_PIN(3)) { | ||
41 | buttons |= BUTTON_RIGHT; | ||
42 | } | ||
43 | if (GPIOC_PIN(4)) { | ||
44 | buttons |= BUTTON_SELECT; | ||
45 | } | ||
46 | if (GPIOC_PIN(5)) { | ||
47 | buttons |= BUTTON_UP; | ||
48 | } | ||
49 | |||
50 | /* prepare row 2 */ | ||
51 | GPIOC_PIN(1) = 0; | ||
52 | GPIOC_PIN(2) = (1 << 2); | ||
53 | row = 2; | ||
54 | break; | ||
55 | |||
56 | case 2: | ||
57 | /* read row 2 */ | ||
58 | buttons &= ~(BUTTON_HOME | BUTTON_DOWN | BUTTON_LEFT); | ||
59 | if (GPIOC_PIN(3)) { | ||
60 | buttons |= BUTTON_HOME; | ||
61 | } | ||
62 | if (GPIOC_PIN(4)) { | ||
63 | buttons |= BUTTON_DOWN; | ||
64 | } | ||
65 | if (GPIOC_PIN(5)) { | ||
66 | buttons |= BUTTON_LEFT; | ||
67 | } | ||
68 | |||
69 | /* prepare row 1 */ | ||
70 | GPIOC_PIN(1) = (1 << 1); | ||
71 | GPIOC_PIN(2) = 0; | ||
72 | row = 1; | ||
73 | break; | ||
74 | |||
75 | default: | ||
76 | row = 1; | ||
77 | break; | ||
78 | } | ||
79 | |||
80 | return buttons; | ||
81 | } | ||
82 | |||
30 | void button_init_device(void) | 83 | void button_init_device(void) |
31 | { | 84 | { |
32 | /* GPIO A6, A7 and D6 are direct button inputs */ | 85 | /* GPIO A6, A7 and D6 are direct button inputs */ |
@@ -39,15 +92,6 @@ void button_init_device(void) | |||
39 | GPIOC_DIR &= ~((1 << 3) | (1 << 4) | (1 << 5)); | 92 | GPIOC_DIR &= ~((1 << 3) | (1 << 4) | (1 << 5)); |
40 | } | 93 | } |
41 | 94 | ||
42 | /* TODO: | ||
43 | Instead of using udelay to wait for buttons to settle, we could use a | ||
44 | simple state machine to alternate between key matrix rows (like we do on | ||
45 | the clip) and this way avoid burning cycles in the udelay. | ||
46 | |||
47 | TODO: | ||
48 | Figure out the real mappings from GPIOs to buttons. | ||
49 | The current mapping is just an educated guess. | ||
50 | */ | ||
51 | int button_read_device(void) | 95 | int button_read_device(void) |
52 | { | 96 | { |
53 | int buttons = 0; | 97 | int buttons = 0; |
@@ -64,39 +108,9 @@ int button_read_device(void) | |||
64 | if (GPIOA_PIN(7)) { | 108 | if (GPIOA_PIN(7)) { |
65 | buttons |= BUTTON_VOL_UP; | 109 | buttons |= BUTTON_VOL_UP; |
66 | } | 110 | } |
67 | |||
68 | /* key matrix buttons, first row */ | ||
69 | GPIOC_PIN(1) = (1 << 1); | ||
70 | GPIOC_PIN(2) = 0; | ||
71 | udelay(500); | ||
72 | |||
73 | if (GPIOC_PIN(3)) { | ||
74 | buttons |= BUTTON_RIGHT; | ||
75 | } | ||
76 | if (GPIOC_PIN(4)) { | ||
77 | buttons |= BUTTON_SELECT; | ||
78 | } | ||
79 | if (GPIOC_PIN(5)) { | ||
80 | buttons |= BUTTON_UP; | ||
81 | } | ||
82 | |||
83 | /* key matrix buttons, second row */ | ||
84 | GPIOC_PIN(1) = 0; | ||
85 | GPIOC_PIN(2) = (1 << 2); | ||
86 | udelay(500); | ||
87 | |||
88 | if (GPIOC_PIN(3)) { | ||
89 | buttons |= BUTTON_HOME; | ||
90 | } | ||
91 | if (GPIOC_PIN(4)) { | ||
92 | buttons |= BUTTON_DOWN; | ||
93 | } | ||
94 | if (GPIOC_PIN(5)) { | ||
95 | buttons |= BUTTON_LEFT; | ||
96 | } | ||
97 | 111 | ||
98 | /* deselect scan rows */ | 112 | /* keyscan buttons */ |
99 | GPIOC_PIN(2) = 0; | 113 | buttons |= keyscan(); |
100 | 114 | ||
101 | return buttons; | 115 | return buttons; |
102 | } | 116 | } |