diff options
Diffstat (limited to 'firmware/target/arm/s5l8700/yps3')
-rw-r--r-- | firmware/target/arm/s5l8700/yps3/button-yps3.c | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/firmware/target/arm/s5l8700/yps3/button-yps3.c b/firmware/target/arm/s5l8700/yps3/button-yps3.c new file mode 100644 index 0000000000..74b5e130c3 --- /dev/null +++ b/firmware/target/arm/s5l8700/yps3/button-yps3.c | |||
@@ -0,0 +1,146 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2009 Bertrik Sikken | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include <stdbool.h> | ||
23 | #include "config.h" | ||
24 | |||
25 | #include "inttypes.h" | ||
26 | #include "s5l8700.h" | ||
27 | #include "button-target.h" | ||
28 | |||
29 | /* Button driver for the touch keys on the Samsung YP-S3 | ||
30 | |||
31 | The exact controller is not known, but it is likely from Melfas. | ||
32 | |||
33 | The protocol is as follows: | ||
34 | * the communication is done using three signals: DRDY, DCLK and DOUT | ||
35 | * in the idle state these signals are all high. | ||
36 | * when a key is touched or released, the key controller pulls down DRDY | ||
37 | and outputs the first bit of a 20-bit word on its DOUT signal. | ||
38 | * the CPU stores the bit, then acknowledges it by toggling the DCLK signal. | ||
39 | * the key controller prepares the next bit, then toggles its DRDY output, | ||
40 | unless all 20 bits have been transferred (in that case it stays high). | ||
41 | * the 20-bit word contains separate bits for each button, some fixed bits | ||
42 | and a bit indicating the number of keys pressed (modulo 2). | ||
43 | */ | ||
44 | |||
45 | |||
46 | void button_init_device(void) | ||
47 | { | ||
48 | /* P0.5/P1.0 power switch input */ | ||
49 | PCON0 &= ~(3 << 10); | ||
50 | PCON1 &= ~0x0000000F; | ||
51 | |||
52 | /* P1.5 DATA, P1.6 DRDY inputs (touch key controller) */ | ||
53 | PCON1 &= ~0x0FF00000; | ||
54 | |||
55 | /* P3.4 DCLK output (touch key controller) */ | ||
56 | PCON3 = (PCON3 & ~0x000F0000) | 0x00010000; | ||
57 | PDAT3 |= (1 << 4); | ||
58 | |||
59 | /* P4.3 hold switch input */ | ||
60 | PCON4 &= ~0x0000F000; | ||
61 | } | ||
62 | |||
63 | static unsigned int tkey_read(void) | ||
64 | { | ||
65 | static int value = 0; | ||
66 | int i; | ||
67 | |||
68 | /* check activity */ | ||
69 | if (PDAT1 & (1 << 6)) { | ||
70 | return value; | ||
71 | } | ||
72 | |||
73 | /* get key bits */ | ||
74 | value = 0; | ||
75 | for (i = 0; i < 10; i++) { | ||
76 | /* sample bit from falling edge of DRDY */ | ||
77 | while ((PDAT1 & (1 << 6)) != 0); | ||
78 | value <<= 1; | ||
79 | if (PDAT1 & (1 << 5)) { | ||
80 | value |= 1; | ||
81 | } | ||
82 | |||
83 | /* acknowledge on DCLK */ | ||
84 | PDAT3 &= ~(1 << 4); | ||
85 | |||
86 | /* sample bit from rising edge of DRDY */ | ||
87 | while ((PDAT1 & (1 << 6)) == 0); | ||
88 | value <<= 1; | ||
89 | if (PDAT1 & (1 << 5)) { | ||
90 | value |= 1; | ||
91 | } | ||
92 | |||
93 | /* acknowledge on DCLK */ | ||
94 | PDAT3 |= (1 << 4); | ||
95 | } | ||
96 | return value; | ||
97 | } | ||
98 | |||
99 | |||
100 | int button_read_device(void) | ||
101 | { | ||
102 | int buttons = 0; | ||
103 | static unsigned int data; | ||
104 | |||
105 | /* hold switch */ | ||
106 | if (button_hold()) { | ||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | /* power button */ | ||
111 | if (PDAT1 & (1 << 0)) { | ||
112 | buttons |= BUTTON_POWER; | ||
113 | } | ||
114 | |||
115 | /* touch keys */ | ||
116 | data = tkey_read(); | ||
117 | if (data & (1 << 9)) { | ||
118 | buttons |= BUTTON_BACK; | ||
119 | } | ||
120 | if (data & (1 << 8)) { | ||
121 | buttons |= BUTTON_UP; | ||
122 | } | ||
123 | if (data & (1 << 7)) { | ||
124 | buttons |= BUTTON_MENU; | ||
125 | } | ||
126 | if (data & (1 << 6)) { | ||
127 | buttons |= BUTTON_LEFT; | ||
128 | } | ||
129 | if (data & (1 << 5)) { | ||
130 | buttons |= BUTTON_SELECT; | ||
131 | } | ||
132 | if (data & (1 << 4)) { | ||
133 | buttons |= BUTTON_RIGHT; | ||
134 | } | ||
135 | if (data & (1 << 3)) { | ||
136 | buttons |= BUTTON_DOWN; | ||
137 | } | ||
138 | |||
139 | return buttons; | ||
140 | } | ||
141 | |||
142 | bool button_hold(void) | ||
143 | { | ||
144 | return (PDAT4 & (1 << 3)); | ||
145 | } | ||
146 | |||