hwkey: added virtio hwkey driver
authorsungmin ha <sungmin82.ha@samsung.com>
Wed, 20 Mar 2013 03:22:51 +0000 (12:22 +0900)
committersungmin ha <sungmin82.ha@samsung.com>
Wed, 20 Mar 2013 03:22:51 +0000 (12:22 +0900)
improve hwkey mapping

Signed-off-by: Sungmin Ha <sungmin82.ha@samsung.com>
arch/x86/configs/i386_tizen_emul_defconfig
drivers/maru/Kconfig
drivers/maru/Makefile
drivers/maru/maru_virtio_hwkey.c [new file with mode: 0644]
include/linux/virtio_ids.h
package/changelog
package/pkginfo.manifest

index 21567ce4241861a4d19b18e133c611cc630d2221..2b774cddc96a7eff0ed135acb4ea3109eae21a33 100644 (file)
@@ -2769,6 +2769,7 @@ CONFIG_MARU_LCD=y
 CONFIG_MARU_CODEC=y
 CONFIG_MARU_TOUCHSCREEN=y
 CONFIG_MARU_VIRTIO_TOUCHSCREEN=y
+CONFIG_MARU_VIRTIO_HWKEY=y
 CONFIG_MARU_FB=y
 CONFIG_MARU_CAMERA=y
 CONFIG_MARU_BACKLIGHT=y
index 1bd2a62f955d426c9bf753d3863b42442740cb07..6f959334ea812eaab56e81154d353ed68e98b003 100644 (file)
@@ -18,6 +18,10 @@ config MARU_VIRTIO_TOUCHSCREEN
        tristate "MARU Virtio Touchscreen Driver"
        depends on MARU != n
 
+config MARU_VIRTIO_HWKEY
+       tristate "MARU Virtio Hwkey Driver"
+       depends on MARU != n
+
 config MARU_FB
        tristate "MARU framebuffer driver"
        depends on MARU != n
index 6fac6dc1a6e14a4ceacce2a4e73439bd221c11b8..01700ce335f9f837f545f3e03b5ffa282d314839 100644 (file)
@@ -2,6 +2,7 @@ obj-$(CONFIG_MARU_LCD) += maru_lcd.o
 obj-$(CONFIG_MARU_CODEC) += maru_codec.o
 obj-$(CONFIG_MARU_TOUCHSCREEN) += maru_usb_touchscreen.o
 obj-$(CONFIG_MARU_VIRTIO_TOUCHSCREEN) += maru_virtio_touchscreen.o
+obj-$(CONFIG_MARU_VIRTIO_HWKEY) += maru_virtio_hwkey.o
 obj-$(CONFIG_MARU_FB) += maru_fb.o
 obj-$(CONFIG_MARU_CAMERA) += maru_camera.o
 obj-$(CONFIG_MARU_BACKLIGHT) += maru_bl.o
