您尚未登录。

楼主 #1 2019-01-02 15:39:03

aoaoao123mm
会员
注册时间: 2019-01-02
已发帖子: 15
积分: 15

有大哥知道lradc的中断驱动怎么写吗

 #include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/device.h>

#include <linux/io.h>
#include <linux/interrupt.h>


static void __iomem *LRADC_BASE_Data0;
static void __iomem *LRADC_BASE_Inter_S;
static void __iomem *LRADC_BASE_Inter_C;
static void __iomem *LRADC_BASE_Control;
static void __iomem *LRADC_BASE;

static struct cdev LRADC_cdev;		//字符设备结构体
static dev_t	LRADC_num = 0;		//设备号
static struct class 	*LRADC_class;
static struct device 	*LRADC_device;


short int irq_key = 30;
char name[]={"key"};


static int  LRADC_open(struct inode * inode, struct file *file)
{
	printk("LRADC_open \n");
	return 0;
}

static int  LRADC_release(struct inode * inode, struct file *file)
{
	printk("LRADC_release \n");
	return 0;
}

static ssize_t LRADC_write(struct file * file, const char __user * buf, size_t len,loff_t * off)
{
	printk("LRADC_BASE_Data0=0x%x\r\n",ioread32(LRADC_BASE_Data0));
        printk("LRADC_BASE_Inter_C=0x%x",ioread32(LRADC_BASE_Inter_C));
        printk("LRADC_BASE_Inter_S=0x%x\r\n",ioread32(LRADC_BASE_Inter_S));
	return ioread32(LRADC_BASE_Data0);
}

static const struct file_operations LRADC_fops = {
	.owner = THIS_MODULE,
	.write = LRADC_write,
	.open =  LRADC_open,
	.release = LRADC_release
};


static irqreturn_t r_irq_handler(int irq, void *dev_id)
{
        printk("being interrupt\r\n");
	printk("LRADC_BASE_Inter_S=0x%x\r\n",ioread32(LRADC_BASE_Inter_S));
        if(ioread32(LRADC_BASE_Inter_S) != 0)
	{
        	printk("KEY RISING\r\n");
        	printk("LRADC_BASE_Data0=0x%x\r\n",ioread32(LRADC_BASE_Data0));
	}
        return IRQ_HANDLED;
}








//入口函数
static int __init init_LRADC(void)
{
	int rt = 0;

	struct resource * LRADC_res = NULL;

	//动态申请设备号
	rt = alloc_chrdev_region(&LRADC_num, 0, 1, "LRADC");

	if (rt < 0)
	{
		printk("alloc_chrdev_region fail\n");

		return rt;

	}

	//字符设备初始化
	cdev_init(&LRADC_cdev, &LRADC_fops);

	//字符设备添加到内核
	rt = cdev_add(&LRADC_cdev, LRADC_num, 1);

	if (rt < 0)
	{
		printk("cdev_add fail\n");
		goto fail_cdev_add;
	}

	//创建类
	LRADC_class = class_create(THIS_MODULE, "LRADC");

	if (IS_ERR(LRADC_class))
	{
		rt = PTR_ERR(LRADC_class);

		printk("class_create LRADC fail\n");

		goto fail_class_create;

	}

	//创建设备
	LRADC_device = device_create(LRADC_class, NULL, LRADC_num, NULL, "LRADC");

	if (IS_ERR(LRADC_device))
	{
		rt = PTR_ERR(LRADC_device);

		printk("device_create LRADC fail\n");

		goto fail_device_create;
	}
	

	//申请物理内存区
        //起始地址GPIOg寄存器基址0x01C20000
        //申请大小0xffff字节
        //申请到的名字为GPIOH_MEM
        LRADC_res = request_mem_region(0x01C20000,0xFFFF,"GPIOG_MEM");

	if(LRADC_res == NULL)
	{
	   printk("request_mem_region fail\n");
	  // goto fail_request_mem_region;	
	}
	//IO内存动态映射,得到物理地址相应的虚拟地址
	LRADC_BASE = ioremap(0x01C22000,0XFFFF);
	
        printk("LRADC_BASE=0x%x",((unsigned int)LRADC_BASE));

	if(LRADC_BASE == NULL)
	{	
	    printk("ioremap  fail\n");
	    goto fail_ioremap;
	}	
	//得到每个寄存器的虚拟地址
	LRADC_BASE_Control = LRADC_BASE + 0x800;
        printk("addr:LRADC_BASE_Control=0x%x",((unsigned int)LRADC_BASE_Control));
	LRADC_BASE_Data0 = LRADC_BASE + 0x80C;
	printk("addr:LRADC_BASE_Data0=0x%x",((unsigned int)LRADC_BASE_Data0));
	LRADC_BASE_Inter_S  = LRADC_BASE + 0x808;
        printk("addr:LRADC_BASE_Inter_S=0x%x",((unsigned int)LRADC_BASE_Inter_S));
        LRADC_BASE_Inter_C  = LRADC_BASE + 0x804;
        printk("addr:LRADC_BASE_Inter_C=0x%x",((unsigned int)LRADC_BASE_Inter_C));

	iowrite32(0x1000141 , LRADC_BASE_Control);  
        iowrite32(0x2 , LRADC_BASE_Inter_C);        //down
	printk("LRADC_BASE_Data0=0x%x",ioread32(LRADC_BASE_Data0));
        printk("LRADC_BASE_Inter_C=0x%x",ioread32(LRADC_BASE_Inter_C));
        printk("LRADC_BASE_Inter_S=0x%x",ioread32(LRADC_BASE_Inter_S));

        printk("key init\r\n");
        if (request_irq(irq_key,(irq_handler_t ) r_irq_handler, IRQF_TRIGGER_FALLING , name , NULL)) 
        {
     		printk("Irq Request failure\n");
      		return 0;
        }
        return 0;

fail_ioremap:
	release_mem_region(0x01C22000, 0xffff);

fail_request_mem_region:
	device_destroy(LRADC_class, LRADC_num);

fail_device_create:
	class_destroy(LRADC_class);

fail_class_create:
	cdev_del(&LRADC_cdev);

fail_cdev_add:
	unregister_chrdev_region(LRADC_num, 1);

	return rt;
}


