2 * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
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:
10 * http://www.opensource.org/licenses/gpl-license.html
11 * http://www.gnu.org/copyleft/gpl.html
17 * @brief Driver for the Freescale Semiconductor MXC keypad port.
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.
32 #include <asm/errno.h>
33 #include <asm/arch/keypad.h>
34 #include <linux/types.h>
38 * * Module header file
43 * Comment KPP_DEBUG to disable debug messages
49 #define KPP_PRINTF(fmt, args...) printf(fmt , ##args)
51 static void mxc_kpp_dump_regs()
53 unsigned short t1, t2, t3;
55 t1 = __raw_readw(KPCR);
56 t2 = __raw_readw(KPSR);
57 t3 = __raw_readw(KDDR);
59 KPP_PRINTF("KPCR=0x%04x, KPSR=0x%04x, KDDR=0x%04x\n",
64 #define KPP_PRINTF(fmt, args...)
67 static u16 mxc_key_mapping[] = CONFIG_MXC_KEYMAPPING;
70 * This structure holds the keypad private data structure.
72 static struct keypad_priv kpp_dev;
74 /*! Indicates if the key pad device is enabled. */
76 /*! This static variable indicates whether a key event is pressed/released. */
77 static unsigned short KPress;
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;
84 * Debounce polling period(10ms) in system ticks.
86 static unsigned short KScanRate = (10 * CONFIG_SYS_HZ) / 1000;
89 * These arrays are used to store press and release scancodes.
91 static short **press_scancode;
92 static short **release_scancode;
94 static const unsigned short *mxckpd_keycodes;
95 static unsigned short mxckpd_keycodes_size;
98 * These functions are used to configure and the GPIO pins for keypad to
99 * activate and deactivate it.
101 extern void setup_mxc_kpd(void);
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.
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
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
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
123 * @result Number of key pressed/released.
125 static int mxc_kpp_scan_matrix(void)
127 unsigned short reg_val;
130 int keycnt = 0; /* How many keys are still pressed */
133 * wmb() linux kernel function which guarantees orderings in write
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]));
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);
146 __raw_writew(reg_val, KPDR);
149 * 3. Configure columns as totem pole outputs(for quick
150 * discharging of keypad capacitance)
152 reg_val = __raw_readw(KPCR);
154 __raw_writew(reg_val, KPCR);
163 * 4. Configure columns as open-drain
165 reg_val = __raw_readw(KPCR);
166 reg_val |= ((1 << kpp_dev.kpp_cols) - 1) << 8;
167 __raw_writew(reg_val, KPCR);
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.
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);
181 /* Delay added to avoid propagating the 0 from column to row
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);
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
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 |
212 __raw_writew(reg_val, KPSR);
218 /* Check key press status change */
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.
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
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);
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;
240 for (row = 0; row < kpp_dev.kpp_rows; row++) {
244 * Calculate the change in the keypad row status
246 diff = prev_rcmap[row] ^ cur_rcmap[row];
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) {
253 * Previous state is 0, so now
257 ((row * kpp_dev.kpp_cols) +
260 kpp_dev.iKeyState = KStateUp;
262 KPP_PRINTF("Press (%d, %d) scan=%d "
264 row, col, scancode, KPress);
265 press_scancode[row][col] =
269 * Previous state is not 0, so
270 * now a key is released
273 (row * kpp_dev.kpp_cols) +
274 col + MXC_KEYRELEASE;
276 kpp_dev.iKeyState = KStateDown;
279 ("Release (%d, %d) scan=%d Kpress=%d\n",
280 row, col, scancode, KPress);
281 release_scancode[row][col] =
292 static int mxc_kpp_reset(void)
294 unsigned short reg_val;
298 * Stop scanning and wait for interrupt.
299 * Enable press interrupt and disable release interrupt.
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);
315 * No more keys pressed... make sure unwanted key codes are
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]) *
329 int mxc_kpp_getc(struct kpp_key_info *key_info)
333 unsigned short reg_val;
336 reg_val = __raw_readw(KPSR);
339 if (reg_val & KBD_STAT_KPKD) {
341 * Disable key press(KDIE status bit) interrupt
343 reg_val &= ~KBD_STAT_KDIE;
344 __raw_writew(reg_val, KPSR);
350 key_cnt = mxc_kpp_scan_matrix();
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
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
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.
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
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
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 */
400 press_scancode[row][col];
402 key_info->val = mxckpd_keycodes[scancode];
403 key_info->evt = KDepress;
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;
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)) {
419 release_scancode[row][col];
421 scancode - MXC_KEYRELEASE;
423 key_info->val = mxckpd_keycodes[scancode];
424 key_info->evt = KRelease;
426 KPP_PRINTF("KStateFirstUp: scan=%d val=%d\n",
427 scancode, mxckpd_keycodes[scancode]);
429 kpp_dev.iKeyState = KStateUp;
430 release_scancode[row][col] = -1;
440 /* udelay(KScanRate); */
441 key_cnt = mxc_kpp_scan_matrix();
449 * This function is called to free the allocated memory for local arrays
451 static void mxc_kpp_free_allocated(void)
455 if (press_scancode) {
456 for (i = 0; i < kpp_dev.kpp_rows; i++) {
457 if (press_scancode[i])
458 free(press_scancode[i]);
460 free(press_scancode);
463 if (release_scancode) {
464 for (i = 0; i < kpp_dev.kpp_rows; i++) {
465 if (release_scancode[i])
466 free(release_scancode[i]);
468 free(release_scancode);
479 * This function is called during the driver binding process.
481 * @param pdev the device structure used to store device specific
482 * information that is used by the suspend, resume and remove
485 * @return The function returns 0 on successful registration. Otherwise returns
486 * specific error code.
488 int mxc_kpp_init(void)
492 unsigned int reg_val;
494 kpp_dev.kpp_cols = CONFIG_MXC_KPD_COLMAX;
495 kpp_dev.kpp_rows = CONFIG_MXC_KPD_ROWMAX;
497 /* clock and IOMUX configuration for keypad */
500 /* Configure keypad */
502 /* Enable number of rows in keypad (KPCR[7:0])
503 * Configure keypad columns as open-drain (KPCR[15:8])
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
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);
514 /* Write 0's to KPDR[15:8] */
515 reg_val = __raw_readw(KPDR);
517 __raw_writew(reg_val, KPDR);
519 /* Configure columns as output,
520 * rows as input (KDDR[15:0]) */
521 reg_val = __raw_readw(KDDR);
524 __raw_writew(reg_val, KDDR);
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);
543 mxckpd_keycodes = mxc_key_mapping;
544 mxckpd_keycodes_size = kpp_dev.kpp_cols * kpp_dev.kpp_rows;
546 if ((mxckpd_keycodes == (void *)0)
547 || (mxckpd_keycodes_size == 0)) {
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]));
556 if (!press_scancode || !release_scancode) {
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]));
567 if (!press_scancode[i] || !release_scancode[i]) {
574 (unsigned short *)malloc(kpp_dev.kpp_rows * sizeof(cur_rcmap[0]));
576 (unsigned short *)malloc(kpp_dev.kpp_rows * sizeof(prev_rcmap[0]));
578 if (!cur_rcmap || !prev_rcmap) {
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);
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]));
595 mxc_kpp_free_allocated();