📄 matrix4-buttons.c
字号:
#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/miscdevice.h>#include <linux/sched.h>#include <linux/delay.h>#include <linux/poll.h>#include <linux/spinlock.h>#include <linux/irq.h>#include <linux/delay.h>#include <asm/hardware.h>#define DEVICE_NAME "buttons"#define BUTTON_MAJOR 232#define IRQ_BUTTONS IRQ_EINT7static int count = 0;static int ready = 0;static int key_value = 0;static DECLARE_WAIT_QUEUE_HEAD(buttons_wait);static int waitting_down = 1;static void buttons_irq(int irq, void *dev_id, struct pt_regs *reg){ int key_no; unsigned char data; if (waitting_down) { key_no = 0; GPFCON = (GPFCON & 0x3F03) | 4; udelay(300); data = GPFDAT; if ((data & 0x80) == 0) { if (data & 0x04) { key_no = 2; } else if (data & 0x08) { key_no = 3; } else { key_no = 1; } goto found; } GPFCON = (GPFCON & 0x3F03) | 0x10; udelay(300); data = GPFDAT; if ((data & 0x80) == 0) { if (data & 0x02) { key_no = 4; } else if (data & 0x08) { key_no = 6; } else { key_no = 5; } goto found; } GPFCON = (GPFCON & 0x3F03) | 0x40; udelay(300); data = GPFDAT; if ((data & 0x80) == 0) { if (data & 0x02) { key_no = 7; } else if (data & 0x04) { key_no = 8; } } found: GPFCON = (GPFCON & 0x3F03) | (2 << 14) | (1 << 6) | (1 << 4) | (1 << 2); if (key_no) { ready = 1; key_value = key_no; //printk("%d: key%d pressed\n", count++, key_no); wake_up_interruptible(&buttons_wait); EXTINT0 = (EXTINT0 & ~(7U << 28)) | (1U << 28); waitting_down = 0; } } else { GPFCON = GPFCON & 0x3FFF; udelay(300); data = GPFDAT; GPFCON |= (2 << 14); if ((data & 0x80)) { ready = 1; key_value = -1; wake_up_interruptible(&buttons_wait); //printk("%d: released\n", count++); waitting_down = 1; EXTINT0 &= ~(7U << 28); } }}static void buttons_io_port_init(void){ set_gpio_ctrl(GPIO_F1 | GPIO_PULLUP_DIS | GPIO_MODE_OUT); set_gpio_ctrl(GPIO_F2 | GPIO_PULLUP_DIS | GPIO_MODE_OUT); set_gpio_ctrl(GPIO_F3 | GPIO_PULLUP_DIS | GPIO_MODE_OUT); write_gpio_bit(GPIO_F1, 1); write_gpio_bit(GPIO_F2, 1); write_gpio_bit(GPIO_F3, 1); }static int matrix4_buttons_read(struct file * file, char * buffer, size_t count, loff_t *ppos){ if (!ready) return -EAGAIN; if (count != sizeof key_value) return -EINVAL; copy_to_user(buffer, &key_value, sizeof key_value); ready = 0; return sizeof key_value;}static unsigned int matrix4_buttons_select( struct file *file, struct poll_table_struct *wait){ if (ready) return 1; poll_wait(file, &buttons_wait, wait); return 0;}static int matrix4_buttons_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ switch(cmd) { default: return -EINVAL; }}static struct file_operations matrix4_buttons_fops = { owner: THIS_MODULE, ioctl: matrix4_buttons_ioctl, poll: matrix4_buttons_select, read: matrix4_buttons_read,};static devfs_handle_t devfs_handle;static int __init matrix4_buttons_init(void){ int ret; ready = 0; ret = register_chrdev(BUTTON_MAJOR, DEVICE_NAME, &matrix4_buttons_fops); if (ret < 0) { printk(DEVICE_NAME " can't register major number\n"); return ret; } buttons_io_port_init(); set_external_irq(IRQ_BUTTONS, EXT_LOWLEVEL, GPIO_PULLUP_DIS); ret = request_irq(IRQ_BUTTONS, &buttons_irq, SA_INTERRUPT, DEVICE_NAME, &buttons_irq); if (ret) { unregister_chrdev(BUTTON_MAJOR, DEVICE_NAME); printk(DEVICE_NAME " can't request irq %d\n", IRQ_BUTTONS); return ret; } devfs_handle = devfs_register(NULL, DEVICE_NAME, DEVFS_FL_DEFAULT, BUTTON_MAJOR, 0, S_IFCHR | S_IRUSR | S_IWUSR, &matrix4_buttons_fops, NULL); return 0;}static void __exit matrix4_buttons_exit(void){ devfs_unregister(devfs_handle); free_irq(IRQ_BUTTONS, buttons_irq); unregister_chrdev(BUTTON_MAJOR, DEVICE_NAME);}module_init(matrix4_buttons_init);module_exit(matrix4_buttons_exit);MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -