From: GiWoong Kim Date: Mon, 23 Mar 2015 12:20:29 +0000 (+0900) Subject: rotary: modified virtual rotary driver X-Git-Tag: submit/tizen/20160422.055611~1^2~55 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ba130a4f3aae2d15d6b1f96e3a5293273a08fefd;p=sdk%2Femulator%2Femulator-kernel.git rotary: modified virtual rotary driver tizen_rotary -> tizen_detent Instead of the delta that the change of the degree, sends up the detent value in every 15 degrees. Change-Id: I1b2b7ea8e4a2ff4ac90626710ddfe7f691ad29e2 Signed-off-by: GiWoong Kim --- diff --git a/drivers/maru/maru_virtio_rotary.c b/drivers/maru/maru_virtio_rotary.c index 762d30dd88e4..70ac0896dfa2 100644 --- a/drivers/maru/maru_virtio_rotary.c +++ b/drivers/maru/maru_virtio_rotary.c @@ -43,7 +43,7 @@ MODULE_LICENSE("GPL2"); MODULE_AUTHOR("Jinhyung Jo "); MODULE_DESCRIPTION("Emulator Virtio Rotary Driver"); -#define DRIVER_NAME "tizen_rotary" +#define DRIVER_NAME "tizen_detent" #define VR_LOG(log_level, fmt, ...) \ printk(log_level "%s: " fmt, DRIVER_NAME, ##__VA_ARGS__) @@ -68,17 +68,39 @@ struct virtio_rotary { struct virtio_rotary *vrtr; +static int last_pos; /* 0 ~ 360 */ +static int last_detent; +static int status; /* 0 ~ 2 */ + static struct virtio_device_id id_table[] = { { VIRTIO_ID_ROTARY, VIRTIO_DEV_ANY_ID }, { 0 }, }; +#define DETENT_UNIT (15) +#define REMAINDER(n,div) ({ \ + typeof(n) _n = (n) % (div); \ + if (_n < 0) { \ + _n += (div); \ + } \ + _n; \ +}) + +static int get_rotary_pos(int value) +{ + return REMAINDER(value, 360); +} + static void vq_rotary_handler(struct virtqueue *vq) { int err = 0, len = 0; void *data; struct rotary_event event; + int i = 0; + int pos = 0; + int value = 0; + data = virtqueue_get_buf(vq, &len); if (!data) { VR_LOG(KERN_ERR, "there is no available buffer\n"); @@ -89,14 +111,61 @@ static void vq_rotary_handler(struct virtqueue *vq) memcpy(&event, &vrtr->event[vqidx], sizeof(struct rotary_event)); - if (event.delta == 0) + + event.delta %= 360; + if (event.delta == 0) { break; + } + + pos = get_rotary_pos(last_pos + event.delta); + VR_LOG(KERN_DEBUG, - "rotary event: vqidx(%d), delta(%d), type(%d)\n", - vqidx, event.delta, event.type); - input_report_rel(vrtr->idev, REL_X, event.delta); - input_report_rel(vrtr->idev, REL_Y, 0); - input_sync(vrtr->idev); + "rotary event: vqidx(%d), event.delta(%d), pos(%d)\n", + vqidx, event.delta, pos); + + if (event.delta > 0) { /* CW */ + for (i = 0; i < event.delta; i++) { + value = last_pos + i; + if ((value % DETENT_UNIT == 0) && (get_rotary_pos(value) != last_detent)) { + status++; + status %= 3; /* 0->1->2->0 .. */ + + last_detent = get_rotary_pos(value); + + VR_LOG(KERN_INFO, + "event: delta(%d), detent(%d), status(%d)\n", + event.delta, last_detent, status); + + input_report_rel(vrtr->idev, REL_X, 0); + input_report_rel(vrtr->idev, REL_Y, 0); + input_report_rel(vrtr->idev, REL_WHEEL, status + 1); + input_sync(vrtr->idev); + } + } + } else { /* CCW */ + for (i = 0; i > event.delta; i--) { + value = last_pos + i; + if ((value % DETENT_UNIT == 0) && (get_rotary_pos(value) != last_detent)) { + status--; + status = REMAINDER(status, 3); /* 0->2->1->0 .. */ + + last_detent = get_rotary_pos(value); + + VR_LOG(KERN_INFO, + "event: delta(%d), detent(%d), status(%d)\n", + event.delta, last_detent, status); + + input_report_rel(vrtr->idev, REL_X, 0); + input_report_rel(vrtr->idev, REL_Y, 0); + input_report_rel(vrtr->idev, REL_WHEEL, status + 1); + input_sync(vrtr->idev); + } + + } + } + + last_pos = pos; + memset(&vrtr->event[vqidx], 0x00, sizeof(struct rotary_event)); @@ -190,11 +259,12 @@ static int virtio_rotary_probe(struct virtio_device *vdev) __set_bit(EV_KEY, vrtr->idev->evbit); __set_bit(REL_X, vrtr->idev->relbit); __set_bit(REL_Y, vrtr->idev->relbit); + __set_bit(REL_WHEEL, vrtr->idev->relbit); __set_bit(BTN_LEFT, vrtr->idev->keybit); input_set_capability(vrtr->idev, EV_REL, REL_X); input_set_capability(vrtr->idev, EV_REL, REL_Y); - input_set_capability(vrtr->idev, EV_REL, REL_Z); + input_set_capability(vrtr->idev, EV_REL, REL_WHEEL); ret = input_register_device(vrtr->idev); if (ret) {