Mark: On Fri, Dec 3, 2010 at 7:53 AM, Mark Brown <broonie@xxxxxxxxxxxxxxxxxxxxxxxxxxx> wrote: > > Surely that's what poll() and whatnot are for? If userspace has to poll > at all that seems to be a failure in itself. The poll() and blocking read() system calls allow an application to tell an input device that it is prepared to receive an event, and for an input device driver to tell userspace when an event has occurred. As implemented in evdev, however, neither system call provides a natural, consistent way for userspace to tell an input device driver how often it wants data--- or even if it wants any (at the moment) at all. I think that you and I talking about two different scenarios. You seem to be focused on the one where userspace is informed when an input event occurs, but has no ability to request or schedule those events. That model makes perfect sense for USB mice and keyboards where the hardware itself is inherently event-driven. For those kinds of devices, users don't know or care when a key will be pressed--- they just need to respond when one is. So they simply block in a poll() or read() until a keypress shows up. Problem solved. I'm looking at input devices like accelerometers and compasses, which must be explicitly sampled and can send events at upwards of 4K/sec if you ask them to. The vast majority of user applications don't need data anywhere near that fast, but the range of desirable rates can't be met by a simple "just sample it at 100 Hz" kernel thread because of power consumption and phase error issues. On a cell phone, for example, some situations call for accelerometer data at 2 Hz while other modes want the data at 200 Hz with minimal latency. The current architecture requires me to implement that range using a dedicated kernel thread, plus a sysfs attribute/ioctl to dial the rate up or down from userspace. For something like a pushbutton, sometimes you simply don't care about the state of the button except when you are asking for it--- and then you don't want a sample that might be a few seconds old. In other situations, doing a poll() and getting blocked until the pushbutton changes state works better. Pushbuttons are therefore kind of a corner case where the approach you choose depends more on what you want the application to look like. (Especially pushbuttons that aren't connected to interrupt-capable inputs). I don't want to do an ad-hoc method for communicating a polling rate request to the hardware for each hardware driver that I have to deal with. One way to avoid this is to add a standard sysfs attribute or ioctl for all input devices, which applications use to specify the rate that they want the hardware to sample at--- if the hardware works that way. That's fine, except that it adds an extra step that applications have to deal with. It also forces you to pick an arbitrary, default sampling rate if the application fails to specify one. The other option, which is the one I'm proposing and which seems more natural for end users, is to add an optional read callback in the input_dev structure that, if implemented by the driver, will call the driver back whenever someone is asking for the state of the input device. Drivers can then choose to initiate a sampling operation only when a user is asking for the data. Users just call poll() or read() at the rate they want the sampling to occur, and never get blocked for longer than it takes to acquire a sample. The advantage to the read callback approach is that users like Android can completely eliminate all of the kernel threads, etc. that drivers currently use to make high-rate hardware like accelerometers behave more like keyboards and mice. And this does more than simplify a bunch of code: it also creates a natural place for powering up/down the hardware between individual samples rather than just when the interface is opened and closed. It also automagically throttles up or down the sampling request rate as necessary to precisely match the user's demands. Finally, with the read callback approach there isn't any behavioral change in the evdev interface at all for existing drivers (and existing drivers will continue to work as they do now). When drivers start implementing the read callback, users will just notice that their drivers are simpler and their data is more recent--- if they care to investigate either of those. What I'm proposing is something that is very similar to input-polldev, except that users don't even have to specify the polling rate: they just call read() or poll() at the rate they want the input device hardware to scan/sample itself. Some current users of input-polldev might be better served by a read callback, in fact. The read callback approach is completely wrong for USB-ish keyboards and mice, so those drivers won't implement a read callback. But for accelerometers, pushbuttons and such, a read callback seems like a very useful tool. I hope to have first-hand evidence of that later today, preferably in a way that will be useful to the broader community as well. :) b.g. -- Bill Gatliff bgat@xxxxxxxxxxxxxxx -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html