您的位置:首页 > 运维架构 > Linux

freescale imx6 linux gpio中断驱动

2017-01-19 10:13 183 查看
其原理图如下:



 

一个三极管,左边是一个外部信号,当POW_SW为高的时候,表明IMX CPU外部供电断开了。此时PMIC自动切换到电池供电。

 

就这个NPN型的三极管而言,POW_SW高,三极管的基极高,基极和发射极导通,集电极和发射极也导通,IMX端GPIO_7_11被拉低。

 

为了确保这个过程顺利执行,在GPIO被设置为中断腿之前,要设置为输入上拉(集电极读入为高)。如下是整个代码:

 

#include <linux/module.h>  

#include <linux/device.h>  

#include <linux/fs.h>  

#include <linux/miscdevice.h>  

#include <linux/sched.h>  

#include <linux/wait.h>  

#include <linux/irqreturn.h>  

#include <linux/interrupt.h>  

#include <asm/uaccess.h>  

#include <mach/gpio.h>  

#include <mach/iomux-v3.h>  

#include <mach/iomux-mx6dl.h>  

#define DEV_NAME        "pmu"  

#define VPU_POW_INT_PIN IMX_GPIO_NR(7, 11)  

#define VPU_POW_INT     gpio_to_irq(VPU_POW_INT_PIN)  

#define EVENT_POW_OFF   "EVENT_CHARGE_OFF\n"  

static DECLARE_WAIT_QUEUE_HEAD(vpu_pow_read_wait);  

static int wait_flag = 0;  

ssize_t ywwh_vpu_pow_read(struct file *filp, char __user *buf,  

size_t count, loff_t *ppos)  {  

wait_event_interruptible(vpu_pow_read_wait, wait_flag);  

wait_flag = 0;  

if (copy_to_user(buf, EVENT_POW_OFF, strlen(EVENT_POW_OFF)))  

return -EFAULT;  

return strlen(EVENT_POW_OFF);  

}  

static struct file_operations ywwh_vpu_pow_ops = {  

.owner = THIS_MODULE,  

.read = ywwh_vpu_pow_read,  

};  

static struct miscdevice miscdev = {  

.minor = MISC_DYNAMIC_MINOR,  

.name = DEV_NAME,  

.fops = &ywwh_vpu_pow_ops,  

.nodename = DEV_NAME,  

};  

static irqreturn_t vpu_pow_off_irq(int irq, void *dev_id)  

{  

printk("interrupt happend!\n");  

wake_up(&vpu_pow_read_wait);  

wait_flag = 1;  

return IRQ_HANDLED;  

}  

static int vpu_pow_init(void)  

{  

printk("irq = %u\n", VPU_POW_INT);  

mxc_iomux_v3_setup_pad(MX6DL_PAD_GPIO_16__GPIO_7_11);  //configures a single pad in the iomuxer

gpio_request(VPU_POW_INT_PIN, "vpu_pow_int");  

gpio_direction_input(VPU_POW_INT_PIN);  

printk("Get gpio val = %u\n", gpio_get_value_cansleep(VPU_POW_INT_PIN));  

gpio_free(VPU_POW_INT_PIN);  

int ret = request_irq(VPU_POW_INT, vpu_pow_off_irq,  

IRQF_TRIGGER_FALLING, "vpu_pow_off_irq", NULL);  

if (ret)  

return ret;  

ret = misc_register(&miscdev);  

if (ret)  

return ret;  

return 0;  

}  

static void vpu_pow_exit(void)  

{  

misc_deregister(&miscdev);  

}  

module_init(vpu_pow_init);  

module_exit(vpu_pow_exit);

MODULE_LICENSE("GPL");  

MODULE_AUTHOR("king");  

MODULE_DESCRIPTION("ywwh vpu pow detect");  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: