我用的是友善之臂的sbc2410开发板,里面自带了个buttons的按钮驱动程序,我们进行了一些改动,如下的程序。现在按下按键后,可在终端上打印出信息,但是不能象标准键盘那样实现io功能,能查的资料也有限,请问大家,如何能把键值传送给内核终端呢?
例如我设定buton 1 为 l
button 2为 s
按下这两个后能实现ls的功能,该如何实现呢?谢谢
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//MODULE_LICENSE("GPL");
#define DEVICE_NAME "buttons"
#define BUTTON_MAJOR 232
//#define KEY_A 1
//#define KEY_B 2
//static struct input_dev buttons_dev;
//static char kbmap[]={
// KK_LEFT,KK_UP,KK_RGHT,KK_DOWN
//};
static struct key_info {
int irq_no;
unsigned int gpio_port;
int key_no;
} key_info_tab[4] = {
{ IRQ_EINT1, GPIO_F1, 0x59 },
{ IRQ_EINT2, GPIO_F2, 0x60 },
{ IRQ_EINT3, GPIO_F3, 0x61 },
{ IRQ_EINT7, GPIO_F7, 0x62 },
};
static int ready = 0;
static int key_value = 0;
static DECLARE_WAIT_QUEUE_HEAD(buttons_wait);
static void buttons_irq(int irq, void *dev_id, struct pt_regs *reg)
{
struct key_info *k;
int i;
int found = 0;
int up;
int flags;
// printk("\nthis is buttons_irq program\n");
for (i = 0; i < sizeof key_info_tab / sizeof key_info_tab[1]; i++) {
k = key_info_tab + i;
if (k->irq_no == irq) {
found = 1;
break;
}
}
if (!found) {
printk("bad irq %d in button\n", irq);
return;
}
save_flags(flags);
cli();
set_gpio_mode_user(k->gpio_port, GPIO_MODE_IN);
up = read_gpio_bit(k->gpio_port);
set_external_irq(k->irq_no, EXT_BOTH_EDGES, GPIO_PULLUP_DIS);
restore_flags(flags);
if (up) {
key_value = k->key_no + 0x80;
handle_scancode(key_value,0);
tasklet_schedule(&keyboard_tasklet);
// input_report_key(&buttons_dev,key_value,1);
// input_sync(&buttons_dev);
printk("button [%d]press up\n\n",k->key_no);
// printk("this is irq %d\n",k->key_no);
} else {
key_value = k->key_no;
handle_scancode(key_value,1);
tasklet_schedule(&keyboard_tasklet);
// input_report_key(&buttons_dev,key_value,2);
// input_sync(&buttons_dev);
printk("button [%d] press down \n\n",k->key_no);
// printk("this is irq %d\n",k->key_no);
}
ready = 1;
wake_up_interruptible(&buttons_wait);
}
static int request_irqs(void)
{
struct key_info *k;
int i;
for (i = 0; i < sizeof key_info_tab / sizeof key_info_tab[1]; i++) {
k = key_info_tab + i;
set_external_irq(k->irq_no, EXT_BOTH_EDGES, GPIO_PULLUP_DIS);
if (request_irq(k->irq_no, &buttons_irq, SA_INTERRUPT, DEVICE_NAME, &buttons_irq)) {
return -1;
}
}
return 0;
}
static void free_irqs(void)
{
struct key_info *k;
int i;
for (i = 0; i < sizeof key_info_tab / sizeof key_info_tab[1]; i++) {
k = key_info_tab + i;
free_irq(k->irq_no, buttons_irq);
}
}
static int sbc2410_buttons_read(struct file * file, char * buffer, size_t count, loff_t *ppos)
{
static int key;
int flags;
int repeat;
if (!ready)
return -EAGAIN;
if (count != sizeof key_value)
return -EINVAL;
save_flags(flags);
if (key != key_value) {
key = key_value;
repeat = 0;
} else {
repeat = 1;
}
restore_flags(flags);
if (repeat) {
return -EAGAIN;
}
copy_to_user(buffer, &key, sizeof key);
ready = 0;
return sizeof key_value;
}
static unsigned int sbc2410_buttons_select(
struct file *file,
struct poll_table_struct *wait)
{
if (ready)
return 1;
poll_wait(file, &buttons_wait, wait);
return 0;
}
static int sbc2410_buttons_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
switch(cmd) {
default:
return -EINVAL;
}
}
static struct file_operations sbc2410_buttons_fops = {
owner: THIS_MODULE,
ioctl: sbc2410_buttons_ioctl,
poll: sbc2410_buttons_select,
read: sbc2410_buttons_read,
};
static int s3c_kbd_translate(unsigned char scancode, unsigned *keycode, char raw_mode)
{
int nResult = 1;
printk("my translate \n");
*keycode = (scancode & 0x7f);
return 1;
}
static devfs_handle_t devfs_handle;
static int __init s3c2410_kbd_init(void)
{
int ret;
// buttons_dev.name="tcbbuttons";
// set_bit(EV_KEY,buttons_dev.evbit);
// set_bit(KEY_A,buttons_dev.keybit);
// set_bit(KEY_B,buttons_dev.keybit);
// input_register_device(&buttons_dev);
ready = 0;
ret = register_chrdev(BUTTON_MAJOR, DEVICE_NAME, &sbc2410_buttons_fops);
if (ret < 0) {
printk(DEVICE_NAME " can't register major number\n");
return ret;
}
ret = request_irqs();
if (ret) {
unregister_chrdev(BUTTON_MAJOR, DEVICE_NAME);
printk(DEVICE_NAME " can't request irqs\n");
return ret;
}
devfs_handle = devfs_register(NULL, DEVICE_NAME, DEVFS_FL_DEFAULT,
BUTTON_MAJOR, 0, S_IFCHR | S_IRUSR | S_IWUSR, &sbc2410_buttons_fops, NULL);
k_translate = s3c_kbd_translate;
return 0;
}
static void __exit s3c2410_kbd_exit(void)
{
devfs_unregister(devfs_handle);
free_irqs();
unregister_chrdev(BUTTON_MAJOR, DEVICE_NAME);
// input_unregister_device(&buttons_dev);
}
module_init(s3c2410_kbd_init);
module_exit(s3c2410_kbd_exit);
MODULE_LICENSE("GPL");