From: giwoong.kim Date: Mon, 27 Aug 2012 04:46:57 +0000 (+0900) Subject: [Title] register for virtio touchscreen as input device X-Git-Tag: 2.2.1_release^2~88^2~22 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=311d1c45a082ff38f73d1d88a0aa21ffbf77e91e;p=sdk%2Femulator%2Femulator-kernel.git [Title] register for virtio touchscreen as input device [Type] feature [Module] Emulator / touch [Priority] major [Jira#] [Redmine#] [Problem] [Cause] [Solution] [TestCase] --- diff --git a/drivers/maru/maru_virtio_touchscreen.c b/drivers/maru/maru_virtio_touchscreen.c old mode 100755 new mode 100644 index 2d23fd5fe59d..50acd0fcd930 --- a/drivers/maru/maru_virtio_touchscreen.c +++ b/drivers/maru/maru_virtio_touchscreen.c @@ -32,14 +32,18 @@ #include #include #include +#include #include #include -//#include #include #include #include #include +MODULE_LICENSE("GPL2"); +MODULE_AUTHOR("GiWoong Kim "); +MODULE_DESCRIPTION("Emulator Virtio Touchscreen driver"); + #define DEVICE_NAME "virtio-touchscreen" @@ -53,13 +57,17 @@ typedef struct virtio_touchscreen { struct virtio_device *vdev; struct virtqueue *vq; + struct input_dev *idev; /* The thread servicing the touchscreen */ - struct task_struct *thread; + struct task_struct *thread; } virtio_touchscreen; #define MAX_TRKID 6 +#define TOUCHSCREEN_RESOLUTION_X 5040 +#define TOUCHSCREEN_RESOLUTION_Y 3780 +#define ABS_PRESSURE_MAX 255 static struct virtio_device_id id_table[] = { @@ -67,48 +75,66 @@ static struct virtio_device_id id_table[] = { { 0 }, }; +/** + * @brief : event polling + */ static int run_touchscreen(void *_vtouchscreen) { - virtio_touchscreen *vt = _vtouchscreen; - int count = 0; - + virtio_touchscreen *vt = NULL; + EmulTouchState *vbuf = NULL; + EmulTouchState *event = NULL; struct scatterlist sg; - EmulTouchState *touch = NULL; - EmulTouchState *buf = kzalloc(sizeof(EmulTouchState), GFP_KERNEL); - buf->x = MAX_TRKID; + int count = 0; // remaining capacity of queue + + struct input_dev *input_dev = NULL; + + vt = _vtouchscreen; + vbuf = kzalloc(sizeof(EmulTouchState), GFP_KERNEL); + vbuf->x = MAX_TRKID; // max touch point + + input_dev = vt->idev; while (!kthread_should_stop()) { - /* publish the real size of the buffer */ - sg_init_one(&sg, buf, sizeof(EmulTouchState)); + sg_init_one(&sg, vbuf, sizeof(EmulTouchState)); - if (virtqueue_add_buf(vt->vq, &sg, 0, 1, (void*)buf, GFP_ATOMIC) >= 0) { + if (virtqueue_add_buf(vt->vq, &sg, 0, 1, (void*)vbuf, GFP_ATOMIC) >= 0) { virtqueue_kick(vt->vq); - while (!(touch = virtqueue_get_buf(vt->vq, &count))) { + while (!(event = 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 "touch x=%d, y=%d, z=%d, state=%d\n", event->x, event->y, event->z, event->state); + + if (event->state != 0) { // pressed + input_report_abs(input_dev, ABS_MT_TRACKING_ID, event->z); + input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, 10); + input_report_abs(input_dev, ABS_MT_POSITION_X, event->x); + input_report_abs(input_dev, ABS_MT_POSITION_Y, event->y); + input_mt_sync(input_dev); + } else { // released + input_report_abs(input_dev, ABS_MT_TRACKING_ID, event->z); + input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, 0); + input_mt_sync(input_dev); } - printk(KERN_INFO "virtio touchscreen remaining capacity of queue = %d\n", count); + input_sync(input_dev); } } - printk(KERN_INFO "stop run_touchscreen\n"); - kfree(buf); + printk(KERN_INFO "virtio touchscreen thread is stopped\n"); + kfree(vbuf); return 0; } +#if 0 static void vq_touchscreen_callback(struct virtqueue *vq) { printk(KERN_INFO "vq touchscreen callback\n"); } +#endif static int virtio_touchscreen_open(struct inode *inode, struct file *file) { @@ -122,77 +148,116 @@ static int virtio_touchscreen_release(struct inode *inode, struct file *file) return 0; } +static int input_touchscreen_open(struct input_dev *dev) +{ + printk(KERN_INFO "input touchscreen device is opened\n"); + return 0; +} + +static void input_touchscreen_close(struct input_dev *dev) +{ + printk(KERN_INFO "input touchscreen device is closed\n"); +} + struct file_operations virtio_touchscreen_fops = { .owner = THIS_MODULE, - .write = NULL, - .mmap = NULL, .open = virtio_touchscreen_open, .release = virtio_touchscreen_release, }; -static struct miscdevice virtio_touchscreen_dev = { - .minor = MISC_DYNAMIC_MINOR, - .name = DEVICE_NAME, - .fops = &virtio_touchscreen_fops, -}; - static int virtio_touchscreen_probe(struct virtio_device *vdev) { - struct virtio_touchscreen *vt; + struct virtio_touchscreen *vt = NULL; int ret = 0; - printk(KERN_INFO "virtio touchscreen driver is probed.\n"); + printk(KERN_INFO "virtio touchscreen driver is probed\n"); + /* init virtio */ vdev->priv = vt = kmalloc(sizeof(*vt), GFP_KERNEL); if (!vt) { - return -ENOMEM; - } + 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 = PTR_ERR(vt->vq); + goto fail1; } - ret = misc_register(&virtio_touchscreen_dev); - if (ret) { - printk(KERN_ERR "virtio touchscreen cannot register device as misc\n"); - return -ENODEV; + //vt->vq->callback = vq_touchscreen_callback; + //virtqueue_enable_cb(vt->vq); + + /* register for input device */ + vt->idev = input_allocate_device(); + if (!vt->idev) { + printk(KERN_ERR "failed to allocate a input touchscreen device\n"); + ret = -1; + goto fail1; } + vt->idev->name = "Maru Virtio Touchscreen"; + vt->idev->dev.parent = &(vdev->dev); + + input_set_drvdata(vt->idev, vt); + vt->idev->open = input_touchscreen_open; + vt->idev->close = input_touchscreen_close; - // TODO: - vt->vq->callback = vq_touchscreen_callback; - virtqueue_enable_cb(vt->vq); + vt->idev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + vt->idev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); + vt->idev->keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH); - /* thread */ + input_set_abs_params(vt->idev, ABS_X, 0, TOUCHSCREEN_RESOLUTION_X, 4, 0); + input_set_abs_params(vt->idev, ABS_Y, 0, TOUCHSCREEN_RESOLUTION_Y, 4, 0); + input_set_abs_params(vt->idev, ABS_MT_TRACKING_ID, 0, MAX_TRKID, 0, 0); + input_set_abs_params(vt->idev, ABS_MT_TOUCH_MAJOR, 0, ABS_PRESSURE_MAX, 0, 0); + input_set_abs_params(vt->idev, ABS_MT_POSITION_X, 0, TOUCHSCREEN_RESOLUTION_X, 0, 0); + input_set_abs_params(vt->idev, ABS_MT_POSITION_Y, 0, TOUCHSCREEN_RESOLUTION_Y, 0, 0); + + ret = input_register_device(vt->idev); + if (ret) { + printk(KERN_ERR "input touchscreen driver cannot registered\n"); + ret = -1; + goto fail2; + } + + /* Responses from the hypervisor occur through the get_buf function */ vt->thread = kthread_run(run_touchscreen, vt, "vtouchscreen"); if (IS_ERR(vt->thread)) { - return PTR_ERR(vt->thread); - } - + printk(KERN_ERR "unable to start the virtio touchscreen thread\n"); + ret = PTR_ERR(vt->thread); + goto fail3; + } return 0; + +fail3: input_unregister_device(vt->idev); +fail2: input_free_device(vt->idev); +fail1: kfree(vt); + vdev->priv = NULL; + + return ret; } static void __devexit virtio_touchscreen_remove(struct virtio_device *vdev) { - virtio_touchscreen *vt; + virtio_touchscreen *vt = NULL; - printk(KERN_INFO "virtio touchscreen driver is removed.\n"); + 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); } +MODULE_DEVICE_TABLE(virtio, id_table); + static struct virtio_driver virtio_touchscreen_driver = { //.feature_table = features, //.feature_table_size = ARRAY_SIZE(features), @@ -200,9 +265,9 @@ static struct virtio_driver virtio_touchscreen_driver = { .driver.owner = THIS_MODULE, .id_table = id_table, .probe = virtio_touchscreen_probe, - .remove = virtio_touchscreen_remove, + .remove = __devexit_p(virtio_touchscreen_remove), #if 0 - .config_changed = virtballoon_changed, + .config_changed = #ifdef CONFIG_PM .freeze = .restore = @@ -212,20 +277,16 @@ static struct virtio_driver virtio_touchscreen_driver = { static int __init virtio_touchscreen_init(void) { - printk(KERN_INFO "virtio touchscreen device is initialized.\n"); + printk(KERN_INFO "virtio touchscreen device is initialized\n"); return register_virtio_driver(&virtio_touchscreen_driver); } static void __exit virtio_touchscreen_exit(void) { - printk(KERN_INFO "virtio touchscreen device is destroyed.\n"); + printk(KERN_INFO "virtio touchscreen device is destroyed\n"); unregister_virtio_driver(&virtio_touchscreen_driver); } module_init(virtio_touchscreen_init); module_exit(virtio_touchscreen_exit); -MODULE_DEVICE_TABLE(virtio, id_table); -MODULE_AUTHOR("GiWoong Kim "); -MODULE_DESCRIPTION("Emulator Virtio Touchscreen driver"); -MODULE_LICENSE("GPL2");