//出口函数
static void __exit exit_LRADC(void)
{
	iounmap(LRADC_BASE);

        release_mem_region(0x01C22000,0xffff);

	device_destroy(LRADC_class, LRADC_num);

	class_destroy(LRADC_class);

	cdev_del(&LRADC_cdev);

	unregister_chrdev_region(LRADC_num, 1);
       
	free_irq(irq_key, NULL);

        printk("key remove\r\n");  

        return ;
}



module_init(init_LRADC);   
module_exit(exit_LRADC);
MODULE_LICENSE("GPL");//驱动程序符合的协议

离线

楼主 #2 2019-01-02 15:40:20

aoaoao123mm
会员
注册时间: 2019-01-02
已发帖子: 15
积分: 15

Re: 有大哥知道lradc的中断驱动怎么写吗

我这样写是申请失败的

离线

楼主 #3 2019-01-02 15:43:46

aoaoao123mm
会员
注册时间: 2019-01-02
已发帖子: 15
积分: 15

Re: 有大哥知道lradc的中断驱动怎么写吗

板子是荔枝派zero,那个if (request_irq(irq_key,(irq_handler_t ) r_irq_handler, IRQF_TRIGGER_FALLING , name , NULL))中的第三个参数我到底填什么,这个中断事件怎么找???

离线

楼主 #5 2019-01-02 17:03:34

aoaoao123mm
会员
注册时间: 2019-01-02
已发帖子: 15
积分: 15

Re: 有大哥知道lradc的中断驱动怎么写吗

trigger 说:

devname设置中断名称,通常是设备驱动程序的名称  在cat /proc/interrupts中可以看到此名称。

是第三个那个(IRQF_TRIGGER_FALLING),是中断标志,我不知道在哪里找?你说的中断名称是第四个。

离线

楼主 #7 2019-01-03 08:52:07

aoaoao123mm
会员
注册时间: 2019-01-02
已发帖子: 15
积分: 15

Re: 有大哥知道lradc的中断驱动怎么写吗

basicdev 说:

参考这个帖子:  https://whycan.cn/t_1916.html

这个帖子我看过了,但最后也没有给出解决方法。。。。

离线

楼主 #8 2019-01-03 14:27:10

aoaoao123mm
会员
注册时间: 2019-01-02
已发帖子: 15
积分: 15

Re: 有大哥知道lradc的中断驱动怎么写吗

参考晕哥的GPIO中断就可以,但这个lradc中断却不行。。。。。有大神救救吗

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn