Reputation: 5933
on a raspberry pi I want to be able to use a rotary encoder as volume control. the best way I can see to do that would be using the rotary_encoder module to read the encoder, set it up as a relative axis (so would get +1 or -1 events) and then make a driver to interpret that to create volume up or volume down keypresses.
however I'm struggling to get my head around interrupts and drivers, so my driver would have to register itself as able to provide EV_KEY events, which I think I've got handled, but I'm unsure how I can catch and act on events from the other driver?
I figured I would have to poll the /dev/input/event object created by the other driver, but I can't seem to find a guide on how to do this?
is this the best way to go? is there a way i can actually catch interrupts created by the other driver feeding events into the input system?
Upvotes: 1
Views: 2566
Reputation: 98328
It seems you want to receive input events from an unrelated module. But you cannot read /dev/input/event*
from kernel space, so you have to options:
/dev/input/event*
and forwards to your driver, maybe with a char device or a sysfs parameter.Option 1 should be straightforward. I'll elaborate on option 2.
To hook an input device from kernel you use function input_register_handler()
from your module init function (and input_unregister_handler()
from your exit function, of course).
This function takes a struct input_handler
as argument, it has a lot of members, but you probably only need to fill name
, id_table
, connect
, disconnect
and event
.
Then, in your connect
callback you call input_register_handle()
(note the handle
vs handler
names) and input_open_device()
and you will get input events in your event
callback.
Of course, do not forget to undo that work in your disconnect
callback.
There are several instances of this API usage in the kernel, but by far the easier one to read is the evbug
driver: it just dumps all input events into the kernel log.
Upvotes: 2