]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/input/mxc_keyb.c
applied patches from Freescale and Ka-Ro
[karo-tx-uboot.git] / drivers / input / mxc_keyb.c
1 /*
2  * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
3  */
4
5 /*
6  * The code contained herein is licensed under the GNU General Public
7  * License. You may obtain a copy of the GNU General Public License
8  * Version 2 or later at the following locations:
9  *
10  * http://www.opensource.org/licenses/gpl-license.html
11  * http://www.gnu.org/copyleft/gpl.html
12  */
13
14 /*!
15  * @file mxc_keyb.c
16  *
17  * @brief Driver for the Freescale Semiconductor MXC keypad port.
18  *
19  * The keypad driver is designed as a standard Input driver which interacts
20  * with low level keypad port hardware. Upon opening, the Keypad driver
21  * initializes the keypad port. When the keypad interrupt happens the driver
22  * calles keypad polling timer and scans the keypad matrix for key
23  * press/release. If all key press/release happened it comes out of timer and
24  * waits for key press interrupt. The scancode for key press and release events
25  * are passed to Input subsytem.
26  *
27  * @ingroup keypad
28  */
29
30 #include <asm/io.h>
31 #include <common.h>
32 #include <asm/errno.h>
33 #include <asm/arch/keypad.h>
34 #include <linux/types.h>
35 #include <malloc.h>
36
37 /*
38  *  * Module header file
39  *   */
40 #include <mxc_keyb.h>
41
42 /*!
43  * Comment KPP_DEBUG to disable debug messages
44  */
45
46 #undef  KPP_DEBUG
47
48 #ifdef  KPP_DEBUG
49 #define KPP_PRINTF(fmt, args...)        printf(fmt , ##args)
50
51 static void mxc_kpp_dump_regs()
52 {
53         unsigned short t1, t2, t3;
54
55         t1 = __raw_readw(KPCR);
56         t2 = __raw_readw(KPSR);
57         t3 = __raw_readw(KDDR);
58         /*
59         KPP_PRINTF("KPCR=0x%04x, KPSR=0x%04x, KDDR=0x%04x\n",
60                 t1, t2, t3);
61                 */
62 }
63 #else
64 #define KPP_PRINTF(fmt, args...)
65 #endif
66
67 static u16 mxc_key_mapping[] = CONFIG_MXC_KEYMAPPING;
68
69 /*!
70  * This structure holds the keypad private data structure.
71  */
72 static struct keypad_priv kpp_dev;
73
74 /*! Indicates if the key pad device is enabled. */
75
76 /*! This static variable indicates whether a key event is pressed/released. */
77 static unsigned short KPress;
78
79 /*! cur_rcmap and prev_rcmap array is used to detect key press and release. */
80 static unsigned short *cur_rcmap;       /* max 64 bits (8x8 matrix) */
81 static unsigned short *prev_rcmap;
82
83 /*!
84  * Debounce polling period(10ms) in system ticks.
85  */
86 static unsigned short KScanRate = (10 * CONFIG_SYS_HZ) / 1000;
87
88 /*!
89  * These arrays are used to store press and release scancodes.
90  */
91 static short **press_scancode;
92 static short **release_scancode;
93
94 static const unsigned short *mxckpd_keycodes;
95 static unsigned short mxckpd_keycodes_size;
96
97 /*!
98  * These functions are used to configure and the GPIO pins for keypad to
99  * activate and deactivate it.
100  */
101 extern void setup_mxc_kpd(void);
102
103 /*!
104  * This function is called to scan the keypad matrix to find out the key press
105  * and key release events. Make scancode and break scancode are generated for
106  * key press and key release events.
107  *
108  * The following scanning sequence are done for
109  * keypad row and column scanning,
110  * -# Write 1's to KPDR[15:8], setting column data to 1's
111  * -# Configure columns as totem pole outputs(for quick discharging of keypad
112  * capacitance)
113  * -# Configure columns as open-drain
114  * -# Write a single column to 0, others to 1.
115  * -# Sample row inputs and save data. Multiple key presses can be detected on
116  * a single column.
117  * -# Repeat steps the above steps for remaining columns.
118  * -# Return all columns to 0 in preparation for standby mode.
119  * -# Clear KPKD and KPKR status bit(s) by writing to a 1,
120  *    Set the KPKR synchronizer chain by writing "1" to KRSS register,
121  *    Clear the KPKD synchronizer chain by writing "1" to KDSC register
122  *
123  * @result    Number of key pressed/released.
124  */
125 static int mxc_kpp_scan_matrix(void)
126 {
127         unsigned short reg_val;
128         int col, row;
129         short scancode = 0;
130         int keycnt = 0;         /* How many keys are still pressed */
131
132         /*
133          * wmb() linux kernel function which guarantees orderings in write
134          * operations
135          */
136         /* wmb(); */
137
138         /* save cur keypad matrix to prev */
139         memcpy(prev_rcmap, cur_rcmap, kpp_dev.kpp_rows * sizeof(prev_rcmap[0]));
140         memset(cur_rcmap, 0, kpp_dev.kpp_rows * sizeof(cur_rcmap[0]));
141
142         for (col = 0; col < kpp_dev.kpp_cols; col++) {  /* Col */
143                 /* 2. Write 1.s to KPDR[15:8] setting column data to 1.s */
144                 reg_val = __raw_readw(KPDR);
145                 reg_val |= 0xff00;
146                 __raw_writew(reg_val, KPDR);
147
148                 /*
149                  * 3. Configure columns as totem pole outputs(for quick
150                  * discharging of keypad capacitance)
151                  */
152                 reg_val = __raw_readw(KPCR);
153                 reg_val &= 0x00ff;
154                 __raw_writew(reg_val, KPCR);
155
156                 udelay(2);
157
158 #ifdef KPP_DEBUG
159                 mxc_kpp_dump_regs();
160 #endif
161
162                 /*
163                  * 4. Configure columns as open-drain
164                  */
165                 reg_val = __raw_readw(KPCR);
166                 reg_val |= ((1 << kpp_dev.kpp_cols) - 1) << 8;
167                 __raw_writew(reg_val, KPCR);
168
169                 /*
170                  * 5. Write a single column to 0, others to 1.
171                  * 6. Sample row inputs and save data. Multiple key presses
172                  * can be detected on a single column.
173                  * 7. Repeat steps 2 - 6 for remaining columns.
174                  */
175
176                 /* Col bit starts at 8th bit in KPDR */
177                 reg_val = __raw_readw(KPDR);
178                 reg_val &= ~(1 << (8 + col));
179                 __raw_writew(reg_val, KPDR);
180
181                 /* Delay added to avoid propagating the 0 from column to row
182                  * when scanning. */
183
184                 udelay(5);
185
186 #ifdef KPP_DEBUG
187                 mxc_kpp_dump_regs();
188 #endif
189
190                 /* Read row input */
191                 reg_val = __raw_readw(KPDR);
192                 for (row = 0; row < kpp_dev.kpp_rows; row++) {  /* sample row */
193                         if (TEST_BIT(reg_val, row) == 0) {
194                                 cur_rcmap[row] = BITSET(cur_rcmap[row], col);
195                                 keycnt++;
196                         }
197                 }
198         }
199
200         /*
201          * 8. Return all columns to 0 in preparation for standby mode.
202          * 9. Clear KPKD and KPKR status bit(s) by writing to a .1.,
203          * set the KPKR synchronizer chain by writing "1" to KRSS register,
204          * clear the KPKD synchronizer chain by writing "1" to KDSC register
205          */
206         reg_val = 0x00;
207         __raw_writew(reg_val, KPDR);
208         reg_val = __raw_readw(KPDR);
209         reg_val = __raw_readw(KPSR);
210         reg_val |= KBD_STAT_KPKD | KBD_STAT_KPKR | KBD_STAT_KRSS |
211             KBD_STAT_KDSC;
212         __raw_writew(reg_val, KPSR);
213
214 #ifdef KPP_DEBUG
215         mxc_kpp_dump_regs();
216 #endif
217
218         /* Check key press status change */
219
220         /*
221          * prev_rcmap array will contain the previous status of the keypad
222          * matrix.  cur_rcmap array will contains the present status of the
223          * keypad matrix. If a bit is set in the array, that (row, col) bit is
224          * pressed, else it is not pressed.
225          *
226          * XORing these two variables will give us the change in bit for
227          * particular row and column.  If a bit is set in XOR output, then that
228          * (row, col) has a change of status from the previous state.  From
229          * the diff variable the key press and key release of row and column
230          * are found out.
231          *
232          * If the key press is determined then scancode for key pressed
233          * can be generated using the following statement:
234          *    scancode = ((row * 8) + col);
235          *
236          * If the key release is determined then scancode for key release
237          * can be generated using the following statement:
238          *    scancode = ((row * 8) + col) + MXC_KEYRELEASE;
239          */
240         for (row = 0; row < kpp_dev.kpp_rows; row++) {
241                 unsigned char diff;
242
243                 /*
244                  * Calculate the change in the keypad row status
245                  */
246                 diff = prev_rcmap[row] ^ cur_rcmap[row];
247
248                 for (col = 0; col < kpp_dev.kpp_cols; col++) {
249                         if ((diff >> col) & 0x1) {
250                                 /* There is a status change on col */
251                                 if ((prev_rcmap[row] & BITSET(0, col)) == 0) {
252                                         /*
253                                          * Previous state is 0, so now
254                                          * a key is pressed
255                                          */
256                                         scancode =
257                                             ((row * kpp_dev.kpp_cols) +
258                                              col);
259                                         KPress = 1;
260                                         kpp_dev.iKeyState = KStateUp;
261
262                                         KPP_PRINTF("Press   (%d, %d) scan=%d "
263                                                  "Kpress=%d\n",
264                                                  row, col, scancode, KPress);
265                                         press_scancode[row][col] =
266                                             (short)scancode;
267                                 } else {
268                                         /*
269                                          * Previous state is not 0, so
270                                          * now a key is released
271                                          */
272                                         scancode =
273                                             (row * kpp_dev.kpp_cols) +
274                                             col + MXC_KEYRELEASE;
275                                         KPress = 0;
276                                         kpp_dev.iKeyState = KStateDown;
277
278                                         KPP_PRINTF
279                                             ("Release (%d, %d) scan=%d Kpress=%d\n",
280                                              row, col, scancode, KPress);
281                                         release_scancode[row][col] =
282                                             (short)scancode;
283                                         keycnt++;
284                                 }
285                         }
286                 }
287         }
288
289         return keycnt;
290 }
291
292 static int mxc_kpp_reset(void)
293 {
294         unsigned short reg_val;
295         int i;
296
297         /*
298         * Stop scanning and wait for interrupt.
299         * Enable press interrupt and disable release interrupt.
300         */
301         __raw_writew(0x00FF, KPDR);
302         reg_val = __raw_readw(KPSR);
303         reg_val |= (KBD_STAT_KPKR | KBD_STAT_KPKD);
304         reg_val |= KBD_STAT_KRSS | KBD_STAT_KDSC;
305         __raw_writew(reg_val, KPSR);
306         reg_val |= KBD_STAT_KDIE;
307         reg_val &= ~KBD_STAT_KRIE;
308         __raw_writew(reg_val, KPSR);
309
310 #ifdef KPP_DEBUG
311         mxc_kpp_dump_regs();
312 #endif
313
314         /*
315         * No more keys pressed... make sure unwanted key codes are
316         * not given upstairs
317         */
318         for (i = 0; i < kpp_dev.kpp_rows; i++) {
319                 memset(press_scancode[i], -1,
320                         sizeof(press_scancode[0][0]) * kpp_dev.kpp_cols);
321                 memset(release_scancode[i], -1,
322                         sizeof(release_scancode[0][0]) *
323                         kpp_dev.kpp_cols);
324         }
325
326         return 0;
327 }
328
329 int mxc_kpp_getc(struct kpp_key_info *key_info)
330 {
331         int col, row;
332         static int key_cnt;
333         unsigned short reg_val;
334         short scancode = 0;
335
336         reg_val = __raw_readw(KPSR);
337
338         if (!key_cnt) {
339                 if (reg_val & KBD_STAT_KPKD) {
340                         /*
341                         * Disable key press(KDIE status bit) interrupt
342                         */
343                         reg_val &= ~KBD_STAT_KDIE;
344                         __raw_writew(reg_val, KPSR);
345
346 #ifdef KPP_DEBUG
347                         mxc_kpp_dump_regs();
348 #endif
349
350                         key_cnt = mxc_kpp_scan_matrix();
351                 } else {
352                         return 0;
353                 }
354         }
355
356         /*
357         * This switch case statement is the
358         * implementation of state machine of debounc
359         * logic for key press/release.
360         * The explaination of state machine is as
361         * follows:
362         *
363         * KStateUp State:
364         * This is in intial state of the state machine
365         * this state it checks for any key presses.
366         * The key press can be checked using the
367         * variable KPress. If KPress is set, then key
368         * press is identified and switches the to
369         * KStateFirstDown state for key press to
370         * debounce.
371         *
372         * KStateFirstDown:
373         * After debounce delay(10ms), if the KPress is
374         * still set then pass scancode generated to
375         * input device and change the state to
376         * KStateDown, else key press debounce is not
377         * satisfied so change the state to KStateUp.
378         *
379         * KStateDown:
380         * In this state it checks for any key release.
381         * If KPress variable is cleared, then key
382         * release is indicated and so, switch the
383         * state to KStateFirstUp else to state
384         * KStateDown.
385         *
386         * KStateFirstUp:
387         * After debounce delay(10ms), if the KPress is
388         * still reset then pass the key release
389         * scancode to input device and change
390         * the state to KStateUp else key release is
391         * not satisfied so change the state to
392         * KStateDown.
393         */
394
395         for (row = 0; row < kpp_dev.kpp_rows; row++) {
396                 for (col = 0; col < kpp_dev.kpp_cols; col++) {
397                         if ((press_scancode[row][col] != -1)) {
398                                 /* Still Down, so add scancode */
399                                 scancode =
400                                     press_scancode[row][col];
401
402                                 key_info->val = mxckpd_keycodes[scancode];
403                                 key_info->evt = KDepress;
404
405                                 KPP_PRINTF("KStateFirstDown: scan=%d val=%d\n",
406                                         scancode, mxckpd_keycodes[scancode]);
407                                 kpp_dev.iKeyState = KStateDown;
408                                 press_scancode[row][col] = -1;
409
410                                 goto key_detect;
411                         }
412                 }
413         }
414
415         for (row = 0; row < kpp_dev.kpp_rows; row++) {
416                 for (col = 0; col < kpp_dev.kpp_cols; col++) {
417                         if ((release_scancode[row][col] != -1)) {
418                                 scancode =
419                                     release_scancode[row][col];
420                                 scancode =
421                                         scancode - MXC_KEYRELEASE;
422
423                                 key_info->val = mxckpd_keycodes[scancode];
424                                 key_info->evt = KRelease;
425
426                                 KPP_PRINTF("KStateFirstUp: scan=%d val=%d\n",
427                                         scancode, mxckpd_keycodes[scancode]);
428
429                                 kpp_dev.iKeyState = KStateUp;
430                                 release_scancode[row][col] = -1;
431
432                                 goto key_detect;
433                         }
434                 }
435         }
436
437         return 0;
438
439 key_detect:
440         /* udelay(KScanRate); */
441         key_cnt = mxc_kpp_scan_matrix();
442
443         if (0 == key_cnt)
444                 mxc_kpp_reset();
445         return 1;
446 }
447
448 /*!
449  * This function is called to free the allocated memory for local arrays
450  */
451 static void mxc_kpp_free_allocated(void)
452 {
453         int i;
454
455         if (press_scancode) {
456                 for (i = 0; i < kpp_dev.kpp_rows; i++) {
457                         if (press_scancode[i])
458                                 free(press_scancode[i]);
459                 }
460                 free(press_scancode);
461         }
462
463         if (release_scancode) {
464                 for (i = 0; i < kpp_dev.kpp_rows; i++) {
465                         if (release_scancode[i])
466                                 free(release_scancode[i]);
467                 }
468                 free(release_scancode);
469         }
470
471         if (cur_rcmap)
472                 free(cur_rcmap);
473
474         if (prev_rcmap)
475                 free(prev_rcmap);
476 }
477
478 /*!
479  * This function is called during the driver binding process.
480  *
481  * @param   pdev  the device structure used to store device specific
482  *                information that is used by the suspend, resume and remove
483  *                functions.
484  *
485  * @return  The function returns 0 on successful registration. Otherwise returns
486  *          specific error code.
487  */
488 int mxc_kpp_init(void)
489 {
490         int i;
491         int retval;
492         unsigned int reg_val;
493
494         kpp_dev.kpp_cols = CONFIG_MXC_KPD_COLMAX;
495         kpp_dev.kpp_rows = CONFIG_MXC_KPD_ROWMAX;
496
497         /* clock and IOMUX configuration for keypad */
498         setup_mxc_kpd();
499
500         /* Configure keypad */
501
502         /* Enable number of rows in keypad (KPCR[7:0])
503          * Configure keypad columns as open-drain (KPCR[15:8])
504          *
505          * Configure the rows/cols in KPP
506          * LSB nibble in KPP is for 8 rows
507          * MSB nibble in KPP is for 8 cols
508          */
509         reg_val = __raw_readw(KPCR);
510         reg_val |= (1  << kpp_dev.kpp_rows) - 1;        /* LSB */
511         reg_val |= ((1 << kpp_dev.kpp_cols) - 1) << 8;  /* MSB */
512         __raw_writew(reg_val, KPCR);
513
514         /* Write 0's to KPDR[15:8] */
515         reg_val = __raw_readw(KPDR);
516         reg_val &= 0x00ff;
517         __raw_writew(reg_val, KPDR);
518
519         /* Configure columns as output,
520          * rows as input (KDDR[15:0]) */
521         reg_val = __raw_readw(KDDR);
522         reg_val |= 0xff00;
523         reg_val &= 0xff00;
524         __raw_writew(reg_val, KDDR);
525
526         /* Clear the KPKD Status Flag
527          * and Synchronizer chain. */
528         reg_val = __raw_readw(KPSR);
529         reg_val &= ~(KBD_STAT_KPKR | KBD_STAT_KPKD);
530         reg_val |= KBD_STAT_KPKD;
531         reg_val |= KBD_STAT_KRSS | KBD_STAT_KDSC;
532         __raw_writew(reg_val, KPSR);
533         /* Set the KDIE control bit, and clear the KRIE
534          * control bit (avoid false release events). */
535         reg_val |= KBD_STAT_KDIE;
536         reg_val &= ~KBD_STAT_KRIE;
537         __raw_writew(reg_val, KPSR);
538
539 #ifdef KPP_DEBUG
540         mxc_kpp_dump_regs();
541 #endif
542
543         mxckpd_keycodes = mxc_key_mapping;
544         mxckpd_keycodes_size = kpp_dev.kpp_cols * kpp_dev.kpp_rows;
545
546         if ((mxckpd_keycodes == (void *)0)
547             || (mxckpd_keycodes_size == 0)) {
548                 retval = -ENODEV;
549                 goto err;
550         }
551
552         /* allocate required memory */
553         press_scancode   = (short **)malloc(kpp_dev.kpp_rows * sizeof(press_scancode[0]));
554         release_scancode = (short **)malloc(kpp_dev.kpp_rows * sizeof(release_scancode[0]));
555
556         if (!press_scancode || !release_scancode) {
557                 retval = -ENOMEM;
558                 goto err;
559         }
560
561         for (i = 0; i < kpp_dev.kpp_rows; i++) {
562                 press_scancode[i] = (short *)malloc(kpp_dev.kpp_cols
563                                             * sizeof(press_scancode[0][0]));
564                 release_scancode[i] =
565                     (short *)malloc(kpp_dev.kpp_cols * sizeof(release_scancode[0][0]));
566
567                 if (!press_scancode[i] || !release_scancode[i]) {
568                         retval = -ENOMEM;
569                         goto err;
570                 }
571         }
572
573         cur_rcmap =
574             (unsigned short *)malloc(kpp_dev.kpp_rows * sizeof(cur_rcmap[0]));
575         prev_rcmap =
576             (unsigned short *)malloc(kpp_dev.kpp_rows * sizeof(prev_rcmap[0]));
577
578         if (!cur_rcmap || !prev_rcmap) {
579                 retval = -ENOMEM;
580                 goto err;
581         }
582
583         for (i = 0; i < kpp_dev.kpp_rows; i++) {
584                 memset(press_scancode[i], -1,
585                        sizeof(press_scancode[0][0]) * kpp_dev.kpp_cols);
586                 memset(release_scancode[i], -1,
587                        sizeof(release_scancode[0][0]) * kpp_dev.kpp_cols);
588         }
589         memset(cur_rcmap, 0, kpp_dev.kpp_rows * sizeof(cur_rcmap[0]));
590         memset(prev_rcmap, 0, kpp_dev.kpp_rows * sizeof(prev_rcmap[0]));
591
592         return 0;
593
594 err:
595         mxc_kpp_free_allocated();
596         return retval;
597 }
598