linux设备树之外部中断key

9 篇文章 0 订阅
吐舌头
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/platform_device.h>
#include <asm/io.h>
#include <linux/fs.h>
#include <linux/of.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h> 

//--------------------------------------------------------------------------------
// 查看 exynos4412-origen.dts 
// --> #include "exynos4412.dtsi" 
// 查看 exynos4412.dtsi 
// --> #include "exynos4x12.dtsi" 
// 查看 exynos4x12.dtsi
// -->#include "exynos4.dtsi"
//	  #include "exynos4x12-pinctrl.dtsi"
// 查看 exynos4x12-pinctrl.dtsi
/* -->  gpx1: gpx1 {
			gpio-controller;
			#gpio-cells = <2>;

			interrupt-controller;
			interrupt-parent = <&gic>;
			interrupts = <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
				         <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>;
			#interrupt-cells = <2>;
		};
	我们看到gpx1的中断控制父节点是gic(generic interrupt controller)
	查看 exynos4.dtsi --> #include "skeleton.dtsi"
	目标出现:------------------>
	gic: interrupt-controller@10490000 {
		compatible = "arm,cortex-a9-gic";
		#interrupt-cells = <3>;
		interrupt-controller;
		reg = <0x10490000 0x1000>, <0x10480000 0x100>;
	};
	查阅exynos4412手册-->
	0x1048_0000 GIC_controller
	0x1049_0000 GIC_distributor
	--------------------------------------------------------------------------------
*/
// 26 58 – EINT[10] External Interrupt
// 25 57 – EINT[9]  External Interrupt
/*DTS
	mykey{
		compatible = "key2";
		interrupt-parent = <&gpx1>; // 父节点gpx1
		interrupts = <1 2>, <2 2>; // 锁定25, 26号中断<0 25 0>,<0 26 0>
	};
*/
MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("a simple driver example!");

int count; 
long last;
struct resource *res2;
struct resource *res3;

struct timer_list key2_timer;
struct timer_list key3_timer;
void key2server_func(unsigned long arg)
{
	printk("key2 pressed: %d!\n", count);
}
void key3server_func(unsigned long arg)
{
	printk("key3 pressed: %d!\n", count);
}
irqreturn_t key2_int_handler(int n, void *dev)
{
	// 定时器去抖
	mod_timer(&key2_timer, jiffies+50);

	return IRQ_HANDLED;
}

irqreturn_t key3_int_handler(int n, void *dev)
{
	// 定时器去抖
	mod_timer(&key3_timer, jiffies+50);

	return IRQ_HANDLED;
}

int key_probe(struct platform_device *pdev)
{
	int ret = 0;
	printk("key probe !\n");
	
	setup_timer(&key2_timer, key2server_func, 0);
	setup_timer(&key3_timer, key3server_func, 0);

	add_timer(&key2_timer);
	add_timer(&key3_timer);	
	// 解析中断号
	res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	printk("irqnum: %#x\n", res2->start);
	res3 = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
	printk("irqnum: %#x\n", res3->start);
	request_irq(res2->start, key2_int_handler, (res2->flags&IRQF_TRIGGER_MASK) | IRQF_DISABLED, "key2", NULL);
	request_irq(res3->start, key3_int_handler, (res3->flags&IRQF_TRIGGER_MASK) | IRQF_DISABLED, "key3", NULL);
	
	return ret;
}

int key_remove(struct platform_device *pdev)
{

	printk("key module release\n");
	free_irq(res2->start, NULL);
	free_irq(res3->start, NULL);
	return 0;
}

#ifdef CONFIG_OF

struct of_device_id key_table[] = {
	{ .compatible = "key" },
	{ }
};

#endif


struct platform_driver key_driver = {
	.probe = key_probe,
	.remove = key_remove,
	.driver = {
		.name = "key",
		.of_match_table = of_match_ptr(key_table)
	}
};

static int key_init(void)
{
	printk("module install\n");


	//add into platform bus
	platform_driver_register(&key_driver);

	return 0;
}

static void key_exit(void)
{
	printk("module release\n");
	//del from platform bus
	platform_driver_unregister(&key_driver);
}


module_init(key_init);
module_exit(key_exit);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值