嵌入式爱好者

查看: 6863|回复: 1

[Linux] AM335-按键中断

[复制链接]

2

主题

4

帖子

8

积分

扫一扫,手机访问本帖
发表于 2014-8-8 17:20:02 | 显示全部楼层 |阅读模式
各位大侠,我现在想把LINUX2.6下的按键驱动移植到linux3.2.0 AM335上!!但是好像总是无法中断!麻烦大侠们指点指点!


#include <linux/init.h>
#include <linux/export.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/moduleparam.h>
#include <linux/errno.h>
#include <linux/device.h>  
#include <linux/syscalls.h>
#include <linux/miscdevice.h>
#include <linux/types.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/sched.h>  
#include <linux/gpio.h>
#include <asm/gpio.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <linux/of_gpio.h>
#include <linux/of_platform.h>
#include <linux/uaccess.h>
#include <linux/string.h>

static struct class *forthdrv_class;
static struct class_device        *forthdrv_class_dev;

static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

/* 中断事件标志, 中断服务程序将它置1,third_drv_read将它清0 */
static volatile int ev_press = 0;

struct pin_desc{
        unsigned int pin;
        unsigned int key_val;
};
/* 键值: 按下时, 0x01, 0x02, 0x03, 0x04 */
/* 键值: 松开时, 0x81, 0x82, 0x83, 0x84 */
static unsigned char key_val;

struct pin_desc pins_desc[6] = {
        {20, 0x01},
        {21, 0x02},
        {22, 0x03},
        {23, 0x04},
        {24, 0x05},
        {25, 0x06},
};
       
#define DPRINTK(fmt,arg...) printk(fmt,##arg);
#define IRQT_BOTHEDGE (__IRQT_RISEDGE|__IRQT_FALEDGE);

#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio))

#define LED_ON 1
#define LED_OFF 0
#define DEV_NAME        "led"

/*
  * 确定按键值
  */
static irqreturn_t buttons_irq(int irq, void *dev_id)
{
        struct pin_desc * pindesc = (struct pin_desc *)dev_id;
        unsigned int pinval;
        printk("<0>""interrupt is open");
        pinval = gpio_get_value(GPIO_TO_PIN(1, pindesc->pin));
        if (pinval)
        {
                /* 松开 */
                key_val = 0x80 | pindesc->key_val;
        }
        else
        {
                /* 按下 */
                key_val = pindesc->key_val;
        }

    ev_press = 1;                  /* 表示中断发生了 */
    wake_up_interruptible(&button_waitq);   /* 唤醒休眠的进程 */

       
        return IRQ_RETVAL(IRQ_HANDLED);
}

static void led_on(int num)
{
        //gpio had been requested so just use it
        gpio_set_value(GPIO_TO_PIN(1, 16 + num), 0);
}
static void led_off(int num)
{
        gpio_set_value(GPIO_TO_PIN(1, 16 + num), 1);
}


static int led_open(struct inode *inode, struct file *filp)
{

        DPRINTK("led open\n");

  request_irq(gpio_to_irq(GPIO_TO_PIN(1, 20)),  buttons_irq, IRQF_TRIGGER_FALLING, "S0", &pins_desc[0]);
        request_irq(gpio_to_irq(GPIO_TO_PIN(1, 21)),  buttons_irq, IRQF_TRIGGER_FALLING, "S1", &pins_desc[1]);
        request_irq(gpio_to_irq(GPIO_TO_PIN(1, 22)),  buttons_irq, IRQF_TRIGGER_FALLING, "S2", &pins_desc[2]);
        request_irq(gpio_to_irq(GPIO_TO_PIN(1, 23)),  buttons_irq, IRQF_TRIGGER_FALLING, "S3", &pins_desc[3]);
        request_irq(gpio_to_irq(GPIO_TO_PIN(1, 24)),  buttons_irq, IRQF_TRIGGER_FALLING, "S4", &pins_desc[4]);
        request_irq(gpio_to_irq(GPIO_TO_PIN(1, 25)),  buttons_irq, IRQF_TRIGGER_FALLING, "S5", &pins_desc[5]);
       
        return 0;

       

}

