Input subsystem

There seems to be something wrong with what we said earlier:
1) The device module we write is not compiled together with input.c of the core layer and evdev.c of the call layer.
The positive solution is that our device is a module, and the core layer is also a module, and the call layer is also a module. Only when the kernel is running, it has loaded the resources of the core layer and the call layer into the kernel. When our device module is loaded into the kernel, the kernel will call the core and call layer modules to form a complete driver.
2) That set_ The bit function does not take that ev_key is written into evdev: this function is to set ev_ EV in dev_ Key position 1:

3) For event, this device file is the device node applied for when calling. So all device nodes are called event?
If so, why are there mouse and other device nodes in it? If not, why can event also represent mouse and other input systems.
So what is the relationship between event event and mouse?
Here, let's explain in detail what the previous functions did?
First, we create a device object (instantiate the input device structure object):

struct input_dev *inputdev;

What is inside the equipment structure?

struct input_dev {//It represents a specific input device and describes what data the device can generate
	const char *name; // Information for users in sysfs
	const char *phys;
	const char *uniq;
	struct input_id id;
	//evbit is actually a bit table that describes what type of data the input device can generate
	unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; // EV_KEY,EV_ABS, EV_REL
	//Indicates which key can be generated
	unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];//KEY_POWER.. can represent 768bit, which is directly represented by 24 long
							 // KEY_CNT == 768   BITS_TO_LONGS== nr/32 = 768/32==24
	//Indicates which relative coordinate data can be generated
	unsigned long relbit[BITS_TO_LONGS(REL_CNT)];// REL_X
	//Indicates which absolute coordinate data can be generated
	unsigned long absbit[BITS_TO_LONGS(ABS_CNT)]; //ABS_X
	unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];
	unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];
	unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];
	unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
	unsigned long swbit[BITS_TO_LONGS(SW_CNT)];

	struct device dev; // Inherit device object

	struct list_head	h_list;
	struct list_head	node; //Represents a node

This structure is actually very large: there are some important information above.

First, the first four: add user information
Represents: our customized device information. What is the name and version number of our device? If you type this information, you will print it out and tell the user when you check the device information.
Directly use: input - > name = "key1"... To initialize the device information.

The fourth data: indicates the data type generated
unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; // EV_KEY,EV_ABS, EV_REL
This is actually a 32-bit bit table. Each bit represents the corresponding data type.
Then our input device will generate many kinds of data:

eg: 1,Key/keyboard:  The generated key value is actually a number
				#define KEY_VOLUMEDOWN		114
				#define KEY_VOLUMEUP		115
				#define KEY_POWER		116	/* SC System Power Down */
		2,ts/gsensor:Generate coordinates, absolute coordinates, have a clear coordinate system, and the origin(0,0),Maximum(800,480)
				#define ABS_X			0x00
				#define ABS_Y			0x01
				#define ABS_PRESSURE		0x18
				#define ABS_MT_TOUCH_MAJOR	0x30	/* Major axis of touching ellipse */
				#define ABS_MT_TOUCH_MINOR	0x31	/* Minor axis (omit if circular) */
				#define ABS_MT_WIDTH_MAJOR	0x32	/* Major axis of approaching ellipse */
				#define ABS_MT_WIDTH_MINOR	0x33	/* Minor axis (omit if circular) */
				#define ABS_MT_ORIENTATION	0x34	/* Ellipse orientation */
				#define ABS_MT_POSITION_X	0x35	/* Center X touch position */
				#define ABS_MT_POSITION_Y	0x36	/* Center Y touch position */
		3,mouse: Generate coordinates, relative coordinates, and the coordinate value is relative to the previous point coordinates	
				#define REL_X			0x00
				#define REL_Y			0x01
				#define REL_WHEEL		0x08

So how do we distinguish these signals is in the bit table of evbit. The position you give will indicate which bit your data is.
For example, this is a key signal:

I can use:_set_bit(EV_KEY,inputdev->evbit);  
#define EV_KEY			0x01

Go and express EV in evbit_ Position 1 of key can see our ev_key is number one

Setting it to one will produce this effect: the kernel knows that you are an ev_key type data, which is also equivalent to a switch. If you turn this switch on, your data can be sent to the calling layer.

5; The fifth member: indicates the specific information of the key
unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];/ /KEY_POWER... Can represent 768bit, which is directly represented by 24 long
This is a 768 bit array, which is used to store your keys. It is the specific representation type above.
For example, if I want to press this key, it means that I pressed an ESC key. If you set the position of the ESC key corresponding to the keybit to one, it means that this key means ESC
Of course, you want to set this button to 12345qewrrtyuiopasdfghjklzxcvbnm... These buttons are OK.

_set_bit(KEY_POWER, inputdev->keybit);
#define KEY_POWER 		 116 ` insert code slice here`

This means that you put 166 in one position, which means that your key is a power key. In this way, the data you send will bring the key_power this data
Of course, you can also set 166 directly by handwriting without a function. It is a 768 bit 768 / 32 long data
inputdev->keybit[116/32] |= 1 << 116%32;// 116%32;

Because we are a button, we have no relative coordinates and other information
Therefore: the Long data of 5 ~ 12 is the specific information of the generated data.

13: struct device dev; // Inherit device object
Represents the inherited device object, owns all device properties, and makes some extensions. This is inheritance
15: Represents the information node of our device, which can be registered in the core layer and matched with the calling layer

3, Data reporting:
The last time we saw our data reporting, we used:
void input_event(struct input_dev *dev,unsigned int type, unsigned int code, int value)
Can: device data type (key, absolute coordinate, relative coordinate...)
Specific representation of equipment data (a specific key, specific coordinates...)
Data status: 0 / 1 -- indicates the status of this data. For example, if I pass a 1, it means that my esc key is pressed, and it will
To execute the data or interrupt processing of esc.
These three data are made into a package and sent to the calling layer.
Method 2: encapsulation:
input_report_key(struct input_dev * dev, unsigned int code, int value)
input_event(dev, EV_KEY, code, !!value); // It must be 0 or 1 when reporting the button
You can also report data in this way:
!! Value: this button must be 0 or 1 when reporting. The usage is ingenious. For example, the value I pass is 5! Value is 0, then! (! value) is 1;
So two!! The function of is to ensure that the reporting button must be 0 or 1.

Posted by surion on Fri, 24 Sep 2021 00:59:21 -0700