首页 > 系统相关 >linux input子系统的event编号修改

linux input子系统的event编号修改

时间:2022-11-15 09:46:06浏览次数:64  
标签:struct evdev dev linux device input event minor

linux input子系统的event编号修改

在对接甲方的时候,一些input外设需要固定的input、event编号。而不同厂家不同型号的驱动在内核中加载的顺序不同,因此/dev/input下的event对应的设备不固定,如果更换外设的话event会发生相应的变化,是对接很不方便。

1、查看系统总线上的input设备

# cat /proc/bus/input/devices 
I: Bus=0000 Vendor=0000 Product=0000 Version=0000
N: Name="rockchip,rk3308-vad Headphones"
P: Phys=ALSA
S: Sysfs=/devices/platform/vad-acodec-sound/sound/card0/input0
U: Uniq=
H: Handlers=event0 
B: PROP=0
B: EV=21
B: SW=4

I: Bus=0019 Vendor=0001 Product=0001 Version=0100
N: Name="adc-keys"
P: Phys=adc-keys/input0
S: Sysfs=/devices/platform/adc-keys/input/input1
U: Uniq=
H: Handlers=event1 cpufreq 
B: PROP=0
B: EV=3
B: KEY=200000 0 0 0 1000000 8000 0 0 c0000 0 0 0

I: Bus=0019 Vendor=0001 Product=0001 Version=0100
N: Name="test_key"
P: Phys=gpio-keys/input0
S: Sysfs=/devices/platform/cdn_key/input/input3
U: Uniq=
H: Handlers=event2 cpufreq 
B: PROP=0
B: EV=100003
B: KEY=40 0 0 0

2、源码路径

input子系统的源码:kernel/drivers/input/input.c、kernel/drivers/input/evdev.c

3、修改input编号

根据源码可找到input_allocate_device函数,新的输入设备通过此函数分配内存,同时确定input编号,如下:

/**
 * input_allocate_device - allocate memory for new input device
 *
 * Returns prepared struct input_dev or %NULL.
 *
 * NOTE: Use input_free_device() to free devices that have not been
 * registered; input_unregister_device() should be used for already
 * registered devices.
 */
struct input_dev *input_allocate_device(void)
{
	static atomic_t input_no = ATOMIC_INIT(-1);
	struct input_dev *dev;
	dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);
	if (dev) {
		dev->dev.type = &input_dev_type;
		dev->dev.class = &input_class;
		device_initialize(&dev->dev);
		mutex_init(&dev->mutex);
		spin_lock_init(&dev->event_lock);
		init_timer(&dev->timer);
		INIT_LIST_HEAD(&dev->h_list);
		INIT_LIST_HEAD(&dev->node);

		dev_set_name(&dev->dev, "input%lu",
			     (unsigned long)atomic_inc_return(&input_no));

		__module_get(THIS_MODULE);
	}
	return dev;
}
EXPORT_SYMBOL(input_allocate_device);

以test_key为例,将input0修改为input1。

struct input_dev *input_allocate_device(void)
{
	static atomic_t input_no = ATOMIC_INIT(-1);
	struct input_dev *dev;
	dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);
	if (dev) {
		dev->dev.type = &input_dev_type;
		dev->dev.class = &input_class;
		device_initialize(&dev->dev);
		mutex_init(&dev->mutex);
		spin_lock_init(&dev->event_lock);
		init_timer(&dev->timer);
		INIT_LIST_HEAD(&dev->h_list);
		INIT_LIST_HEAD(&dev->node);
		/*dev_set_name(&dev->dev, "input%lu",
			     (unsigned long)atomic_inc_return(&input_no));*/
		if (strcmp(dev->name,"test_key") == 0) {
		    printk("Ares Debug test_key fixed to input1. \r\n");
                    dev_set_name(&dev->dev, "input1");
                }
                else {
        	    unsigned long inputNO = (unsigned long)atomic_inc_return(&input_no);
                    if(inputNO == 1) {
            	        printk("Ares Debug input1 has registed, turn to next. \r\n");
                        inputNO = (unsigned long)atomic_inc_return(&input_no)
                    }
                    printk("Ares Debug %s fixed to input%d. \r\n",dev->name,inputNO);
                    dev_set_name(&dev->dev, "input%lu", (unsigned long)inputNO);
                 }        
	         __module_get(THIS_MODULE);
	}
	return dev;
}
EXPORT_SYMBOL(input_allocate_device);

4、修改enent编号

根据源码可找到evdev_connect函数,新的输入设备通过此函数确定event编号,如下:

static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
			 const struct input_device_id *id)
{
	struct evdev *evdev;
	int minor;
	int dev_no;
	int error;

	minor = input_get_new_minor(EVDEV_MINOR_BASE, EVDEV_MINORS, true);
	if (minor < 0) {
		error = minor;
		pr_err("failed to reserve new minor: %d\n", error);
		return error;
	}
	......
	err_cleanup_evdev:
		evdev_cleanup(evdev);
	err_unregister_handle:
		input_unregister_handle(&evdev->handle);
	err_free_evdev:
		put_device(&evdev->dev);
	err_free_minor:
		input_free_minor(minor);
	return error;
}

以test_key为例,将event2修改为event1。

static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
			 const struct input_device_id *id)
{
	struct evdev *evdev;
	int minor;
	int dev_no;
	int error;

	//minor = input_get_new_minor(EVDEV_MINOR_BASE, EVDEV_MINORS, true);
    
	if(strcmp(dev->name, "test_key") == 0) {
	    printk("evdev_connect: Ares Debug test_key fixed to event0. \r\n");
	    minor = EVDEV_MINOR_BASE + 1;
	}
	else {
	    minor = input_get_new_minor(EVDEV_MINOR_BASE, EVDEV_MINORS, true);
	    if(minor == EVDEV_MINOR_BASE + 1) {
	        printk("evdev_connect: Ares Debug event0 has registed. turn to next. \r\n");
	        minor = input_get_new_minor(EVDEV_MINOR_BASE, EVDEV_MINORS, true);
	    }
	}
	printk("evdev_connect: %s: minor = %d \r\n", dev->name, minor);
    
    
	if (minor < 0) {
		error = minor;
		pr_err("failed to reserve new minor: %d\n", error);
		return error;
	}
	......
	err_cleanup_evdev:
		evdev_cleanup(evdev);
 	err_unregister_handle:
		input_unregister_handle(&evdev->handle);
 	err_free_evdev:
		put_device(&evdev->dev);
 	err_free_minor:
		input_free_minor(minor);
	return error;
}

注:以上是我的一些记录和遇到的问题,以及解决方法,如果有不对的地方,请各位大佬指出。

1、转载说明:
转载于:https://blog.csdn.net/Auris/article/details/116156047

标签:struct,evdev,dev,linux,device,input,event,minor
From: https://www.cnblogs.com/Rxin/p/16891369.html

相关文章

  • Linux——虚拟机如何连接XShell
    目录一、检查虚拟机设置的网络连接是否为NAT模式二、虚拟网络编辑器中查看IP地址三、设置虚拟机的IP地址,子网掩码,网关,DNS四、XSell中连接虚拟机五、总结一、检查虚拟......
  • linux FHS结构
    FHS:Linux的文件系统分层结构:FHSFilesystemHierarchyStandard(文件系统层次化标准)的缩写,多数Linux版本采用这种文件组织形式,类似于Windows操作系统中c盘的文件目录,FHS采......
  • Linux笔记:查看和修改系统时间
    1.查看系统当前时间命令:date[root@zjy~]#dateSunNov1320:14:44CST20222.修改系统时间修改时间:date-s"21:12:00"修改日期:date-s"2022-11-12"#需......
  • 第四章 linux字符设备驱动一
    前言字符设备是Linux驱动中三大设备之一,字符(char)设备是个能够像字节流(类似文件)一样被访问的设备,由字符设备驱动程序来实现这种特性。字符设备驱动程序通常至少要实现open......
  • 云服务器(Linux)安装部署Kafka
    云服务器(Linux)安装部署Kafka前期准备kafka的安装需要依赖于jdk,需要在服务器上提前安装好该环境,这里使用用jdk1.8。下载安装包官网地址:较新的版本已自带Zookeeper,无......
  • 【Linux环境部署】Python版本更新及替换
    默认python版本替换1.测试当前默认python版本user@user-jwq#pythonPython2.7.18(default,Jul12022,12:27:04)[GCC9.4.0]onlinux2Type"help","copyright......
  • Linux内存管理 (2)页表的映射过程【转】
    转自:https://www.cnblogs.com/arnoldlu/p/8087022.html 关键词:swapper_pd_dir、ARMPGD/PTE、LinuxPGD/PTE、pgd_offset_k。 Linux下的页表映射分为两种,一是Linux自......
  • 嵌入式-Linux常用初级指令和介绍
    ls:列出当前文件夹下有哪些文件 ls-a:显示所有文件,包括隐藏的文件和文件夹pwd:显示在当前哪个文件夹下面  mkdir+新建文件夹名称:新建文件夹  进入文件夹:cd+......
  • 嵌入式-Linux基础操作
    Crtl+Alt+T:调出命令窗口xrandr:列出分辨率列表 设置窗口的分辨率大小为1280x960:xrandr-s1280x960   通过命令窗口来执行一段C语言程序:VI工具的使用:(1)vifir......
  • linux环境与IDE
    1 Linux上练习和开发 1.1 安装centos环境1.1.1 windows机器上安装虚拟机vmwarehttps://www.likecs.com/show-145995.html 1.1.2 下载centos7操作系统光盘http......