freescale imx6 linux gpio中断驱动


今天上班写了个小代码,用于检测掉电处理。当主控CPU的GPIO_7_11被拉低的时候,则触发中断,表明发生了外部掉电事件。

其原理图如下:


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

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

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

/*
 * Author: King
 * Date: 2016.4.22
 */

#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"

MODULE_LICENSE("GPL");
MODULE_AUTHOR("king");
MODULE_DESCRIPTION("ywwh vpu pow detect");

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



  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值