AM3358 >> C/C++
Keyboard(Polling)
arch/arm/boot/dts/am335x-bonegreen-wireless.dts
am33xx_pinmux: pinmux@44e10800 { pinctrl-names = "default"; pinctrl-0 = <&gpio_keys_s0 &lcd_pins_s0> ... gpio_keys_s0: gpio_keys_s0 { pinctrl-single,pins = < 0x90 0x37 0x9c 0x37 0x34 0x37 0x3c 0x37 0x2c 0x37 0x94 0x37 0x98 0x37 0x30 0x37 0x28 0x37 0x38 0x37 0x8c 0x37 0x78 0x37 >; };
drivers/gpio/keyboard/main.c
#include <linux/init.h> #include <linux/device.h> #include <linux/module.h> #include <linux/delay.h> #include <linux/timer.h> #include <linux/gpio.h> #include <linux/input.h> #include <asm/irq.h> #include <asm/io.h> #include <asm/io.h> #define do_request(pin, name) \ if(gpio_request(pin, name) < 0){ \ printk("failed to request gpio: %s\n", name); \ } \ else{ \ printk("request successfully for gpio: %s\n", name); \ gpio_direction_output(pin, 1); \ gpio_direction_input(pin); \ } MODULE_AUTHOR("Steward_Fu"); MODULE_DESCRIPTION("AM335x Keyboard Driver"); MODULE_LICENSE("GPL"); static int g_blink_period=100; static struct input_dev *button_dev; static struct timer_list g_blink_timer; static void report_key(unsigned long btn, unsigned long mask, unsigned char key) { static unsigned long btn_pressed=0; static unsigned long btn_released=0xfff; if(btn & mask){ btn_released&= ~mask; if((btn_pressed & mask) == 0){ btn_pressed|= mask; input_report_key(button_dev, key, 1); } } else{ btn_pressed&= ~mask; if((btn_released & mask) == 0){ btn_released|= mask; input_report_key(button_dev, key, 0); } } } static void blink_handler(unsigned long unused) { unsigned long val; static unsigned long pre=0; val = gpio_get_value(66) << 10; // left val|= gpio_get_value(69) << 11; // down val|= gpio_get_value(45) << 8; // up val|= gpio_get_value(47) << 9; // right val|= gpio_get_value(27) << 0; // a val|= gpio_get_value(68) << 3; // b val|= gpio_get_value(67) << 1; // x val|= gpio_get_value(44) << 2; // y val|= gpio_get_value(26) << 4; // l val|= gpio_get_value(60) << 7; // r val|= gpio_get_value(46) << 6; // start val|= gpio_get_value(65) << 5; // select val = ~val; if(pre != val){ pre = val; report_key(pre, 0x100, KEY_UP); report_key(pre, 0x800, KEY_DOWN); report_key(pre, 0x400, KEY_LEFT); report_key(pre, 0x200, KEY_RIGHT); report_key(pre, 0x080, KEY_BACKSPACE); report_key(pre, 0x040, KEY_ENTER); report_key(pre, 0x020, KEY_ESC); report_key(pre, 0x010, KEY_TAB); report_key(pre, 0x001, KEY_LEFTCTRL); report_key(pre, 0x008, KEY_LEFTALT); report_key(pre, 0x002, KEY_SPACE); report_key(pre, 0x004, KEY_LEFTSHIFT); input_sync(button_dev); } mod_timer(&g_blink_timer, jiffies + msecs_to_jiffies(g_blink_period)); } static int __init main_init(void) { do_request(66, "gpio-66"); do_request(69, "gpio-69"); do_request(45, "gpio-45"); do_request(47, "gpio-47"); do_request(27, "gpio-27"); do_request(67, "gpio-67"); do_request(68, "gpio-68"); do_request(44, "gpio-44"); do_request(26, "gpio-26"); do_request(46, "gpio-46"); do_request(65, "gpio-65"); do_request(60, "gpio-60"); button_dev = input_allocate_device(); set_bit(EV_KEY,button_dev-> evbit); set_bit(KEY_UP, button_dev->keybit); set_bit(KEY_DOWN, button_dev->keybit); set_bit(KEY_LEFT, button_dev->keybit); set_bit(KEY_RIGHT, button_dev->keybit); set_bit(KEY_ENTER, button_dev->keybit); set_bit(KEY_ESC, button_dev->keybit); set_bit(KEY_LEFTCTRL, button_dev->keybit); set_bit(KEY_LEFTALT, button_dev->keybit); set_bit(KEY_SPACE, button_dev->keybit); set_bit(KEY_LEFTSHIFT, button_dev->keybit); set_bit(KEY_TAB, button_dev->keybit); set_bit(KEY_BACKSPACE, button_dev->keybit); button_dev->name = "am335x-kbd"; button_dev->id.bustype = BUS_HOST; input_register_device(button_dev); setup_timer(&g_blink_timer, blink_handler, 0); mod_timer(&g_blink_timer, jiffies + msecs_to_jiffies(g_blink_period)); return 0; } static void __exit main_exit(void) { input_unregister_device(button_dev); del_timer(&g_blink_timer); } module_init(main_init); module_exit(main_exit);