linux中input_register_device註冊函數分析

 

17.1.2  註冊函數input_register_device()(1)

button_init()函數中的28行調用了input_register_device()函數註冊輸入設備結構體。input_register_device()函數是輸入子系統核心(input core)提供的函數。該函數將input_dev結構體註冊到輸入子系統核心中,input_dev結構體必須由前面講的input_allocate_device()函數來分配。input_register_device()函數如果註冊失敗,必須調用input_free_device()函數釋放分配的空間。如果該函數註冊成功,在卸載函數中應該調用input_unregister_device()函數來註銷輸入設備結構體。

1.input_register_device()函數

input_register_device()函數的代碼如下:

/**
 * input_register_device - register device with input core
 * @dev: device to be registered
 *
 * This function registers device with input core. The device must be
 * allocated with input_allocate_device() and all it's capabilities
 * set up before registering.
 * If function fails the device must be freed with input_free_device().
 * Once device has been successfully registered it can be unregistered
 * with input_unregister_device(); input_free_device() should not be
 * called in this case.
 */
int input_register_device(struct input_dev *dev)
{
	static atomic_t input_no = ATOMIC_INIT(0);
	struct input_handler *handler;
	const char *path;
	int error;

	/* Every input device generates EV_SYN/SYN_REPORT events. */
	__set_bit(EV_SYN, dev->evbit);

	/* KEY_RESERVED is not supposed to be transmitted to userspace. */
	__clear_bit(KEY_RESERVED, dev->keybit);

	/* Make sure that bitmasks not mentioned in dev->evbit are clean. */
	input_cleanse_bitmasks(dev);

	/*
	 * If delay and period are pre-set by the driver, then autorepeating
	 * is handled by the driver itself and we don't do it in input.c.
	 */
	init_timer(&dev->timer);
	if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) {
		dev->timer.data = (long) dev;
		dev->timer.function = input_repeat_key;
		dev->rep[REP_DELAY] = 250;
		dev->rep[REP_PERIOD] = 33;
	}

	if (!dev->getkeycode)
		dev->getkeycode = input_default_getkeycode;

	if (!dev->setkeycode)
		dev->setkeycode = input_default_setkeycode;

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

	error = device_add(&dev->dev);
	if (error)
		return error;

	path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
	printk(KERN_INFO "input: %s as %s\n",
		dev->name ? dev->name : "Unspecified device", path ? path : "N/A");
	kfree(path);

	error = mutex_lock_interruptible(&input_mutex);
	if (error) {
		device_del(&dev->dev);
		return error;
	}

	list_add_tail(&dev->node, &input_dev_list);

	list_for_each_entry(handler, &input_handler_list, node)
		input_attach_handler(dev, handler);

	input_wakeup_procfs_readers();

	mutex_unlock(&input_mutex);

	return 0;
}


 

 

下面對該函數的主要代碼進行分析。

第03~06行,定義了一些函數中將要用到的局部變量。

第07行,調用__set_bit()函數設置input_dev所支持的事件類型。事件類型由input_dev的evbit成員來表示,在這裏將其EV_SYN置位,表示設備支持所有的事件。注意,一個設備可以支持一種或者多種事件類型。常用的事件類型如下:

  1. #define EV_SYN          0x00    /*表示設備支持所有的事件*/  
  2. #define EV_KEY          0x01    /*鍵盤或者按鍵,表示一個鍵碼*/  
  3. #define EV_REL          0x02    /*鼠標設備,表示一個相對的光標位置結果*/  
  4. #define EV_ABS          0x03    /*手寫板產生的值,其是一個絕對整數值*/  
  5. #define EV_MSC          0x04    /*其他類型*/  
  6. #define EV_LED          0x11    /*LED燈設備*/  
  7. #define EV_SND          0x12    /*蜂鳴器,輸入聲音*/  
  8. #define EV_REP          0x14    /*允許重複按鍵類型*/  
  9. #define EV_PWR          0x16    /*電源管理事件*/ 

dev_set_name設置input_dev中的device的名字,名字以input0、input1、input2、input3、input4等的形式出現在sysfs文件系統中。

使用device_add()函數將input_dev包含的device結構註冊到Linux設備模型中,並可以在sysfs文件系統中表現出來。

打印設備的路徑,輸出調試信息。

調用list_add_tail()函數將input_dev加入input_dev_list鏈表中,input_dev_list鏈表中包含了系統中所有的input_dev設備。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章