static int led_release(struct inode *inode, struct file *filp)
{
                free_irq(gpio_to_irq(GPIO_TO_PIN(1, 20)), &pins_desc[0]);
                free_irq(gpio_to_irq(GPIO_TO_PIN(1, 21)), &pins_desc[1]);
                free_irq(gpio_to_irq(GPIO_TO_PIN(1, 22)), &pins_desc[2]);
                free_irq(gpio_to_irq(GPIO_TO_PIN(1, 23)), &pins_desc[3]);
                free_irq(gpio_to_irq(GPIO_TO_PIN(1, 24)), &pins_desc[4]);
                free_irq(gpio_to_irq(GPIO_TO_PIN(1, 25)), &pins_desc[5]);
               
    DPRINTK("led release\n");
        return 0;
}


static long led_ioctl(struct file *filp,
                        unsigned int cmd, unsigned long arg)
{
        DPRINTK("led ioctl with cmd:%d,arg:%d\n",cmd,arg);

#if defined(CONFIG_OK335XD)       
        if(arg <0 || arg >3)
                return -EINVAL;
#elif defined(CONFIG_OK335XS)
        if(arg <0 || arg >0)
                return -EINVAL;
#endif
       
        switch (cmd) {
        case LED_ON:
                led_on(arg);
                break;
        case LED_OFF:
                led_off(arg);
                break;
        default:
                break;
        }

        return 0;
}
ssize_t led_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{

        int regval,i;
       
        if (size != 1)
                return -EINVAL;
                /* 如果没有按键动作, 休眠 */
        wait_event_interruptible(button_waitq, ev_press);

        /* 如果有按键动作, 返回键值 */
        copy_to_user(buf, &key_val, 1);
        ev_press = 0;
       
        return 1;
       
}
static struct file_operations forth_drv_fops = {
        .owner   = THIS_MODULE,
        .open    = led_open,
        .read    = led_read,
        .release = led_release,
        .unlocked_ioctl         = led_ioctl,
};

static struct miscdevice led_miscdev =
{
         .minor        = MISC_DYNAMIC_MINOR,
         .name        = DEV_NAME,
         .fops        = &forth_drv_fops,
};

int major;
static int __init forthdrv_init(void)
{
        //misc_register(&led_miscdev);
        int ret=0;
        int inter=0;
        major = register_chrdev(0, "forth_drv", &forth_drv_fops); // 注册, 告诉内核

        forthdrv_class = class_create(THIS_MODULE, "forthdrv");

        forthdrv_class_dev = device_create(forthdrv_class, NULL, MKDEV(major, 0), NULL, "button"); /* /dev/button */
       
        return 1;

}

static void __exit forthdrv_exit(void)
{
  // misc_deregister(&led_miscdev);
  unregister_chrdev(major, "forth_drv"); // 卸载

        device_unregister(forthdrv_class_dev);
        class_destroy(forthdrv_class);
}

module_init(forthdrv_init);
module_exit(forthdrv_exit);

MODULE_AUTHOR("duyahui <duyahui@forlinx.com>");
MODULE_DESCRIPTION("forth driver");
MODULE_LICENSE("GPL");

回复

使用道具 举报

153

主题

3910

帖子

4207

积分

AM5718通行证AM335x通行证i.MX6UL通行证i.MX RT通行证i.MX6Q通行证XX18通行证TCU通行证FCU1401通行证FCU1301通行证FCU11xx通行证

发表于 2014-8-12 09:16:45 | 显示全部楼层
楼主,最好比对一下代码有什么不一样的地方,而且2.6版本的和3.X版本的内核的结构是有变化的
技术支持电话:0312-3119192
技术支持邮箱:Linux@forlinx.com
点评回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋| 飞凌嵌入式 ( 冀ICP备12004394号-1 )

GMT+8, 2024-5-7 08:23

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表