diff --git a/drivers/maru/maru_virtio_hwkey.c b/drivers/maru/maru_virtio_hwkey.c
new file mode 100644 (file)
index 0000000..937f860
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ * Maru Virtio Hwkey Device Driver
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ *  Sungmin Ha <sungmin82.ha@samsung.com>
+ *  Sangjin Kim <sangjin3.kim@samsung.com>
+ *  YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/input.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <linux/virtio.h>
+#include <linux/virtio_ids.h>
+#include <linux/virtio_config.h>
+#include <linux/kthread.h>
+
+MODULE_LICENSE("GPL2");
+MODULE_AUTHOR("Sungmin Ha <sungmin82.ha@samsung.com>");
+MODULE_DESCRIPTION("Emulator Virtio Hwkey driver");
+
+#define DEVICE_NAME "virtio-hwkey"
+
+/* This structure must match the qemu definitions */
+typedef struct EmulHwkeyEvent {
+    uint8_t event_type;
+    uint32_t keycode;
+} EmulHwkeyEvent;
+static EmulHwkeyEvent *event;
+
+typedef struct virtio_hwkey
+{
+    struct virtio_device *vdev;
+    struct virtqueue *vq;
+    struct input_dev *idev;
+} virtio_hwkey;
+virtio_hwkey *vh;
+
+static struct virtio_device_id id_table[] = {
+    { VIRTIO_ID_HWKEY, VIRTIO_DEV_ANY_ID },
+    { 0 },
+};
+
+#define MAX_BUF_COUNT 10
+static struct scatterlist sg[MAX_BUF_COUNT];
+static EmulHwkeyEvent vbuf[MAX_BUF_COUNT];
+
+/* keep it consistent with emulator-skin definition */
+enum {  
+    KEY_PRESSED = 1,
+    KEY_RELEASED = 2,
+};
+
+static int err = 0;
+static unsigned int len = 0; /* not used */
+static unsigned int index = 0;
+static unsigned int recv_index = 0;
+
+/**
+* @brief : callback for virtqueue
+*/
+static void vq_hwkey_callback(struct virtqueue *vq)
+{
+#if 0
+    printk(KERN_INFO "vq hwkey callback\n");
+#endif
+
+    recv_index = (unsigned int)virtqueue_get_buf(vh->vq, &len);
+    if (recv_index == 0) {
+        printk(KERN_ERR "failed to get buffer\n");
+        return;
+    }
+
+    do {
+        event = &vbuf[recv_index - 1];
+#if 0
+        printk(KERN_INFO "hwkey event_type=%d, keycodey=%d, recv_index=%d\n",
+            event->event_type, event->keycode, recv_index);
+#endif
+        if (event->event_type == KEY_PRESSED) { /* pressed */
+          input_event(vh->idev, EV_KEY, event->keycode, true);
+        }
+        else if (event->event_type == KEY_RELEASED) { /* released */
+          input_event(vh->idev, EV_KEY, event->keycode, false);
+        }
+        else {
+          printk(KERN_ERR "Unknown event type\n");
+          return;
+        }
+
+        input_sync(vh->idev);
+
+        /* expose buffer to other end */
+        err = virtqueue_add_buf(vh->vq, sg, 0,
+            recv_index, (void *)recv_index, GFP_ATOMIC);
+
+        if (err < 0) {
+            printk(KERN_ERR "failed to add buffer!\n");
+        }
+
+        recv_index = (unsigned int)virtqueue_get_buf(vh->vq, &len);
+        if (recv_index == 0) {
+            break;
+        }
+    } while(true);
+
+    virtqueue_kick(vh->vq);
+}
+
+static int virtio_hwkey_open(struct inode *inode, struct file *file)
+{
+    printk(KERN_INFO "virtio hwkey device is opened\n");
+    return 0;
+}
+
+static int virtio_hwkey_release(struct inode *inode, struct file *file)
+{
+    printk(KERN_INFO "virtio hwkey device is closed\n");
+    return 0;
+}
+
+static int input_hwkey_open(struct input_dev *dev)
+{
+    printk(KERN_INFO "input hwkey device is opened\n");
+    return 0;
+}
+
+static void input_hwkey_close(struct input_dev *dev)
+{
+    printk(KERN_INFO "input hwkey device is closed\n");
+}
+
+struct file_operations virtio_hwkey_fops = {
+    .owner   = THIS_MODULE,
+    .open    = virtio_hwkey_open,
+    .release = virtio_hwkey_release,
+};
+
+static int virtio_hwkey_probe(struct virtio_device *vdev)
+{
+    int ret = 0;
+
+    printk(KERN_INFO "virtio hwkey driver is probed\n");
+
+    /* init virtio */
+    vdev->priv = vh = kmalloc(sizeof(*vh), GFP_KERNEL);
+    if (!vh) {
+        return -ENOMEM;
+    }
+
+    vh->vdev = vdev;
+
+    vh->vq = virtio_find_single_vq(vh->vdev,
+        vq_hwkey_callback, "virtio-hwkey-vq");
+    if (IS_ERR(vh->vq)) {
+        ret = PTR_ERR(vh->vq);
+
+        kfree(vh);
+        vdev->priv = NULL;
+        return ret;
+    }
+
+    /* enable callback */
+    virtqueue_enable_cb(vh->vq);
+
+    sg_init_table(sg, MAX_BUF_COUNT);
+
+    /* prepare the buffers */
+    for (index = 0; index < MAX_BUF_COUNT; index++) {
+        sg_set_buf(&sg[index], &vbuf[index], sizeof(EmulHwkeyEvent));
+
+        err = virtqueue_add_buf(vh->vq, sg, 0,
+            index + 1, (void *)index + 1, GFP_ATOMIC);
+
+        if (err < 0) {
+            printk(KERN_ERR "failed to add buffer\n");
+
+            kfree(vh);
+            vdev->priv = NULL;
+            return ret;
+        }
+    }
+
+    /* register for input device */
+    vh->idev = input_allocate_device();
+    if (!vh->idev) {
+        printk(KERN_ERR "failed to allocate a input hwkey device\n");
+        ret = -1;
+
+        kfree(vh);
+        vdev->priv = NULL;
+        return ret;
+    }
+
+    vh->idev->name = "Maru Virtio Hwkey";
+    vh->idev->dev.parent = &(vdev->dev);
+
+    input_set_drvdata(vh->idev, vh);
+    vh->idev->open = input_hwkey_open;
+    vh->idev->close = input_hwkey_close;
+
+    vh->idev->evbit[0] = BIT_MASK(EV_KEY);
+    /* to support any keycode */
+    memset(vh->idev->keybit, 0xffffffff, sizeof(unsigned long) * BITS_TO_LONGS(KEY_CNT));
+
+    ret = input_register_device(vh->idev);
+    if (ret) {
+        printk(KERN_ERR "input hwkey driver cannot registered\n");
+        ret = -1;
+
+        input_free_device(vh->idev);
+        kfree(vh);
+        vdev->priv = NULL;
+        return ret;
+    }
+
+    virtqueue_kick(vh->vq);
+    index = 0;
+
+    return 0;
+}
+
+static void __devexit virtio_hwkey_remove(struct virtio_device *vdev)
+{
+    virtio_hwkey *vhk = NULL;
+
+    printk(KERN_INFO "virtio hwkey driver is removed\n");
+
+    vhk = vdev->priv;
+
+    vdev->config->reset(vdev); /* reset device */
+    vdev->config->del_vqs(vdev); /* clean up the queues */
+
+    input_unregister_device(vhk->idev);
+
+    kfree(vhk);
+}
+
+MODULE_DEVICE_TABLE(virtio, id_table);
+
+static struct virtio_driver virtio_hwkey_driver = {
+    .driver.name = KBUILD_MODNAME,
+    .driver.owner = THIS_MODULE,
+    .id_table = id_table,
+    .probe = virtio_hwkey_probe,
+    .remove = __devexit_p(virtio_hwkey_remove),
+};
+
+static int __init virtio_hwkey_init(void)
+{
+    printk(KERN_INFO "virtio hwkey device is initialized\n");
+    return register_virtio_driver(&virtio_hwkey_driver);
+}
+
+static void __exit virtio_hwkey_exit(void)
+{
+    printk(KERN_INFO "virtio hwkey device is destroyed\n");
+    unregister_virtio_driver(&virtio_hwkey_driver);
+}
+
+module_init(virtio_hwkey_init);
+module_exit(virtio_hwkey_exit);
+
index 96975a785b1a1ba3db275bc0a38e17faf4cc6423..f401735b2e331c2f565302ddcfe6dd33f35743f0 100644 (file)
@@ -44,6 +44,7 @@
 #define VIRTIO_ID_TOUCHSCREEN  11 /* virtio touchscreen */
 #define VIRTIO_ID_KEYBOARD     12 /* virtio keyboard */
 #define VIRTIO_ID_ESM          13 /* virtio ESM */
+#define VIRTIO_ID_HWKEY                14 /* virtio hwkey */
 #endif
 
 #endif /* _LINUX_VIRTIO_IDS_H */
index 75c2f054c25dc782f9b67b4b2becedd666f54edc..b2273cf2574c906859fbe6af482b8a88cbcfb700 100644 (file)
@@ -1,3 +1,6 @@
+* 1.4.17
+- added virtio hwkey driver and improved hwkey mapping
+== Sungmin Ha <sungmin82.ha@samsung.com> 2013-03-20
 * 1.4.15
 - source clean-up for overlay and backlight module.
 == Kitae Kim <kt920.kim@samsung.com> 2013-03-08
index 188eb1950030e23fe872db9a621e390dad05cbb6..d1653981bd18a867cf382b3147bc85cd023b3e8c 100644 (file)
@@ -1,4 +1,4 @@
-Version: 1.4.16
+Version: 1.4.17
 Maintainer: Yeong-Kyoon, Lee <yeongkyoon.lee@samsung.com>
 Source: emulator-kernel