summaryrefslogtreecommitdiff
path: root/firmware/drivers/synaptics-mep.c
diff options
context:
space:
mode:
authorMark Arigo <markarigo@gmail.com>2009-06-19 02:48:15 +0000
committerMark Arigo <markarigo@gmail.com>2009-06-19 02:48:15 +0000
commit4c58ad26ba462309f95790c32421130a73909f05 (patch)
tree96af9c1cda5f21e5af6443b13171ed66ccb1d9d1 /firmware/drivers/synaptics-mep.c
parent753064fccf270643edc8d60e46886e327b099c49 (diff)
downloadrockbox-4c58ad26ba462309f95790c32421130a73909f05.tar.gz
rockbox-4c58ad26ba462309f95790c32421130a73909f05.zip
Clean up the Synaptics touchpad driver.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21344 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers/synaptics-mep.c')
-rw-r--r--firmware/drivers/synaptics-mep.c251
1 files changed, 181 insertions, 70 deletions
diff --git a/firmware/drivers/synaptics-mep.c b/firmware/drivers/synaptics-mep.c
index 57aeefeadf..64b63397f7 100644
--- a/firmware/drivers/synaptics-mep.c
+++ b/firmware/drivers/synaptics-mep.c
@@ -24,6 +24,7 @@
24#include "cpu.h" 24#include "cpu.h"
25#include "system.h" 25#include "system.h"
26#include "kernel.h" 26#include "kernel.h"
27#include "button-target.h"
27 28
28#define LOGF_ENABLE 29#define LOGF_ENABLE
29#include "logf.h" 30#include "logf.h"
@@ -32,38 +33,46 @@
32 Protocol: 3-Wire Interface Specification" documentation */ 33 Protocol: 3-Wire Interface Specification" documentation */
33 34
34#if defined(MROBE_100) 35#if defined(MROBE_100)
35#define INT_ENABLE GPIOD_INT_LEV &= ~0x2; GPIOD_INT_EN |= 0x2 36#define INT_ENABLE GPIO_CLEAR_BITWISE(GPIOD_INT_LEV, 0x2);\
36#define INT_DISABLE GPIOD_INT_EN &= ~0x2; GPIOD_INT_CLR |= 0x2 37 GPIO_SET_BITWISE(GPIOD_INT_EN, 0x2)
38#define INT_DISABLE GPIO_CLEAR_BITWISE(GPIOD_INT_EN, 0x2);\
39 GPIO_SET_BITWISE(GPIOD_INT_CLR, 0x2)
37 40
38#define ACK (GPIOD_INPUT_VAL & 0x1) 41#define ACK (GPIOD_INPUT_VAL & 0x1)
39#define ACK_HI GPIOD_OUTPUT_VAL |= 0x1 42#define ACK_HI GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x1)
40#define ACK_LO GPIOD_OUTPUT_VAL &= ~0x1 43#define ACK_LO GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x1)
41 44
42#define CLK ((GPIOD_INPUT_VAL & 0x2) >> 1) 45#define CLK ((GPIOD_INPUT_VAL & 0x2) >> 1)
43#define CLK_HI GPIOD_OUTPUT_VAL |= 0x2 46#define CLK_HI GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x2)
44#define CLK_LO GPIOD_OUTPUT_VAL &= ~0x2 47#define CLK_LO GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x2)
45 48
46#define DATA ((GPIOD_INPUT_VAL & 0x4) >> 2) 49#define DATA ((GPIOD_INPUT_VAL & 0x4) >> 2)
47#define DATA_HI GPIOD_OUTPUT_EN |= 0x4; GPIOD_OUTPUT_VAL |= 0x4 50#define DATA_HI GPIO_SET_BITWISE(GPIOD_OUTPUT_EN, 0x4);\
48#define DATA_LO GPIOD_OUTPUT_EN |= 0x4; GPIOD_OUTPUT_VAL &= ~0x4 51 GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x4)
49#define DATA_CL GPIOD_OUTPUT_EN &= ~0x4 52#define DATA_LO GPIO_SET_BITWISE(GPIOD_OUTPUT_EN, 0x4);\
53 GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x4)
54#define DATA_CL GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_EN, 0x4)
50 55
51#elif defined(PHILIPS_HDD1630) 56#elif defined(PHILIPS_HDD1630)
52#define INT_ENABLE GPIOA_INT_LEV &= ~0x20; GPIOA_INT_EN |= 0x20 57#define INT_ENABLE GPIO_CLEAR_BITWISE(GPIOA_INT_LEV, 0x20);\
53#define INT_DISABLE GPIOA_INT_EN &= ~0x20; GPIOA_INT_CLR |= 0x20 58 GPIO_SET_BITWISE(GPIOA_INT_EN, 0x20)
59#define INT_DISABLE GPIO_CLEAR_BITWISE(GPIOA_INT_EN, 0x20);\
60 GPIO_SET_BITWISE(GPIOA_INT_CLR, 0x20)
54 61
55#define ACK (GPIOD_INPUT_VAL & 0x80) 62#define ACK (GPIOD_INPUT_VAL & 0x80)
56#define ACK_HI GPIOD_OUTPUT_VAL |= 0x80 63#define ACK_HI GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x80)
57#define ACK_LO GPIOD_OUTPUT_VAL &= ~0x80 64#define ACK_LO GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x80)
58 65
59#define CLK ((GPIOA_INPUT_VAL & 0x20) >> 5) 66#define CLK ((GPIOA_INPUT_VAL & 0x20) >> 5)
60#define CLK_HI GPIOA_OUTPUT_VAL |= 0x20 67#define CLK_HI GPIO_SET_BITWISE(GPIOA_OUTPUT_VAL, 0x20)
61#define CLK_LO GPIOA_OUTPUT_VAL &= ~0x20 68#define CLK_LO GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_VAL, 0x20)
62 69
63#define DATA ((GPIOA_INPUT_VAL & 0x10) >> 4) 70#define DATA ((GPIOA_INPUT_VAL & 0x10) >> 4)
64#define DATA_HI GPIOA_OUTPUT_EN |= 0x10; GPIOA_OUTPUT_VAL |= 0x10 71#define DATA_HI GPIO_SET_BITWISE(GPIOA_OUTPUT_EN, 0x10);\
65#define DATA_LO GPIOA_OUTPUT_EN |= 0x10; GPIOA_OUTPUT_VAL &= ~0x10 72 GPIO_SET_BITWISE(GPIOA_OUTPUT_VAL, 0x10)
66#define DATA_CL GPIOA_OUTPUT_EN &= ~0x10 73#define DATA_LO GPIO_SET_BITWISE(GPIOA_OUTPUT_EN, 0x10);\
74 GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_VAL, 0x10)
75#define DATA_CL GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_EN, 0x10)
67#endif 76#endif
68 77
69#define LO 0 78#define LO 0
@@ -80,6 +89,18 @@
80 89
81static unsigned short syn_status = 0; 90static unsigned short syn_status = 0;
82 91
92static void syn_enable_int(bool enable)
93{
94 if (enable)
95 {
96 INT_ENABLE;
97 }
98 else
99 {
100 INT_DISABLE;
101 }
102}
103
83static int syn_wait_clk_change(unsigned int val) 104static int syn_wait_clk_change(unsigned int val)
84{ 105{
85 int i; 106 int i;
@@ -93,6 +114,30 @@ static int syn_wait_clk_change(unsigned int val)
93 return 0; 114 return 0;
94} 115}
95 116
117static void syn_set_ack(int val)
118{
119 if (val == HI)
120 {
121 ACK_HI;
122 }
123 else
124 {
125 ACK_LO;
126 }
127}
128
129static void syn_set_data(int val)
130{
131 if (val == HI)
132 {
133 DATA_HI;
134 }
135 else
136 {
137 DATA_LO;
138 }
139}
140
96static inline int syn_get_data(void) 141static inline int syn_get_data(void)
97{ 142{
98 DATA_CL; 143 DATA_CL;
@@ -105,20 +150,20 @@ static void syn_wait_guest_flush(void)
105 handshake until DATA goes high during P3 stage */ 150 handshake until DATA goes high during P3 stage */
106 if (CLK == LO) 151 if (CLK == LO)
107 { 152 {
108 ACK_HI; /* P1 -> P2 */ 153 syn_set_ack(HI); /* P1 -> P2 */
109 syn_wait_clk_change(HI); /* P2 -> P3 */ 154 syn_wait_clk_change(HI); /* P2 -> P3 */
110 } 155 }
111 156
112 while (syn_get_data() == LO) 157 while (syn_get_data() == LO)
113 { 158 {
114 ACK_HI; /* P3 -> P0 */ 159 syn_set_ack(HI); /* P3 -> P0 */
115 syn_wait_clk_change(LO); /* P0 -> P1 */ 160 syn_wait_clk_change(LO); /* P0 -> P1 */
116 ACK_LO; /* P1 -> P2 */ 161 syn_set_ack(LO); /* P1 -> P2 */
117 syn_wait_clk_change(HI); /* P2 -> P3 */ 162 syn_wait_clk_change(HI); /* P2 -> P3 */
118 } 163 }
119 164
120 /* Continue handshaking until back to P0 */ 165 /* Continue handshaking until back to P0 */
121 ACK_HI; /* P3 -> P0 */ 166 syn_set_ack(HI); /* P3 -> P0 */
122} 167}
123 168
124static void syn_flush(void) 169static void syn_flush(void)
@@ -128,26 +173,26 @@ static void syn_flush(void)
128 logf("syn_flush..."); 173 logf("syn_flush...");
129 174
130 /* Flusher holds DATA low for at least 36 handshake cycles */ 175 /* Flusher holds DATA low for at least 36 handshake cycles */
131 DATA_LO; 176 syn_set_data(LO);
132 177
133 for (i = 0; i < 36; i++) 178 for (i = 0; i < 36; i++)
134 { 179 {
135 syn_wait_clk_change(LO); /* P0 -> P1 */ 180 syn_wait_clk_change(LO); /* P0 -> P1 */
136 ACK_LO; /* P1 -> P2 */ 181 syn_set_ack(LO); /* P1 -> P2 */
137 syn_wait_clk_change(HI); /* P2 -> P3 */ 182 syn_wait_clk_change(HI); /* P2 -> P3 */
138 ACK_HI; /* P3 -> P0 */ 183 syn_set_ack(HI); /* P3 -> P0 */
139 } 184 }
140 185
141 /* Raise DATA in P1 stage */ 186 /* Raise DATA in P1 stage */
142 syn_wait_clk_change(LO); /* P0 -> P1 */ 187 syn_wait_clk_change(LO); /* P0 -> P1 */
143 DATA_HI; 188 syn_set_data(HI);
144 189
145 /* After a flush, the flushing device enters a flush-receiving (flushee) 190 /* After a flush, the flushing device enters a flush-receiving (flushee)
146 state */ 191 state */
147 syn_wait_guest_flush(); 192 syn_wait_guest_flush();
148} 193}
149 194
150int syn_send(int *data, int len) 195static int syn_send(char *data, int len)
151{ 196{
152 int i, bit; 197 int i, bit;
153 int parity = 0; 198 int parity = 0;
@@ -155,13 +200,13 @@ int syn_send(int *data, int len)
155 logf("syn_send..."); 200 logf("syn_send...");
156 201
157 /* 1. Lower DATA line to issue a request-to-send to guest */ 202 /* 1. Lower DATA line to issue a request-to-send to guest */
158 DATA_LO; 203 syn_set_data(LO);
159 204
160 /* 2. Wait for guest to lower CLK */ 205 /* 2. Wait for guest to lower CLK */
161 syn_wait_clk_change(LO); 206 syn_wait_clk_change(LO);
162 207
163 /* 3. Lower ACK (with DATA still low) */ 208 /* 3. Lower ACK (with DATA still low) */
164 ACK_LO; 209 syn_set_ack(LO);
165 210
166 /* 4. Wait for guest to raise CLK */ 211 /* 4. Wait for guest to raise CLK */
167 syn_wait_clk_change(HI); 212 syn_wait_clk_change(HI);
@@ -177,17 +222,17 @@ int syn_send(int *data, int len)
177 /* 5a. Drive data low if bit is 0, or high if bit is 1 */ 222 /* 5a. Drive data low if bit is 0, or high if bit is 1 */
178 if (data[i] & (1 << bit)) 223 if (data[i] & (1 << bit))
179 { 224 {
180 DATA_HI; 225 syn_set_data(HI);
181 parity++; 226 parity++;
182 } 227 }
183 else 228 else
184 { 229 {
185 DATA_LO; 230 syn_set_data(LO);
186 } 231 }
187 bit++; 232 bit++;
188 233
189 /* 5b. Invert ACK to indicate that the data bit is ready */ 234 /* 5b. Invert ACK to indicate that the data bit is ready */
190 ACK_HI; 235 syn_set_ack(HI);
191 236
192 /* 5c. Wait for guest to invert CLK */ 237 /* 5c. Wait for guest to invert CLK */
193 syn_wait_clk_change(LO); 238 syn_wait_clk_change(LO);
@@ -195,16 +240,16 @@ int syn_send(int *data, int len)
195 /* Repeat for next bit */ 240 /* Repeat for next bit */
196 if (data[i] & (1 << bit)) 241 if (data[i] & (1 << bit))
197 { 242 {
198 DATA_HI; 243 syn_set_data(HI);
199 parity++; 244 parity++;
200 } 245 }
201 else 246 else
202 { 247 {
203 DATA_LO; 248 syn_set_data(LO);
204 } 249 }
205 bit++; 250 bit++;
206 251
207 ACK_LO; 252 syn_set_ack(LO);
208 253
209 syn_wait_clk_change(HI); 254 syn_wait_clk_change(HI);
210 } 255 }
@@ -217,25 +262,25 @@ int syn_send(int *data, int len)
217 parity = parity % 2; 262 parity = parity % 2;
218 if (parity) 263 if (parity)
219 { 264 {
220 DATA_HI; 265 syn_set_data(HI);
221 } 266 }
222 else 267 else
223 { 268 {
224 DATA_LO; 269 syn_set_data(LO);
225 } 270 }
226 logf(" send parity = %d", parity); 271 logf(" send parity = %d", parity);
227 272
228 /* 7b. Raise ACK to indicate that the optional parity bit is ready */ 273 /* 7b. Raise ACK to indicate that the optional parity bit is ready */
229 ACK_HI; 274 syn_set_ack(HI);
230 275
231 /* 7c. Guest lowers CLK */ 276 /* 7c. Guest lowers CLK */
232 syn_wait_clk_change(LO); 277 syn_wait_clk_change(LO);
233 278
234 /* 7d. Pull DATA high (if parity bit was 0) */ 279 /* 7d. Pull DATA high (if parity bit was 0) */
235 DATA_HI; 280 syn_set_data(HI);
236 281
237 /* 7e. Lower ACK to indicate that the stop bit is ready */ 282 /* 7e. Lower ACK to indicate that the stop bit is ready */
238 ACK_LO; 283 syn_set_ack(LO);
239 284
240 /* 7f. Guest raises CLK */ 285 /* 7f. Guest raises CLK */
241 syn_wait_clk_change(HI); 286 syn_wait_clk_change(HI);
@@ -251,15 +296,15 @@ int syn_send(int *data, int len)
251 } 296 }
252 297
253 /* 7h. Host raises ACK and the link enters the idle state */ 298 /* 7h. Host raises ACK and the link enters the idle state */
254 ACK_HI; 299 syn_set_ack(HI);
255 300
256 return len; 301 return len;
257} 302}
258 303
259static int syn_read_data(int *data, int data_len) 304static int syn_read_data(char *data, int data_len)
260{ 305{
261 int i, len, bit, parity, tmp; 306 int i, len, bit, parity;
262 int *data_ptr; 307 char *data_ptr, tmp;
263 308
264 logf("syn_read_data..."); 309 logf("syn_read_data...");
265 310
@@ -268,7 +313,7 @@ static int syn_read_data(int *data, int data_len)
268 return 0; 313 return 0;
269 314
270 /* 1a. If the host is willing to receive a packet it lowers ACK */ 315 /* 1a. If the host is willing to receive a packet it lowers ACK */
271 ACK_LO; 316 syn_set_ack(LO);
272 317
273 /* 2. Guest may issue a request-to-send by lowering DATA. If the 318 /* 2. Guest may issue a request-to-send by lowering DATA. If the
274 guest decides not to transmit a packet, it may abort the 319 guest decides not to transmit a packet, it may abort the
@@ -284,12 +329,12 @@ static int syn_read_data(int *data, int data_len)
284 { 329 {
285 logf(" read abort"); 330 logf(" read abort");
286 331
287 ACK_HI; 332 syn_set_ack(HI);
288 return READ_ERROR; 333 return READ_ERROR;
289 } 334 }
290 else 335 else
291 { 336 {
292 ACK_HI; 337 syn_set_ack(HI);
293 } 338 }
294 339
295 /* 5. Read the incoming data packet */ 340 /* 5. Read the incoming data packet */
@@ -320,7 +365,7 @@ static int syn_read_data(int *data, int data_len)
320 bit++; 365 bit++;
321 366
322 /* 5e. Invert ACK to indicate that data has been read */ 367 /* 5e. Invert ACK to indicate that data has been read */
323 ACK_LO; 368 syn_set_ack(LO);
324 369
325 /* Repeat for next bit */ 370 /* Repeat for next bit */
326 syn_wait_clk_change(HI); 371 syn_wait_clk_change(HI);
@@ -332,7 +377,7 @@ static int syn_read_data(int *data, int data_len)
332 } 377 }
333 bit++; 378 bit++;
334 379
335 ACK_HI; 380 syn_set_ack(HI);
336 } 381 }
337 382
338 /* First byte is the packet header */ 383 /* First byte is the packet header */
@@ -367,7 +412,7 @@ static int syn_read_data(int *data, int data_len)
367 /* TODO: parity error handling */ 412 /* TODO: parity error handling */
368 413
369 /* 7d. The host lowers ACK */ 414 /* 7d. The host lowers ACK */
370 ACK_LO; 415 syn_set_ack(LO);
371 416
372 /* 7e. The host waits for the guest to raise CLK indicating 417 /* 7e. The host waits for the guest to raise CLK indicating
373 that the stop bit is ready */ 418 that the stop bit is ready */
@@ -378,16 +423,16 @@ static int syn_read_data(int *data, int data_len)
378 { 423 {
379 logf(" framing error"); 424 logf(" framing error");
380 425
381 ACK_HI; 426 syn_set_ack(HI);
382 return READ_ERROR; 427 return READ_ERROR;
383 } 428 }
384 429
385 ACK_HI; 430 syn_set_ack(HI);
386 431
387 return len; 432 return len;
388} 433}
389 434
390int syn_read(int *data, int len) 435static int syn_read(char *data, int len)
391{ 436{
392 int i; 437 int i;
393 int ret = READ_ERROR; 438 int ret = READ_ERROR;
@@ -413,16 +458,16 @@ int syn_read(int *data, int len)
413 return ret; 458 return ret;
414} 459}
415 460
416int syn_reset(void) 461static int syn_reset(void)
417{ 462{
418 int val, id; 463 int val, id;
419 int data[2]; 464 char data[2];
420 465
421 logf("syn_reset..."); 466 logf("syn_reset...");
422 467
423 /* reset module 0 */ 468 /* reset module 0 */
424 val = (0 << 4) | (1 << 3) | 0; 469 data[0] = (0 << 4) | (1 << 3) | 0;
425 syn_send(&val, 1); 470 syn_send(data, 1);
426 471
427 val = syn_read(data, 2); 472 val = syn_read(data, 2);
428 if (val == 1) 473 if (val == 1)
@@ -440,15 +485,16 @@ int syn_reset(void)
440 return 0; 485 return 0;
441} 486}
442 487
443int syn_init(void) 488int touchpad_init(void)
444{ 489{
445 syn_flush(); 490 syn_flush();
446 syn_status = syn_reset(); 491 syn_status = syn_reset();
447 492
448 if (syn_status) 493 if (syn_status)
449 { 494 {
450 INT_DISABLE; 495 /* reset interrupts */
451 INT_ENABLE; 496 syn_enable_int(false);
497 syn_enable_int(true);
452 498
453 CPU_INT_EN |= HI_MASK; 499 CPU_INT_EN |= HI_MASK;
454 CPU_HI_INT_EN |= GPIO0_MASK; 500 CPU_HI_INT_EN |= GPIO0_MASK;
@@ -457,21 +503,86 @@ int syn_init(void)
457 return syn_status; 503 return syn_status;
458} 504}
459 505
460int syn_get_status(void) 506int touchpad_read_device(char *data, int len)
461{ 507{
462 return syn_status; 508 char tmp[4];
463} 509 int id;
510 int val = 0;
464 511
465void syn_int_enable(bool enable) 512 if (syn_status)
466{
467 if (enable)
468 { 513 {
469 INT_ENABLE; 514 /* disable interrupt while we read the touchpad */
515 syn_enable_int(false);
516
517 val = syn_read(data, len);
518 if (val > 0)
519 {
520 val = data[0] & 0xff; /* packet header */
521 id = (data[1] >> 4) & 0xf; /* packet id */
522
523 logf("syn_read:");
524 logf(" data[0] = 0x%08x", data[0]);
525 logf(" data[1] = 0x%08x", data[1]);
526 logf(" data[2] = 0x%08x", data[2]);
527 logf(" data[3] = 0x%08x", data[3]);
528
529 if ((val == MEP_BUTTON_HEADER) && (id == MEP_BUTTON_ID))
530 {
531 /* an absolute packet should follow which we ignore */
532 syn_read(tmp, 4);
533 }
534 else if (val == MEP_ABSOLUTE_HEADER)
535 {
536 logf(" pos %d", val);
537 logf(" z %d", data[3]);
538 logf(" finger %d", data[1] & 0x1);
539 logf(" gesture %d", data[1] & 0x2);
540 logf(" RelPosVld %d", data[1] & 0x4);
541
542 if (!(data[1] & 0x1))
543 {
544 /* finger is NOT on touch strip */
545 val = 0;
546 }
547 }
548 else
549 {
550 val = 0;
551 }
552 }
553
554 /* re-enable interrupts */
555 syn_enable_int(true);
470 } 556 }
471 else 557
558 return val;
559}
560
561int touchpad_set_buttonlights(int led_mask, char brightness)
562{
563 char data[6];
564 int val = 0;
565
566 if (syn_status)
472 { 567 {
473 INT_DISABLE; 568 syn_enable_int(false);
569
570 /* turn on all touchpad leds */
571 data[0] = 0x05;
572 data[1] = 0x31;
573 data[2] = (brightness & 0xf) << 4;
574 data[3] = 0x00;
575 data[4] = (led_mask >> 8) & 0xff;
576 data[5] = led_mask & 0xff;
577 syn_send(data, 6);
578
579 /* device responds with a single-byte ACK packet */
580 val = syn_read(data, 2);
581
582 syn_enable_int(true);
474 } 583 }
584
585 return val;
475} 586}
476 587
477#ifdef ROCKBOX_HAS_LOGF 588#ifdef ROCKBOX_HAS_LOGF
@@ -493,7 +604,7 @@ void syn_info(void)
493 for (i = 0; i < 8; i++) 604 for (i = 0; i < 8; i++)
494 logf(" data[%d] = 0x%02x", i, data[i]); 605 logf(" data[%d] = 0x%02x", i, data[i]);
495 } 606 }
496 607
497 /* module product info */ 608 /* module product info */
498 logf("module product info:"); 609 logf("module product info:");
499 data[0] = MEP_READ; 610 data[0] = MEP_READ;