4412驱动-input 输入子系统


// cat /proc/bus/input/devices 列出当前系统下注册的所有输入设备


/* 测试方法,将当前终端的标准输入重定向到驱动框架所产生的tty设备上
 * exec 0  */


4412驱动-input 输入子系统_第1张图片


#include 
#include 
#include 

#include 
#include 
#include 
#include 

#include 

// cat /proc/bus/input/devices 列出当前系统下注册的所有输入设备

/* 测试方法,将当前终端的标准输入重定向到驱动框架所产生的tty设备上
 * exec 0reg);//从内存映射的 I/O 空间读取数据,readl 从 I/O 读取 32 位数据 ( 4 字节 )
	return data & pkey->ctrlbit;
}

static struct key_info key[] = {
	{"KEY_L", KEY_L, stat, (unsigned long)GPX3DAT, 1 << 2, IRQ_EINT(26)},
	{"KEY_S", KEY_S, stat, (unsigned long)GPX3DAT, 1 << 3, IRQ_EINT(27)},
	{"KEY_ENTER", KEY_ENTER, stat, (unsigned long)GPX3DAT, 1 << 4, IRQ_EINT(28)},
	{"KEY_BACKSPACE", KEY_BACKSPACE, stat, (unsigned long)GPX3DAT, 1 << 5, IRQ_EINT(29)},
};

static irqreturn_t key_handler(int irqno, void *arg)
{
	struct key_info *pkey = (struct key_info *)arg;

	//读出触发中断的当前按键的状态
	if (pkey->read_stat(pkey)) { //抬起
		//value=1表示按下,=0表示抬起,硬件状态应根据寄存器反应的电平状态来判断
		input_report_key(ldm.dev, pkey->code, 0);
	} else { //按下
		input_report_key(ldm.dev, pkey->code, 1);
	}

	//哨兵event
	input_sync(ldm.dev);

	return IRQ_HANDLED;
}

static int __init ldm_init(void)
{
	printk("%s %s\n", __FUNCTION__, __FILE__);

	int ret = 0;

	//1 创建输入设备对象
	ldm.dev = input_allocate_device();
	if (!ldm.dev) {
		printk("input_allocate_device failed\n");
		ret = -ENOMEM;
		goto err_input_allocate_device;
	}

	//2 对象初始化
	ldm.dev->name = "ldm_key";

	//2.1 定义输入设备的输入类型
	//有按键类型的操作
	set_bit(EV_KEY, ldm.dev->evbit);
	//支持连发
	set_bit(EV_REP, ldm.dev->evbit);
	//注册本设备所拥有的所有按键键值
	ssize_t i = 0;
	for (i = 0; i < ARRAY_SIZE(key); ++i) {
		set_bit(key[i].code, ldm.dev->keybit);
	}

	//3 硬件初始化,中断申请,按下抬起都触发中断
	for (i = 0; i < ARRAY_SIZE(key); ++i) {
		ret = request_irq(key[i].irqno, key_handler, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, key[i].name, (void*)(key + i));
		if (ret < 0) {
			printk("request_irq %d faild\n", i);
			goto err_request_irq;
		}
	}

	//4 注册输入设备
	ret = input_register_device(ldm.dev);
	if (ret < 0) {
		printk("input_register_device failed\n");
		goto err_input_register_device;
	}

	return 0;

err_input_register_device:
err_request_irq:
	for (i = i - 1; i >= 0; --i) {
		free_irq(key[i].irqno, (void*)(key + i));
	}
	input_free_device(ldm.dev);
err_input_allocate_device:
	return ret;
}

static void __exit ldm_exit(void)
{
	printk(KERN_DEBUG "%s %s\n", __FUNCTION__, __FILE__);

	input_unregister_device(ldm.dev);

	ssize_t i = ARRAY_SIZE(key);//ARRAY_SIZE求设备结构体中设备的个数
	for (i = i - 1; i >= 0; --i) {
		free_irq(key[i].irqno, (void*)(key + i));
	}

	input_free_device(ldm.dev);
}

module_init(ldm_init);
module_exit(ldm_exit);



MODULE_LICENSE("GPL");
MODULE_AUTHOR("xiangtan da xue chenhaipan");  
MODULE_VERSION("2017.5.4"); 

4412驱动-input 输入子系统_第2张图片


你可能感兴趣的:(友善之臂,4412)