In Linux, how do you create an input event interface with a user specified event number and map that to a specific device event?
I'm using the gpio-keys driver to translate key presses from a keypad. I define the keys to be used in my board configuration source file as shown below
static struct gpio_keys_button ev_keys[] = {
[0] = {
.type = EV_KEY,
.active_low = 1,
.wakeup = 0,
.debounce_interval = KEYS_DEBOUNCE_MS,
.code = KEY_MUTE,
.desc = "mute",
.gpio = PUSHBUTTON_MUTE,
}
};
and register this with the kernel.
And I enable the event interface and GPIO buttons when building the kernel.
Device Drivers ---> Input device support --> Event interface
Device Drivers ---> Input device support --> Keyboards --> GPIO buttons
This creates a node to the event at /dev/input/event0 to which the GPIO button events are mapped. In a system that uses only one event interface I can call poll() on the fd to /dev/input/event0 and everything works as expected.
Now, I have second peripheral on my system that uses /dev/input/event0 by default and I need to map the events from the gpio-keys driver to another event. Any suggestions on how I go about creating an event with a number/id I can specify and then map this to the gpio-keys events?
Thanks.
If you mean by "mapping" specifying the name of the /dev/input/eventX 'file', you should use Udev. The kernel assigns the number of the event device, it is a bad idea and probably impossible to try and force this number since you never know which other device may have gotten this number first.
My recommendation would be to let Udev create a symlink that points to your device; you can choose your own name and use that in your program (i.e. /dev/my_first_keypad). For example, my Wacom tablet is assigned /dev/wacom with the following udev rule:
KERNEL=="event*", SUBSYSTEM=="input", SUBSYSTEMS=="input", ATTRS{name}=="Wacom Volito", SYMLINK+="wacom"
The trick is to find the proper set of variables to exactly specify your keypad. If it is USB based, the vender/product ID are a good start. Otherwise, use udevadm info --export-db to get a full dump of the Udev database. Udev rules go in files in /etc/udev/rules.d/ or /lib/udev.d, depending on the Linux distribution you are using.
You can check System.map file for functions that register event interface. The one that comes first, usually gets lowest eventX number and later functions gets eventX number increased by one. IMO, its ok to rely on static device node file for embedded device where device configuration is static and is not going to change during operation, but generally you should use udev for you purposes.
Related
I am writing a kernel module for detecting the tablet mode from a 2-in-1 laptop.
The module is accessing industrial I/O (or sensors) and needs to disable input devices (ex: internal keyboard and mouse). I would like doing it in kernel space to early disable the inputs (or the devices itself) if the laptop is powered on in tablet mode, avoiding users removing the splash screen at startup (for instance). Until now I have not found a way to disable the inputs without modifying the kernel sources.
1st idea:
Without modifying the kernel source,
my first attempt was to call the following function from linux/input.h, which "disables" a given input by ignoring its events:
void input_set_ignore_events(struct input_dev *dev, bool ignored)
I have found a way to get a struct device * device with its name as following, but I cannot find a way to get a struct input_dev * pointer from struct device *:
bus_find_device_by_name(&platform_bus_type, NULL, name);
Another idea would be to externaly access the static LIST_HEAD(input_dev_list); located into drivers/input/input.c.
2nd idea:
Do not try to access the kernel input abstraction but instead leverage offline() and suspend() functions of struct bus_type * from include/linux/device.h. According to the Documentation/ABI/testing/sysfs-devices-online it might work. I will try it soon.
Questions:
Is it possible to disable properly events or inputs from any external module ?
Is it possible to retrieve to a struct input_dev * from any external module ?
Thanks for your time.
I'm creating my first PCIe driver for Linux and have a question regarding which structure to use for the pci_set_drvdata() function.
The PCIe hardware is built in house and we will be using DMA to send data to and from the device. It is not a sound card or any other subsystem which needs to be plugged into the kernel.
When I look at examples there seems to be a specific struct to fill in and then send to pci_set_drvdata().
What do I fill in for this case? Do I simply ignore this and send in a blank structure? The line I am referring to in any PCIe driver is:
struct structure_in_question *my_struct;
my_struct = kzalloc( sizeof(*my_struct), GFP_KERNEL) );
This is usually found in the probe() function.
That function is used for associating with the device private data that cannot be supplied any other way. If there is no such data then the function should simply not be used.
It is a convenient way for example to save a pointer to a local dynamically allocated device context in the device probe callback and then retrieve it back with pci_get_drvdata in the device remove callback and do a proper cleanup of the context.
i am writing a linux kernel module which takes N of real /dev/input/js# devices and proxifies them as a single /dev/input/js3 device. Currently my module is creating /dev/input/js3 just fine, jstest is happy with it, but not the real applications. I guess (strace'd) it is so because i have no matching pair of /dev/input/event# for my virtual js3 device. How do i create one from my module?
Here is my module's source, which probably has numerous of issues, but mostly working: https://github.com/iamtakingiteasy/unijoy/blob/master/unijoy.c
Here is an example, you can use
1. class_create to create the class specified for the device,
2. device_create to create the device node
3. cdev_init to initialize and
4. cdev_add to add the device to the /dev list
For example you can refer the below link :Create a device node in kernel module
I am trying add some debug messages in block io to track the io operation in linux kernel.
IO could happen to multiple block device, I have dev_t value with me.
I can get major and minor number from dev_t.
I want to know is there any way to get the device file name from /dev/ dir using these major and minor number?
Of course, I need kernel APIs.
It's simple:
Use bdget function to find the block_device by dev_t.
Use bdevname to get the device name.
Use bdput to put the device reference.
Have fun.
You can also use libudev. Since you already have the dev_t id this way is aesier.
#include <libudev.h>
// Create the udev context.
struct udev *udev = udev_new();
// Create de udev_device from the dev_t.
struct udev_device *dev = udev_device_new_from_devnum(udev, 'b', sb.st_dev);
// Finally obtain the node.
const char* node = udev_device_get_devnode(dev);
udev_unref(udev);
In general, you cannot do such simple reverse mapping. This is because knowing some major and major numbers, one can always use mknod to create valid device file anywhere, not necessarily under /dev.
At the end of the day, kernel does not care much how did any particular device node with certain major/minor came about - such a node is simply entry point into the kernel device driver that can handle this hardware or software device.
Granted, in practice on most modern Linux systems most device nodes are located in /dev and maintained by udev - but it is user-space daemon, which your kernel driver cannot talk to. Also note that udev can be configured to create new device nodes with any name.
As I understood after reading the chapter related to The Linux Device Model in the Linux Device Drivers 3rd Edition, when a new device is configured, the kernel (2.6) follows more or less this sequence:
The Device is registered in the driver core (device_register(), what includes device initialization)
A kobject is registered in the device model
It creates an entry in sysfs and provokes a hotplug event
Bus and drivers are checked to see which one matches with the device
Probe
Device is binded to the driver
My main doubt is, in step 1, when is device_register() called and what fields should already be set in the device struct?
Is it called by the bus to which the device is connected? Any example in the code?
Have I misunderstood anything? :)
PCI hotplug code is going to call pci_do_scan_bus() to go through all slots, see if we find a device/bridge and add them to our device tree :
unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus) {
max = pci_scan_child_bus(bus) //scan bus for all slots and devices in them
pci_bus_add_devices(bus); //add what we find
...
}
The fields in struct device are actually filled up as part of call to pci_scan_child_bus(). Here's the call graph (sort of :)):
pci_scan_child_bus > pci_scan_slot (scan for slots on the bus) > pci_scan_single_device > pci_device_add > device_initialize.
Note that device_initialize() is the first part of device_register(). You will see that the fields of struct device are filled up in pci_device_add after the call to device_initialize(). You can find it under drivers/pci/probe.c in the kernel sources. The struct pci_dev will also be filled up which will later be used by the device specific driver.
The actual addition of the kobject to the device hierarchy happens in pci_bus_add_devices. Here's the call graph :
pci_bus_add_devices > pci_bus_add_device > device_add.
As you can see, this call flow completes the second part of the device_register() function.
So, in short, device_register() consists of : 1. Initialize device and 2. Add device.
pci_device_add does step 1 and pci_bus_add_device does step 2.
Files of interest are : drivers/pci/{pci.c,bus.c,probe.c}
In struct bus type there is pointer to function match, whose job is to match the driver associated with device. So when the device is associated with a bus, then as soon as the device is connected to bus then it is responsiblity of bus to search for the device.
Pls correct me if that is not the case.