设备注册
定义按键的映射,
/* KEY(row, col, keycode) */
static const uint32_t board_matrix_keys[] = {
KEY(0, 0, KEY_LEFT),
KEY(1, 0, KEY_RIGHT),
KEY(2, 0, KEY_A),
KEY(3, 0, KEY_B),
KEY(4, 0, KEY_C),
KEY(0, 1, KEY_DOWN),
KEY(1, 1, KEY_UP),
KEY(2, 1, KEY_E),
KEY(3, 1, KEY_F),
KEY(4, 1, KEY_G),
KEY(0, 2, KEY_ENTER),
KEY(1, 2, KEY_I),
KEY(2, 2, KEY_J),
KEY(3, 2, KEY_K),
KEY(4, 2, KEY_3),
KEY(0, 3, KEY_M),
KEY(1, 3, KEY_N),
KEY(2, 3, KEY_O),
KEY(3, 3, KEY_P),
KEY(4, 3, KEY_Q),
KEY(0, 4, KEY_R),
KEY(1, 4, KEY_4),
KEY(2, 4, KEY_T),
KEY(3, 4, KEY_U),
KEY(4, 4, KEY_ENTER),
KEY(0, 5, KEY_V),
KEY(1, 5, KEY_W),
KEY(2, 5, KEY_L),
KEY(3, 5, KEY_S),
KEY(4, 5, KEY_ENTER),
};
static const struct matrix_keymap_data board_keymap_data = {
.keymap = board_matrix_keys,
.keymap_size = ARRAY_SIZE(board_matrix_keys),
};
static unsigned int board_keypad_row_gpios[] = {
88, 89, 124, 11, 6, 96
};
static unsigned int board_keypad_col_gpios[] = {
90, 91, 100, 36, 12, 97, 98
};
static struct matrix_keypad_platform_data board_keypad_platform_data = {
.keymap_data = &board_keymap_data,
.row_gpios = board_keypad_row_gpios,
.num_row_gpios = ARRAY_SIZE(board_keypad_row_gpios),
.col_gpios = board_keypad_col_gpios,
.num_col_gpios = ARRAY_SIZE(board_keypad_col_gpios),
.active_low = 1,
.debounce_ms = 20,//消除抖动的时间,20ms
.col_scan_delay_us = 5,
};
static struct platform_device board_keyboard = {
.name = "matrix-keypad",
.id = -1,
.dev = {
.platform_data = &board_keypad_platform_data,
},
};
platform_device_register(&board_keyboard); //将矩阵键盘注册到系统中
驱动程序注册
static struct platform_driver matrix_keypad_driver = {
.probe = matrix_keypad_probe,
.remove = __devexit_p(matrix_keypad_remove),
.driver = {
.name = "matrix-keypad",//设备名字和驱动名字完全匹配后,调用matrix_keypad_probe函数
.owner = THIS_MODULE,
#ifdef CONFIG_PM
.pm = &matrix_keypad_pm_ops,
#endif
},
};
static int __init matrix_keypad_init(void)
{
return platform_driver_register(&matrix_keypad_driver);
}
static void __exit matrix_keypad_exit(void)
{
platform_driver_unregister(&matrix_keypad_driver);
}
module_init(matrix_keypad_init);
module_exit(matrix_keypad_exit);
MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
MODULE_DESCRIPTION("GPIO Driven Matrix Keypad Driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:matrix-keypad");
static int __devinit matrix_keypad_probe(struct platform_device *pdev)
{
const struct matrix_keypad_platform_data *pdata;
const struct matrix_keymap_data *keymap_data;
struct matrix_keypad *keypad;
struct input_dev *input_dev;
unsigned short *keycodes;
unsigned int row_shift;
int err;
pdata = pdev->dev.platform_data;
if (!pdata) {
dev_err(&pdev->dev, "no platform data defined\n");
return -EINVAL;
}
keymap_data = pdata->keymap_data;
if (!keymap_data) {
dev_err(&pdev->dev, "no keymap data defined\n");
return -EINVAL;
}
row_shift = get_count_order(pdata->num_col_gpios);
keypad = kzalloc(sizeof(struct matrix_keypad), GFP_KERNEL);
keycodes = kzalloc((pdata->num_row_gpios << row_shift) *
sizeof(*keycodes),
GFP_KERNEL);
input_dev = input_allocate_device();
if (!keypad || !keycodes || !input_dev) {
err = -ENOMEM;
goto err_free_mem;
}
keypad->input_dev = input_dev;
keypad->pdata = pdata;
keypad->keycodes = keycodes;
keypad->row_shift = row_shift;
keypad->stopped = true;
INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan);
spin_lock_init(&keypad->lock);
input_dev->name = pdev->name;
input_dev->id.bustype = BUS_HOST;
input_dev->dev.parent = &pdev->dev;
input_dev->evbit[0] = BIT_MASK(EV_KEY);
if (!pdata->no_autorepeat)
input_dev->evbit[0] |= BIT_MASK(EV_REP);
input_dev->open = matrix_keypad_start;
input_dev->close = matrix_keypad_stop;
input_dev->keycode = keycodes;
input_dev->keycodesize = sizeof(*keycodes);
input_dev->keycodemax = pdata->num_row_gpios << row_shift;
matrix_keypad_build_keymap(keymap_data, row_shift,
input_dev->keycode, input_dev->keybit);
input_set_capability(input_dev, EV_MSC, MSC_SCAN);
input_set_drvdata(input_dev, keypad);
err = init_matrix_gpio(pdev, keypad);
if (err)
goto err_free_mem;
err = input_register_device(keypad->input_dev);
if (err)
goto err_free_mem;
device_init_wakeup(&pdev->dev, pdata->wakeup);
platform_set_drvdata(pdev, keypad);
return 0;
err_free_mem:
input_free_device(input_dev);
kfree(keycodes);
kfree(keypad);
return err;
}