您尚未登录。

#1 Re: 全志 SOC » 请问有人可以教一下怎么写lradc驱动吗? » 2019-01-08 11:41:27

晕哥 说:
aoaoao123mm 说:
晕哥 说:

原来如此, 给大家挖坑了, 当时我也不记得是怎么算的了, 不会算也就算了, 还算了个错的放上来   ;(

晕哥那你知道哪里能看全部的中断号吗?

V3s手册 (Allwinner_V3s_Datasheet_V1.0.pdf) ?

那个中断号都不对的。。。。

#2 Re: 全志 SOC » 请问有人可以教一下怎么写lradc驱动吗? » 2019-01-04 15:41:00

晕哥 说:

原来如此, 给大家挖坑了, 当时我也不记得是怎么算的了, 不会算也就算了, 还算了个错的放上来   ;(

晕哥那你知道哪里能看全部的中断号吗?

#3 Re: 全志 SOC » 请问有人可以教一下怎么写lradc驱动吗? » 2019-01-04 08:44:23

smartcar 说:
aoaoao123mm 说:
晕哥 说:

@aoaoao123mm 参考26 楼呢?

兄弟,中断号是34不是30,测了我一天了,心累啊。。。。

https://whycan.cn/files/members/458/QQ20190103201646.png

为什么不是 62 ?

34 是怎么算出来的?

不是算的啊,是改内核那个sun4i-lradc-keys.c ,然它把中断号打印出来看的,你们知道中断号究竟怎么查吗?

#4 Re: 全志 SOC » 请问有人可以教一下怎么写lradc驱动吗? » 2019-01-03 17:39:00

晕哥 说:

@aoaoao123mm 参考26 楼呢?

兄弟,中断号是34不是30,测了我一天了,心累啊。。。。

#5 Re: 全志 SOC » 请问有人可以教一下怎么写lradc驱动吗? » 2019-01-03 16:26:53

晕哥 说:

@aoaoao123mm 参考26 楼呢?

不行,不过问题好像找到了中断共用了,好像得改下sun4i-a10-lradc-keys文件,我先试试先

#6 Re: 全志 SOC » 有大哥知道lradc的中断驱动怎么写吗 » 2019-01-03 14:27:10

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

#7 Re: 全志 SOC » 请问有人可以教一下怎么写lradc驱动吗? » 2019-01-03 14:24:45

605364021 说:

lradc.ko模块可以加载,但是在打开设备时提示申请中断失败

# cat /proc/interrupts 
           CPU0       
 19:       7017     GIC-0  27 Level     arch_timer
 21:          0     GIC-0  50 Level     /soc/timer@01c20c00
 22:          0     GIC-0  82 Level     1c02000.dma-controller
 23:      18046     GIC-0  92 Level     sunxi-mmc
 24:      12219     GIC-0  93 Level     sunxi-mmc
 25:          1     GIC-0 103 Level     musb-hdrc.1.auto
 26:          0     GIC-0 104 Level     ehci_hcd:usb1
 27:          0     GIC-0 105 Level     ohci_hcd:usb2
 28:          0     GIC-0  72 Level     1c20400.rtc
 35:        800     GIC-0  32 Level     ttyS0
 36:          0     GIC-0  38 Level     mv64xxx_i2c
IPI0:          0  CPU wakeup interrupts
IPI1:          0  Timer broadcast interrupts
IPI2:          0  Rescheduling interrupts
IPI3:          0  Function call interrupts
IPI4:          0  CPU stop interrupts
IPI5:          0  IRQ work interrupts
IPI6:          0  completion interrupts
Err:          0
# exec 6</dev/lradc 
[  293.796488] genirq: Failed to request resources for my_adc (irq 62) on irqchip sunxi_pio_edge
-sh: can't open /dev/lradc: Invalid argument

我在驱动程序open函数中使用request_irq进行申请中断,其中62我是在v3s芯片手册中查到的lradc中断号,知道会是什么原因导致注册中断失败?

static int adc_open(struct inode * inode,struct file * file) //打开设备函数
{
	//注册中断
	int ret;
	ret=request_irq(62,adc_interrupt,IRQF_SHARED,ADC_NAME,1);//注册中断 IRQ_ADC在 mach/irqs.h中定义
	if(ret<0)
	{
		printk("IRQ %d can not request/n",IRQ_ADC);
		return ret;
	}
	return 0;
}

兄弟你这个弄好了吗?我也一样遇到这个问题

#8 Re: 全志 SOC » 有大哥知道lradc的中断驱动怎么写吗 » 2019-01-03 08:52:07

basicdev 说:

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

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

#9 Re: 全志 SOC » 有大哥知道lradc的中断驱动怎么写吗 » 2019-01-02 17:03:34

trigger 说:

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

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

#10 Re: 全志 SOC » 有大哥知道lradc的中断驱动怎么写吗 » 2019-01-02 15:43:46

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

#12 全志 SOC » 有大哥知道lradc的中断驱动怎么写吗 » 2019-01-02 15:39:03

aoaoao123mm
回复: 7
 #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");//驱动程序符合的协议

页脚

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

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