diff mbox

virtio-input: support absolute axis config in pass-through

Message ID 1460558603-18331-1-git-send-email-lprosek@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Ladi Prosek April 13, 2016, 2:43 p.m. UTC
VIRTIO_INPUT_CFG_ABS_INFO was not implemented for pass-through input
devices. This patch follows the existing design and pre-fetches the
config for all absolute axes using EVIOCGABS at realize time.

Signed-off-by: Ladi Prosek <lprosek@redhat.com>
---
 hw/input/virtio-input-host.c     | 46 ++++++++++++++++++++++++++++++++++++++--
 hw/input/virtio-input.c          |  6 +++---
 include/hw/virtio/virtio-input.h |  3 +++
 3 files changed, 50 insertions(+), 5 deletions(-)

Comments

Gerd Hoffmann April 13, 2016, 3:45 p.m. UTC | #1
On Mi, 2016-04-13 at 16:43 +0200, Ladi Prosek wrote:
> VIRTIO_INPUT_CFG_ABS_INFO was not implemented for pass-through input
> devices. This patch follows the existing design and pre-fetches the
> config for all absolute axes using EVIOCGABS at realize time.

Just in time for the input pull request I was preparing ;)

thanks,
  Gerd
Ladi Prosek April 13, 2016, 3:50 p.m. UTC | #2
On Wed, Apr 13, 2016 at 5:45 PM, Gerd Hoffmann <kraxel@redhat.com> wrote:
> On Mi, 2016-04-13 at 16:43 +0200, Ladi Prosek wrote:
>> VIRTIO_INPUT_CFG_ABS_INFO was not implemented for pass-through input
>> devices. This patch follows the existing design and pre-fetches the
>> config for all absolute axes using EVIOCGABS at realize time.
>
> Just in time for the input pull request I was preparing ;)

Thanks! I'm done with my guest driver work so there shouldn't be
anything else from me in this area for some time.

Ladi

> thanks,
>   Gerd
>
diff mbox

Patch

diff --git a/hw/input/virtio-input-host.c b/hw/input/virtio-input-host.c
index 62185d5..58ee83f 100644
--- a/hw/input/virtio-input-host.c
+++ b/hw/input/virtio-input-host.c
@@ -69,13 +69,39 @@  static void virtio_input_bits_config(VirtIOInputHost *vih,
     virtio_input_add_config(VIRTIO_INPUT(vih), &bits);
 }
 
+static void virtio_input_abs_config(VirtIOInputHost *vih, int axis)
+{
+    virtio_input_config config;
+    struct input_absinfo absinfo;
+    int rc;
+
+    rc = ioctl(vih->fd, EVIOCGABS(axis), &absinfo);
+    if (rc < 0) {
+        return;
+    }
+
+    memset(&config, 0, sizeof(config));
+    config.select = VIRTIO_INPUT_CFG_ABS_INFO;
+    config.subsel = axis;
+    config.size   = sizeof(virtio_input_absinfo);
+
+    config.u.abs.min  = cpu_to_le32(absinfo.minimum);
+    config.u.abs.max  = cpu_to_le32(absinfo.maximum);
+    config.u.abs.fuzz = cpu_to_le32(absinfo.fuzz);
+    config.u.abs.flat = cpu_to_le32(absinfo.flat);
+    config.u.abs.res  = cpu_to_le32(absinfo.resolution);
+
+    virtio_input_add_config(VIRTIO_INPUT(vih), &config);
+}
+
 static void virtio_input_host_realize(DeviceState *dev, Error **errp)
 {
     VirtIOInputHost *vih = VIRTIO_INPUT_HOST(dev);
     VirtIOInput *vinput = VIRTIO_INPUT(dev);
-    virtio_input_config id;
+    virtio_input_config id, *abs;
     struct input_id ids;
-    int rc, ver;
+    int rc, ver, i, axis;
+    uint8_t byte;
 
     if (!vih->evdev) {
         error_setg(errp, "evdev property is required");
@@ -126,6 +152,22 @@  static void virtio_input_host_realize(DeviceState *dev, Error **errp)
     virtio_input_bits_config(vih, EV_SW,  SW_CNT);
     virtio_input_bits_config(vih, EV_LED, LED_CNT);
 
+    abs = virtio_input_find_config(VIRTIO_INPUT(vih),
+        VIRTIO_INPUT_CFG_EV_BITS, EV_ABS);
+    if (abs) {
+        for (i = 0; i < abs->size; i++) {
+            byte = abs->u.bitmap[i];
+            axis = 8 * i;
+            while (byte) {
+                if (byte & 1) {
+                    virtio_input_abs_config(vih, axis);
+                }
+                axis++;
+                byte >>= 1;
+            }
+        }
+    }
+
     qemu_set_fd_handler(vih->fd, virtio_input_host_event, NULL, vih);
     return;
 
diff --git a/hw/input/virtio-input.c b/hw/input/virtio-input.c
index 5061f4c..5f036a3 100644
--- a/hw/input/virtio-input.c
+++ b/hw/input/virtio-input.c
@@ -96,9 +96,9 @@  static void virtio_input_handle_sts(VirtIODevice *vdev, VirtQueue *vq)
     virtio_notify(vdev, vinput->sts);
 }
 
-static virtio_input_config *virtio_input_find_config(VirtIOInput *vinput,
-                                                     uint8_t select,
-                                                     uint8_t subsel)
+virtio_input_config *virtio_input_find_config(VirtIOInput *vinput,
+                                              uint8_t select,
+                                              uint8_t subsel)
 {
     VirtIOInputConfig *cfg;
 
diff --git a/include/hw/virtio/virtio-input.h b/include/hw/virtio/virtio-input.h
index af1c207..b4e1b1b 100644
--- a/include/hw/virtio/virtio-input.h
+++ b/include/hw/virtio/virtio-input.h
@@ -111,6 +111,9 @@  struct VirtIOInputHost {
 void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event);
 void virtio_input_init_config(VirtIOInput *vinput,
                               virtio_input_config *config);
+virtio_input_config *virtio_input_find_config(VirtIOInput *vinput,
+                                              uint8_t select,
+                                              uint8_t subsel);
 void virtio_input_add_config(VirtIOInput *vinput,
                              virtio_input_config *config);
 void virtio_input_idstr_config(VirtIOInput *vinput,