[Title] init the virtio touchscreen driver
authorgiwoong.kim <giwoong.kim@samsung.com>
Mon, 20 Aug 2012 12:55:22 +0000 (21:55 +0900)
committergiwoong.kim <giwoong.kim@samsung.com>
Wed, 22 Aug 2012 12:58:31 +0000 (21:58 +0900)
[Type] feature
[Module] Emulator / touch
[Priority] major
[Jira#]
[Redmine#]
[Problem]
[Cause]
[Solution]
[TestCase]

arch/x86/configs/i386_emul_defconfig
drivers/maru/Kconfig
drivers/maru/Makefile
drivers/maru/maru_virtio_touchscreen.c [changed mode: 0644->0755]

index 9b8b839bc13e57d624095ff0112327a08c132ebc..6f1af114c162310209fd788134a45221d85c61ce 100644 (file)
@@ -2765,6 +2765,7 @@ CONFIG_MARU=y
 CONFIG_MARU_LCD=y
 CONFIG_MARU_CODEC=y
 CONFIG_MARU_TOUCHSCREEN=y
+CONFIG_MARU_VIRTIO_TOUCHSCREEN=y
 CONFIG_MARU_FB=y
 CONFIG_MARU_CAMERA=y
 CONFIG_MARU_BACKLIGHT=y
index 78e48f432dcce08b35c5b0fa158214600822d3f7..8313e4e23f2404daa53510d96b7902b85127d2c4 100644 (file)
@@ -11,7 +11,11 @@ config MARU_CODEC
        depends on MARU != n
 
 config MARU_TOUCHSCREEN
-       tristate "MARU touchscreen driver"
+       tristate "MARU USB Touchscreen Driver"
+       depends on MARU != n
+
+config MARU_VIRTIO_TOUCHSCREEN
+       tristate "MARU Virtio Touchscreen Driver"
        depends on MARU != n
 
 config MARU_FB
index 3b4c39beb183c6dfa38430cadc03d96659f28799..ddce2ecdf02b2fb3a9a3ec85789bf7ef8a023c99 100644 (file)
@@ -1,6 +1,7 @@
 obj-$(CONFIG_MARU_LCD) += maru_lcd.o
 obj-$(CONFIG_MARU_CODEC) += maru_codec.o
 obj-$(CONFIG_MARU_TOUCHSCREEN) += maru_touchscreen.o
+obj-$(CONFIG_MARU_VIRTIO_TOUCHSCREEN) += maru_virtio_touchscreen.o
 obj-$(CONFIG_MARU_FB) += maru_fb.o
 obj-$(CONFIG_MARU_CAMERA) += maru_camera.o
 obj-$(CONFIG_MARU_BACKLIGHT) += maru_bl.o
old mode 100644 (file)
new mode 100755 (executable)
index 822e2b0..d214e17
@@ -38,6 +38,7 @@
 #include <linux/virtio.h>
 #include <linux/virtio_ids.h>
 #include <linux/virtio_config.h>
+#include <linux/kthread.h>
 
 
 #define DEVICE_NAME "virtio-touchscreen"
@@ -48,14 +49,62 @@ typedef struct EmulTouchState {
     uint8_t state;
 } EmulTouchState;
 
+typedef struct virtio_touchscreen
+{
+    struct virtio_device *vdev;
+    struct virtqueue *vq;
+
+    /* The thread servicing the touchscreen */
+       struct task_struct *thread;
+} virtio_touchscreen;
+
+
+#define MAX_TRKID 6
 
-static struct virtqueue *vq = NULL;
 
 static struct virtio_device_id id_table[] = {
     { VIRTIO_ID_TOUCHSCREEN, VIRTIO_DEV_ANY_ID },
     { 0 },
 };
 
+static int run_touchscreen(void *_vtouchscreen)
+{
+       virtio_touchscreen *vt = _vtouchscreen;
+    int count = 0;
+
+    struct scatterlist sg;
+    EmulTouchState *touch = NULL;
+    EmulTouchState *buf = kzalloc(sizeof(EmulTouchState), GFP_KERNEL);
+    buf->x = MAX_TRKID;
+
+    while (!kthread_should_stop()) {
+        /* publish the real size of the buffer */
+        sg_init_one(&sg, buf, sizeof(EmulTouchState));
+
+        if (virtqueue_add_buf(vt->vq, &sg, 0, 1, (void*)buf, GFP_ATOMIC) >= 0) {
+            virtqueue_kick(vt->vq);
+
+            while (!(touch = virtqueue_get_buf(vt->vq, &count))) {
+                cpu_relax();
+            }
+
+            if (touch == NULL) {
+                printk(KERN_INFO "touch is null\n");
+            } else {
+                printk(KERN_INFO "x=%d, y=%d, z=%d, state=%d\n", touch->x, touch->y, touch->z, touch->state);
+            }
+
+            printk(KERN_INFO "virtio touchscreen remaining capacity of queue = %d\n", count);
+        }
+
+    }
+
+    printk(KERN_INFO "stop run_touchscreen\n");
+    kfree(buf);
+
+    return 0;
+}
+
 static void vq_touchscreen_callback(struct virtqueue *vq)
 {
     printk(KERN_INFO "vq touchscreen callback\n");
@@ -89,13 +138,21 @@ static struct miscdevice virtio_touchscreen_dev = {
 
 static int virtio_touchscreen_probe(struct virtio_device *vdev)
 {
+    struct virtio_touchscreen *vt;
     int ret = 0;
 
     printk(KERN_INFO "virtio touchscreen driver is probed.\n");
 
-    vq = virtio_find_single_vq(vdev, NULL, "virtio-touchscreen-vq");
-    if (IS_ERR(vq)) {
-        return PTR_ERR(vq);
+    vdev->priv = vt = kmalloc(sizeof(*vt), GFP_KERNEL);
+    if (!vt) {
+               return -ENOMEM;
+       }
+
+    vt->vdev = vdev;
+
+    vt->vq = virtio_find_single_vq(vt->vdev, NULL, "virtio-touchscreen-vq");
+    if (IS_ERR(vt->vq)) {
+        return PTR_ERR(vt->vq);
     }
 
     ret = misc_register(&virtio_touchscreen_dev);
@@ -105,28 +162,36 @@ static int virtio_touchscreen_probe(struct virtio_device *vdev)
     }
 
 
-    // temp
-    vq->callback = vq_touchscreen_callback;
+    // TODO:
+    vt->vq->callback = vq_touchscreen_callback;
+    virtqueue_enable_cb(vt->vq);
+
+    /* thread */
+    vt->thread = kthread_run(run_touchscreen, vt, "vtouchscreen");
+    if (IS_ERR(vt->thread)) {
+        kfree(vt);
+               return PTR_ERR(vt->thread);
+       }
 
-    /* Transfer data */
-#if 0
-    if (virtqueue_add_buf(vq, sg_list, out_page, in_page, (void*)1, GFP_ATOMIC) >= 0) {
-        while (!virtqueue_get_buf(vq, &count)) {
-            cpu_relax();
-        }
-    }
-#endif
 
     return 0;
 }
 
 static void __devexit virtio_touchscreen_remove(struct virtio_device *vdev)
 {
+    virtio_touchscreen *vt;
+
     printk(KERN_INFO "virtio touchscreen driver is removed.\n");
 
+    vt = vdev->priv;
+
+    kthread_stop(vt->thread);
+
     vdev->config->reset(vdev); // reset device
     misc_deregister(&virtio_touchscreen_dev);
     vdev->config->del_vqs(vdev); // clean up the queues
+
+    kfree(vt);
 }
 
 static struct virtio_driver virtio_touchscreen_driver = {