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);


返回上一頁