rendered paste body/* linux/arch/arm/mach-msm/board-kaiser-keypad.c
*
* Copyright (C) 2007 Google, Inc.
* Author: Marcin Baliniak <marcin@baliniak.pl>
* based on Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <asm/gpio.h>
#include <asm/hardware.h>
#include <asm/arch/board.h>
#include <asm/arch/msm_iomap.h>
#include <asm/io.h>
#include <asm/delay.h>
#include <linux/gpio_event.h>
static unsigned int kaiser_row_gpios[] = {23, 30, 31, 32, 33, 34, 35, 78};
static unsigned int kaiser_col_gpios[] = { 36, 37, 38, 39, 40, 41, 42 };
#define KEYMAP_INDEX(row, col) ((row)*ARRAY_SIZE(kaiser_col_gpios) + (col))
static unsigned short kaiser_keymap[ARRAY_SIZE(kaiser_col_gpios) * ARRAY_SIZE(kaiser_row_gpios)] = {
[KEYMAP_INDEX(0, 0)] = KEY_MENU,// (keyboard menu)
[KEYMAP_INDEX(0, 1)] = KEY_OK,// (keyboard ok)
[KEYMAP_INDEX(0, 2)] = KEY_TAB,//
[KEYMAP_INDEX(0, 3)] = KEY_V,//
[KEYMAP_INDEX(0, 4)] = KEY_SPACE,//
[KEYMAP_INDEX(0, 5)] = KEY_DOT,//
[KEYMAP_INDEX(0, 6)] = KEY_ENTER, //
[KEYMAP_INDEX(1, 0)] = KEY_1,
[KEYMAP_INDEX(1, 1)] = KEY_2,
[KEYMAP_INDEX(1, 2)] = KEY_3,
[KEYMAP_INDEX(1, 3)] = KEY_MENU,//
[KEYMAP_INDEX(1, 4)] = KEY_1, // hangup
[KEYMAP_INDEX(1, 5)] = KEY_OK,//
[KEYMAP_INDEX(1, 6)] = KEY_2,// call
[KEYMAP_INDEX(2, 0)] = KEY_LEFTALT,// Fn
[KEYMAP_INDEX(2, 1)] = KEY_X,//
[KEYMAP_INDEX(2, 2)] = KEY_C,//
[KEYMAP_INDEX(2, 3)] = KEY_G,//
[KEYMAP_INDEX(2, 4)] = KEY_B,//
[KEYMAP_INDEX(2, 5)] = KEY_M,//
[KEYMAP_INDEX(2, 6)] = KEY_BACKSPACE,//
[KEYMAP_INDEX(3, 0)] = KEY_RIGHTSHIFT,//
[KEYMAP_INDEX(3, 1)] = KEY_Z,//
[KEYMAP_INDEX(3, 2)] = KEY_F,//
[KEYMAP_INDEX(3, 3)] = KEY_Y,//
[KEYMAP_INDEX(3, 4)] = KEY_H,//
[KEYMAP_INDEX(3, 5)] = KEY_N,//
[KEYMAP_INDEX(3, 6)] = KEY_L,//
[KEYMAP_INDEX(4, 0)] = KEY_A,//
[KEYMAP_INDEX(4, 1)] = KEY_S,//
[KEYMAP_INDEX(4, 2)] = KEY_D,//
[KEYMAP_INDEX(4, 3)] = KEY_T,//
[KEYMAP_INDEX(4, 4)] = KEY_J,//
[KEYMAP_INDEX(4, 5)] = KEY_K,//
[KEYMAP_INDEX(4, 6)] = KEY_P,//
[KEYMAP_INDEX(5, 0)] = KEY_Q,//
[KEYMAP_INDEX(5, 1)] = KEY_W,//
[KEYMAP_INDEX(5, 2)] = KEY_E,//
[KEYMAP_INDEX(5, 3)] = KEY_R,//
[KEYMAP_INDEX(5, 4)] = KEY_U,//
[KEYMAP_INDEX(5, 5)] = KEY_I,//
[KEYMAP_INDEX(5, 6)] = KEY_O, //
//dummy mapping for test only
[KEYMAP_INDEX(6, 0)] = KEY_4,//
[KEYMAP_INDEX(6, 1)] = KEY_5,//
[KEYMAP_INDEX(6, 2)] = KEY_6,//
[KEYMAP_INDEX(6, 3)] = KEY_7,//
[KEYMAP_INDEX(6, 4)] = KEY_8,//
[KEYMAP_INDEX(6, 5)] = KEY_9,//
[KEYMAP_INDEX(6, 6)] = KEY_0,//
[KEYMAP_INDEX(7, 0)] = KEY_4,//
[KEYMAP_INDEX(7, 1)] = KEY_5,//
[KEYMAP_INDEX(7, 2)] = KEY_6,//
[KEYMAP_INDEX(7, 3)] = KEY_7,//
[KEYMAP_INDEX(7, 4)] = KEY_8,//
[KEYMAP_INDEX(7, 5)] = KEY_9,//
[KEYMAP_INDEX(7, 6)] = KEY_0,//
};
#define KEY_SHIFT 0x10000
static unsigned int kaiser_keymap_plus_fn[ARRAY_SIZE(kaiser_col_gpios) * ARRAY_SIZE(kaiser_row_gpios)] = {
[KEYMAP_INDEX(0, 0)] = KEY_SEMICOLON,// ;
[KEYMAP_INDEX(0, 1)] = KEY_WLAN,//
[KEYMAP_INDEX(0, 2)] = KEY_TAB,//
[KEYMAP_INDEX(0, 3)] = KEY_SHIFT | KEY_8,// *
[KEYMAP_INDEX(0, 4)] = KEY_SPACE,
[KEYMAP_INDEX(0, 5)] = KEY_0,//
[KEYMAP_INDEX(0, 6)] = KEY_ENTER,
[KEYMAP_INDEX(1, 0)] = KEY_1,
[KEYMAP_INDEX(1, 1)] = KEY_2,
[KEYMAP_INDEX(1, 2)] = KEY_3,
[KEYMAP_INDEX(1, 3)] = KEY_MENU,//
[KEYMAP_INDEX(1, 4)] = KEY_E, // hangup
[KEYMAP_INDEX(1, 5)] = KEY_OK,//
[KEYMAP_INDEX(1, 6)] = KEY_C,// call
[KEYMAP_INDEX(2, 0)] = KEY_LEFTALT,// Fn
[KEYMAP_INDEX(2, 1)] = KEY_SHIFT | KEY_7,// *
[KEYMAP_INDEX(2, 2)] = KEY_SHIFT | KEY_SEMICOLON,// :
[KEYMAP_INDEX(2, 3)] = KEY_SHIFT | KEY_EQUAL,// =
[KEYMAP_INDEX(2, 4)] = KEY_7,//
[KEYMAP_INDEX(2, 5)] = KEY_9,//
[KEYMAP_INDEX(2, 6)] = KEY_DELETE,//
[KEYMAP_INDEX(3, 0)] = KEY_CAPSLOCK,//
[KEYMAP_INDEX(3, 1)] = KEY_APOSTROPHE,// '
[KEYMAP_INDEX(3, 2)] = KEY_MINUS,// -
[KEYMAP_INDEX(3, 3)] = KEY_1,//
[KEYMAP_INDEX(3, 4)] = KEY_4,//
[KEYMAP_INDEX(3, 5)] = KEY_8,//
[KEYMAP_INDEX(3, 6)] = KEY_EQUAL,//
[KEYMAP_INDEX(4, 0)] = KEY_SHIFT | KEY_MINUS,// _
[KEYMAP_INDEX(4, 1)] = KEY_SHIFT | KEY_APOSTROPHE,// "
[KEYMAP_INDEX(4, 2)] = KEY_SHIFT | KEY_5,// %
[KEYMAP_INDEX(4, 3)] = KEY_SHIFT | KEY_3,// #
[KEYMAP_INDEX(4, 4)] = KEY_5,//
[KEYMAP_INDEX(4, 5)] = KEY_6,//
[KEYMAP_INDEX(4, 6)] = KEY_SHIFT | KEY_0,// )
[KEYMAP_INDEX(5, 0)] = KEY_SHIFT | KEY_2,// @
[KEYMAP_INDEX(5, 1)] = KEY_SHIFT | KEY_1,// !
[KEYMAP_INDEX(5, 2)] = KEY_SHIFT | KEY_BACKSLASH,// ?
[KEYMAP_INDEX(5, 3)] = KEY_BACKSLASH,//
[KEYMAP_INDEX(5, 4)] = KEY_2,//
[KEYMAP_INDEX(5, 5)] = KEY_3,//
[KEYMAP_INDEX(5, 6)] = KEY_SHIFT | KEY_9,// (
//dummy mapping for test only
[KEYMAP_INDEX(6, 0)] = KEY_4,//
[KEYMAP_INDEX(6, 1)] = KEY_5,//
[KEYMAP_INDEX(6, 2)] = KEY_6,//
[KEYMAP_INDEX(6, 3)] = KEY_7,//
[KEYMAP_INDEX(6, 4)] = KEY_8,//
[KEYMAP_INDEX(6, 5)] = KEY_9,//
[KEYMAP_INDEX(6, 6)] = KEY_0,//
};
int Fn_pressed=0;
int Capslock_pressed=0;
void kaiser_key_event(struct input_dev *input_dev, int key_index, int pressed)
{
unsigned short key;
if (pressed == 0)
return;
//if we relese Fn key, keymapping need to be change
if (key_index == KEYMAP_INDEX(2, 0))
{
Fn_pressed++;
if (Fn_pressed > 2)
Fn_pressed=0;
Capslock_pressed =0;
return;
}
//if we relese Fn key, keymapping need to be change
if (key_index == KEYMAP_INDEX(3, 0))
{
Capslock_pressed++;
if (Capslock_pressed > 2)
Capslock_pressed=0;
Fn_pressed = 0;
return;
}
if (Fn_pressed)
{
if (Fn_pressed == 1)
Fn_pressed=0;
key = (kaiser_keymap_plus_fn[key_index] & 0xffff);
if (kaiser_keymap_plus_fn[key_index] & KEY_SHIFT)
input_report_key(input_dev, KEY_RIGHTSHIFT, 1);
printk("\nSHIFT:0x%X, %d\n",kaiser_keymap_plus_fn[key_index],key_index);
input_report_key(input_dev, key, 1);
input_report_key(input_dev, key, 0);
if (kaiser_keymap_plus_fn[key_index] & KEY_SHIFT)
input_report_key(input_dev, KEY_RIGHTSHIFT, 0);
input_sync(input_dev);
return;
}
if (Capslock_pressed)
{
if (Capslock_pressed == 1)
Capslock_pressed=0;
input_report_key(input_dev, KEY_RIGHTSHIFT, 1);
input_report_key(input_dev, kaiser_keymap[key_index], 1);
input_report_key(input_dev, kaiser_keymap[key_index], 0);
input_report_key(input_dev, KEY_RIGHTSHIFT, 0);
input_sync(input_dev);
return;
}
input_report_key(input_dev,kaiser_keymap[key_index],1);
input_report_key(input_dev,kaiser_keymap[key_index],0);
input_sync(input_dev);
}
static struct gpio_event_matrix_info kaiser_matrix_info = {
.info.func = gpio_event_matrix_func,
.info.report_key_event = kaiser_key_event,
.keymap = kaiser_keymap,
.output_gpios = kaiser_row_gpios,
.input_gpios = kaiser_col_gpios,
.noutputs = ARRAY_SIZE(kaiser_row_gpios),
.ninputs = ARRAY_SIZE(kaiser_col_gpios),
.settle_time.tv.nsec = 0,
.poll_time.tv.nsec = 20 * NSEC_PER_MSEC,
.flags = GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_DRIVE_INACTIVE | GPIOKPF_PRINT_UNMAPPED_KEYS
};
struct gpio_event_info *kaiser_keypad_info[] = {
&kaiser_matrix_info.info
};
static struct gpio_event_platform_data kaiser_keypad_data = {
.name = "kaiser_keypad",
.info = kaiser_keypad_info,
.info_count = ARRAY_SIZE(kaiser_keypad_info)
};
static struct platform_device kaiser_keypad_device = {
.name = GPIO_EVENT_DEV_NAME,
.id = -1,
.dev = {
.platform_data = &kaiser_keypad_data,
},
};
void kaiser_init_keypad(void)
{
platform_device_register(&kaiser_keypad_device);
}