- #include <linux/module.h>
- #include<linux/errno.h>
- #include<linux/types.h>
- #include<linux/init.h>
- #include<linux/kernel.h>
- #include<linux/cdev.h>
- #include<linux/interrupt.h>
- #include<linux/irq.h>
- #include<linux/gpio.h>
- #include<linux/fs.h>
- #include<linux/device.h>
- #include<linux/uaccess.h>
- #include<linux/wait.h>
- #include<asm/io.h>
- #include<asm/irq.h>
- #include<linux/slab.h>
- #include<linux/kthread.h>
- struct cdev btn_cdev;
- wait_queue_head_t btn_wq;
- static int major;
- static struct class*cls;
- static int is_press;
- static unsigned char key_val;
- //static int press_num;
- static int irq;
- static void led_on(void)
- {
- printk("<0>""the lcd is on work\n");
- __gpio_set_value(GPIOH(6),1); //点亮lcd屏幕
- }
- static void led_off(void)
- {
- printk("<0>""the lcd is off work\n");
- __gpio_set_value(GPIOH(6),0); //灭掉lcd屏幕
- }
- static int button_open(struct inode*inode,struct file*file)
- {
- return 0;
- }
- static int button_close(struct inode*inode,struct file*file)
- {
- return 0;
- }
- static ssize_t button_read(struct file*file,char __user *buf,size_t count,loff_t *ppos)
- {
- unsigned long ret;
- wait_event_interruptible(btn_wq,is_press!=0);
- is_press=0;
- ret=copy_to_user(buf,&key_val,sizeof(key_val));
- return count;
- }
- static struct file_operations btn_fops={
- .owner=THIS_MODULE,
- .open=button_open,
- .release=button_close,
- .read=button_read
- };
- static irqreturn_t button_isr(int irq, void*dev_id)
- {
- unsigned int status;
- status=__gpio_get_value(GPIOG(0)); //获取gpiog0的电平值
- printk("<0>""the gpio value is %u\n",status);
- if(status==1){
- led_on();
- key_val=0x50;
- }else if(status==0){
- led_off();
- key_val=0x51;
- }
- printk("<0>""the isr is ok\n");
- wake_up_interruptible(&btn_wq);
- is_press=1;
- return IRQ_HANDLED;
- }
- static int button_init(void)
- {
- dev_t dev_id;
- int ret;
- int error;
- if(major){
- dev_id=MKDEV(major,0);
- register_chrdev_region(dev_id,1,"button_1"); //注册设备
- }else{
- alloc_chrdev_region(&dev_id,0,1,"button_1");
- major=MAJOR(dev_id);
- }
- printk("<0>""the major is on job\n");
- cdev_init(&btn_cdev,&btn_fops);
- init_waitqueue_head(&btn_wq);
- cdev_add(&btn_cdev,dev_id,1);
- cls=class_create(THIS_MODULE,"button_1");
- device_create(cls,NULL,dev_id,NULL,"button_1");
- ret=gpio_is_valid(GPIOG(0)); //判断gpio是否合法
- printk("<0>""the valid value is %d\n",ret);
- if(gpio_request(GPIOG(0),"gpio_pin")){
- printk("request gpio error\n");
- }
- gpio_direction_input(GPIOG(0)); //把pg0设置为输入
- irq=gpio_to_irq(GPIOG(0)); //gpio实现虚拟irq
- printk("<0>""the irq value is %d\n",irq);
- error=request_irq(irq,button_isr,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING,"KEY_111",NULL); //上升沿下降沿触发
- if(error){
- printk("request irq error\n");
- }
- printk("<0>""the value of error is %d\n",error);
- return 0;
- }
- static void button_exit(void)
- {
- dev_t dev_id=MKDEV(major,0);
- free_irq(irq,NULL); //释放irq
- gpio_free(GPIOG(0)); //释放gpio口
- device_destroy(cls,dev_id);
- class_destroy(cls);
- cdev_del(&btn_cdev);
- unregister_chrdev_region(dev_id,1); //释放设备
- printk("<0>""the dev is unregister\n");
- }
- module_init(button_init);
- module_exit(button_exit);
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("LZF");
复制代码 全志a33使用gpio口中断功能,检测一个gpio口,上升沿触发中断,开启背光,点亮lcd屏幕,下降沿,关闭背光,关掉lcd,注册为一个字符设备,设备也注册伤了,proc/interrupts下的irq分配的是1,但是按开关也没反应,大家帮我看看,调了好几天了,我在sys_config里面也加了【gpio_para】。图在下面 |