world leader in high performance signal processing
Trace: » bf54x-keys

GENERAL DESCRIPTION

keypad_lr.jpg

Interface Overview

The keypad is a 16 pin Interface module that is used to detect the key pressed in an 8×8 (maximum) keypad matrix. The size of the input keypad matrix is software programmable. The interface is capable of filtering the bounce on the input pins with a programmable width of the filtered bounce.

The keypad module supports two modes of operation, Press-Release-Press mode and Press-Hold mode. The Press-Release-Press mode identifies a press-release-press sequence of a key as two consecutive presses of the same key. The Press-Hold mode checks the input key's state in periodic intervals to determine the number of times the same key is meant to be pressed.

Features

Key features of the keypad are as follows:

  • Programmable input keypad matrix size
  • Programmable debounce filter width
  • Press-Release-Press mode supported
  • Interrupt on any key pressed
  • Multiple key pressed detection and limited multiple key resolution Capability.

The driver only reports single keys pressed – multiple keys pressed are not reported to the input device layer

Keypad Operation

A keypad interface consists of a matrix with two sets of wires, one set that runs horizontally (rows), and another that runs vertically (columns) with a push button switch at each intersection. The row and column wires do not touch, but run over each other. When the push button is depressed, a contact is established at the intersection of a given row and column serving as a switch. The number of switches for a given matrix depends on the number of rows and columns. For example, a 4×4 matrix can support up to 16 switches. A block diagram of the keypad interface is shown in Figure below.

As shown in the figure, the column wires are connected to the column outputs of the keypad interface while the row wires are connected to the row inputs. Each row wire of the keypad has a pull-up resistor that pulls the row wires high. When no key is depressed, there is no contact between any of the column drivers to the row inputs. As a result, all row inputs are read as 1. When a push button is depressed, a contact is established between each corresponding row and column wire. Row inputs will sense the value driven by the column drivers. To determine which key has been pressed, the column drivers drive zero. On a key press, the zero will be vis ible on the row inputs. The interface being aware of which column was driven with what value along with reading the row inputs, it could determine which key has been pressed. The rest of the pages define and explain the infrastructure to determine the keys pressed.

See also: gpio-keys

Adding Kernel Support

  --- Input Device Support
  <*> Generic input layer (needed for keyboard, mouse, ...)
  < >   Support for memoryless force-feedback devices
  ---   Userland interfaces
  < >   Mouse interface
  < >   Joystick interface
  < >   Touchscreen interface
  <*>   Event interface
  < >   Event debugging
  ---   Input Device Drivers
  [*]   Keyboards  --->
  [ ]   Mouse  --->
  [ ]   Joysticks  --->
  [ ]   Touchscreens  --->
  [ ]   Miscellaneous devices  --->
      Hardware I/O ports  --->
  --- Keyboards
  < >   AT keyboard
  < >   Sun Type 4 and Type 5 keyboard
  < >   DECstation/VAXstation LK201/LK401 keyboard
  < >   XT keyboard
  < >   Newton keyboard
  < >   Stowaway keyboard
  < >   GPIO Buttons
  <M>   Blackfin BF54x keypad support

Testing

Enable Input event device test in user config

 --- Blackfin test programs
                    [ ] RTC test program
                    [ ] DPMC test program
                    [ ] PPIFCD test program
                    [ ] AUDIO test program
                    [ ] VIDEO test program
                    [ ] PFLAGS test program
                    [ ] PFBUTTONS test program
                    [ ] TWI test program
                    [ ] SPI test program
                    [ ] PPI test program
                    [ ] TWI LCD test program
                    [ ] TWI KEYPAD test program
                    [ ] RTS/CTS test program
                    [ ] Sqlite test program
                    [ ] Pthread lib test
                    [ ] Kernel Panic (test Watchdog)
                    [ ] netperf test tool
                    [ ] SYSVIPC testcase
                    [ ] Still to write
                    [*] Input event device test
                    [ ] AD9960 device test
                    [ ] AD5304 device test
                    [ ] file operation test
                    [ ] common sport test
                    [ ] UPNP samples
                    [ ] DCPLB Replacement Test
                    [ ] IRQ Schedule latency test
                    [ ] Malloc performance test
                    [ ] sram_alloc/sram_free test
                    [ ] erestart test
                    [ ] camera test
                    [ ] NCurses Test apps
                    [ ] libipod examples 

Load the driver module

root:~> modprobe bf54x-keys
input: bf54x-keys as /class/input/input0
bf54x-keys: Blackfin BF54x Keypad registered IRQ 76

Load the Event Interface

root:~> modprobe evdev

Start the Input event device test program

root:~> event_test /dev/input/event0
Input driver version is 1.0.0
Input device ID: bus 0x19 vendor 0x1 product 0x1 version 0x100
Input device name: "bf54x-keys"
Supported events:
  Event type 0 (Reset)
    Event code 0 (Reset)
    Event code 1 (Key)
  Event type 1 (Key)
    Event code 2 (1)
    Event code 3 (2)
    Event code 4 (3)
    Event code 5 (4)
    Event code 6 (5)
    Event code 7 (6)
    Event code 8 (7)
    Event code 9 (8)
    Event code 10 (9)
    Event code 11 (0)
    Event code 14 (Backspace)
    Event code 15 (Tab)
    Event code 28 (Enter)
    Event code 103 (Up)
    Event code 108 (Down)
    Event code 138 (Help)
Testing ... (interrupt to exit)
Event: time 1184925251.508479, type 1 (Key), code 2 (1), value 1
Event: time 1184925251.508495, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925251.663602, type 1 (Key), code 2 (1), value 0
Event: time 1184925251.663619, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925252.209280, type 1 (Key), code 3 (2), value 1
Event: time 1184925252.209294, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925252.363602, type 1 (Key), code 3 (2), value 0
Event: time 1184925252.363615, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925252.722639, type 1 (Key), code 4 (3), value 1
Event: time 1184925252.722658, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925252.823603, type 1 (Key), code 4 (3), value 0
Event: time 1184925252.823619, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925253.246274, type 1 (Key), code 103 (Up), value 1
Event: time 1184925253.246293, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925253.399603, type 1 (Key), code 103 (Up), value 0
Event: time 1184925253.399614, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925253.778737, type 1 (Key), code 5 (4), value 1
Event: time 1184925253.778756, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925253.931602, type 1 (Key), code 5 (4), value 0
Event: time 1184925253.931619, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925254.186787, type 1 (Key), code 6 (5), value 1
Event: time 1184925254.186801, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925254.339603, type 1 (Key), code 6 (5), value 0
Event: time 1184925254.339615, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925254.533652, type 1 (Key), code 7 (6), value 1
Event: time 1184925254.533672, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925254.687603, type 1 (Key), code 7 (6), value 0
Event: time 1184925254.687619, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925254.879104, type 1 (Key), code 108 (Down), value 1
Event: time 1184925254.879124, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925255.031603, type 1 (Key), code 108 (Down), value 0
Event: time 1184925255.031619, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925255.373704, type 1 (Key), code 8 (7), value 1
Event: time 1184925255.373718, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925255.475602, type 1 (Key), code 8 (7), value 0
Event: time 1184925255.475619, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925255.764704, type 1 (Key), code 9 (8), value 1
Event: time 1184925255.764723, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925255.919603, type 1 (Key), code 9 (8), value 0
Event: time 1184925255.919619, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925256.099658, type 1 (Key), code 10 (9), value 1
Event: time 1184925256.099671, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925256.255603, type 1 (Key), code 10 (9), value 0
Event: time 1184925256.255619, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925256.419187, type 1 (Key), code 15 (Tab), value 1
Event: time 1184925256.419201, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925256.571603, type 1 (Key), code 15 (Tab), value 0
Event: time 1184925256.571619, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925256.868157, type 1 (Key), code 14 (Backspace), value 1
Event: time 1184925256.868176, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925257.023602, type 1 (Key), code 14 (Backspace), value 0
Event: time 1184925257.023619, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925257.213708, type 1 (Key), code 11 (0), value 1
Event: time 1184925257.213727, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925257.367602, type 1 (Key), code 11 (0), value 0
Event: time 1184925257.367615, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925257.553531, type 1 (Key), code 138 (Help), value 1
Event: time 1184925257.553550, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925257.707603, type 1 (Key), code 138 (Help), value 0
Event: time 1184925257.707619, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925257.892268, type 1 (Key), code 28 (Enter), value 1
Event: time 1184925257.892288, type 0 (Reset), code 0 (Reset), value 0
Event: time 1184925258.047605, type 1 (Key), code 28 (Enter), value 0
Event: time 1184925258.047617, type 0 (Reset), code 0 (Reset), value 0
root:~>

Customizing the Keypad Driver

static struct bfin_kpad_platform_data bf54x_kpad_data = {
	.rows			= 4,
	.cols			= 4,
	.keymap 		= bf548_keymap,
	.keymapsize 		= ARRAY_SIZE(bf548_keymap),
	.debounce_time		= 5000,	/* ns (5ms) */
	.coldrive_time		= 1000, /* ns (1ms) */
	.keyup_test_interval	= 50, /* ms (50ms) */
};
  • rows Number of rows
  • cols Number of columns
  • keymap Pointer to the keymap
  • keymapsize Array size of the keymap table (usually # = rows x cols)
  • debounce_time Debounce time in nano seconds
  • coldrive_time Colum drive time in nano seconds (keypad scan speed)
  • keyup_test_interval Time between two successive tests for key release in mili seconds
static int bf548_keymap[] = {
	KEYVAL(0, 0, KEY_ENTER),
	KEYVAL(0, 1, KEY_HELP),
	KEYVAL(0, 2, KEY_0),
	KEYVAL(0, 3, KEY_BACKSPACE),
	KEYVAL(1, 0, KEY_TAB),
	KEYVAL(1, 1, KEY_9),
	KEYVAL(1, 2, KEY_8),
	KEYVAL(1, 3, KEY_7),
	KEYVAL(2, 0, KEY_DOWN),
	KEYVAL(2, 1, KEY_6),
	KEYVAL(2, 2, KEY_5),
	KEYVAL(2, 3, KEY_4),
	KEYVAL(3, 0, KEY_UP),
	KEYVAL(3, 1, KEY_3),
	KEYVAL(3, 2, KEY_2),
	KEYVAL(3, 3, KEY_1),
};

The keymap is fully customizable:

KEYVAL(col, row, code)

  • col specifies the Colum (rows and columns start at 0)
  • row specifies the Row
  • code is event code, for example KEY_A or KEY_BACKSPACE, a complete list is in include/linux/input.h.

For more information please read:

  1. linux-2.6.x/Documentation/input/input.txt
  2. linux-2.6.x/Documentation/input/input-programming.txt

Example Platfrom / Board file

  • arch/blackfin/mach-bf548/boards/ezkit.c
#include <asm/mach/bf54x_keys.h>
 
#if defined(CONFIG_KEYBOARD_BFIN) || defined(CONFIG_KEYBOARD_BFIN_MODULE)
static int bf548_keymap[] = {
	KEYVAL(0, 0, KEY_ENTER),
	KEYVAL(0, 1, KEY_HELP),
	KEYVAL(0, 2, KEY_0),
	KEYVAL(0, 3, KEY_BACKSPACE),
	KEYVAL(1, 0, KEY_TAB),
	KEYVAL(1, 1, KEY_9),
	KEYVAL(1, 2, KEY_8),
	KEYVAL(1, 3, KEY_7),
	KEYVAL(2, 0, KEY_DOWN),
	KEYVAL(2, 1, KEY_6),
	KEYVAL(2, 2, KEY_5),
	KEYVAL(2, 3, KEY_4),
	KEYVAL(3, 0, KEY_UP),
	KEYVAL(3, 1, KEY_3),
	KEYVAL(3, 2, KEY_2),
	KEYVAL(3, 3, KEY_1),
};
 
static struct bfin_kpad_platform_data bf54x_kpad_data = {
	.rows			= 4,
	.cols			= 4,
	.keymap 		= bf548_keymap,
	.keymapsize 		= ARRAY_SIZE(bf548_keymap),
	.debounce_time		= 5000,	/* ns (5ms) */
	.coldrive_time		= 1000, /* ns (1ms) */
	.keyup_test_interval	= 50, /* ms (50ms) */
};
 
static struct resource bf54x_kpad_resources[] = {
	{
		.start = IRQ_KEY,
		.end = IRQ_KEY,
		.flags = IORESOURCE_IRQ,
	},
};
 
static struct platform_device bf54x_kpad_device = {
	.name		= "bf54x-keys",
	.id		= -1,
	.num_resources 	= ARRAY_SIZE(bf54x_kpad_resources),
	.resource 	= bf54x_kpad_resources,
	.dev		= {
		.platform_data = &bf54x_kpad_data,
	},
};
#endif
 
 
static struct platform_device *your_platform_devices[] __initdata = {
 
/* ... SNIP ... */
 
#if defined(CONFIG_KEYBOARD_BFIN) || defined(CONFIG_KEYBOARD_BFIN_MODULE)
	&bf54x_kpad_device,
#endif
 
/* ... SNIP ... */
 
};