Lines Matching +full:wake +full:- +full:on +full:- +full:motion
1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (c) 1999-2002 Vojtech Pavlik
119 #define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03])
120 #define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03])
134 if (mousedev->touch && mousedev->pkt_count >= 2) { in mousedev_touchpad_event()
135 size = input_abs_get_max(dev, ABS_X) - in mousedev_touchpad_event()
140 tmp = ((value - fx(2)) * 256 * FRACTION_DENOM) / size; in mousedev_touchpad_event()
141 tmp += mousedev->frac_dx; in mousedev_touchpad_event()
142 mousedev->packet.dx = tmp / FRACTION_DENOM; in mousedev_touchpad_event()
143 mousedev->frac_dx = in mousedev_touchpad_event()
144 tmp - mousedev->packet.dx * FRACTION_DENOM; in mousedev_touchpad_event()
150 if (mousedev->touch && mousedev->pkt_count >= 2) { in mousedev_touchpad_event()
152 size = input_abs_get_max(dev, ABS_X) - in mousedev_touchpad_event()
157 tmp = -((value - fy(2)) * 256 * FRACTION_DENOM) / size; in mousedev_touchpad_event()
158 tmp += mousedev->frac_dy; in mousedev_touchpad_event()
159 mousedev->packet.dy = tmp / FRACTION_DENOM; in mousedev_touchpad_event()
160 mousedev->frac_dy = tmp - in mousedev_touchpad_event()
161 mousedev->packet.dy * FRACTION_DENOM; in mousedev_touchpad_event()
178 size = max - min; in mousedev_abs_event()
184 mousedev->packet.x = ((value - min) * xres) / size; in mousedev_abs_event()
185 mousedev->packet.abs_event = 1; in mousedev_abs_event()
192 size = max - min; in mousedev_abs_event()
198 mousedev->packet.y = yres - ((value - min) * yres) / size; in mousedev_abs_event()
199 mousedev->packet.abs_event = 1; in mousedev_abs_event()
209 mousedev->packet.dx += value; in mousedev_rel_event()
213 mousedev->packet.dy -= value; in mousedev_rel_event()
217 mousedev->packet.dz -= value; in mousedev_rel_event()
253 set_bit(index, &mousedev->packet.buttons); in mousedev_key_event()
254 set_bit(index, &mousedev_mix->packet.buttons); in mousedev_key_event()
256 clear_bit(index, &mousedev->packet.buttons); in mousedev_key_event()
257 clear_bit(index, &mousedev_mix->packet.buttons); in mousedev_key_event()
270 list_for_each_entry_rcu(client, &mousedev->client_list, node) { in mousedev_notify_readers()
273 spin_lock(&client->packet_lock); in mousedev_notify_readers()
275 p = &client->packets[client->head]; in mousedev_notify_readers()
276 if (client->ready && p->buttons != mousedev->packet.buttons) { in mousedev_notify_readers()
277 new_head = (client->head + 1) % PACKET_QUEUE_LEN; in mousedev_notify_readers()
278 if (new_head != client->tail) { in mousedev_notify_readers()
279 p = &client->packets[client->head = new_head]; in mousedev_notify_readers()
284 if (packet->abs_event) { in mousedev_notify_readers()
285 p->dx += packet->x - client->pos_x; in mousedev_notify_readers()
286 p->dy += packet->y - client->pos_y; in mousedev_notify_readers()
287 client->pos_x = packet->x; in mousedev_notify_readers()
288 client->pos_y = packet->y; in mousedev_notify_readers()
291 client->pos_x += packet->dx; in mousedev_notify_readers()
292 client->pos_x = clamp_val(client->pos_x, 0, xres); in mousedev_notify_readers()
294 client->pos_y += packet->dy; in mousedev_notify_readers()
295 client->pos_y = clamp_val(client->pos_y, 0, yres); in mousedev_notify_readers()
297 p->dx += packet->dx; in mousedev_notify_readers()
298 p->dy += packet->dy; in mousedev_notify_readers()
299 p->dz += packet->dz; in mousedev_notify_readers()
300 p->buttons = mousedev->packet.buttons; in mousedev_notify_readers()
302 if (p->dx || p->dy || p->dz || in mousedev_notify_readers()
303 p->buttons != client->last_buttons) in mousedev_notify_readers()
304 client->ready = 1; in mousedev_notify_readers()
306 spin_unlock(&client->packet_lock); in mousedev_notify_readers()
308 if (client->ready) { in mousedev_notify_readers()
309 kill_fasync(&client->fasync, SIGIO, POLL_IN); in mousedev_notify_readers()
316 wake_up_interruptible(&mousedev->wait); in mousedev_notify_readers()
322 if (mousedev->touch && in mousedev_touchpad_touch()
324 mousedev->touch + msecs_to_jiffies(tap_time))) { in mousedev_touchpad_touch()
327 * We rely on the fact that mousedev_mix always has 0 in mousedev_touchpad_touch()
328 * motion packet so we won't mess current position. in mousedev_touchpad_touch()
330 set_bit(0, &mousedev->packet.buttons); in mousedev_touchpad_touch()
331 set_bit(0, &mousedev_mix->packet.buttons); in mousedev_touchpad_touch()
332 mousedev_notify_readers(mousedev, &mousedev_mix->packet); in mousedev_touchpad_touch()
334 &mousedev_mix->packet); in mousedev_touchpad_touch()
335 clear_bit(0, &mousedev->packet.buttons); in mousedev_touchpad_touch()
336 clear_bit(0, &mousedev_mix->packet.buttons); in mousedev_touchpad_touch()
338 mousedev->touch = mousedev->pkt_count = 0; in mousedev_touchpad_touch()
339 mousedev->frac_dx = 0; in mousedev_touchpad_touch()
340 mousedev->frac_dy = 0; in mousedev_touchpad_touch()
342 } else if (!mousedev->touch) in mousedev_touchpad_touch()
343 mousedev->touch = jiffies; in mousedev_touchpad_touch()
349 struct mousedev *mousedev = handle->private; in mousedev_event()
355 if (test_bit(BTN_TRIGGER, handle->dev->keybit)) in mousedev_event()
358 if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) in mousedev_event()
359 mousedev_touchpad_event(handle->dev, in mousedev_event()
362 mousedev_abs_event(handle->dev, mousedev, code, value); in mousedev_event()
373 test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) in mousedev_event()
382 if (mousedev->touch) { in mousedev_event()
383 mousedev->pkt_count++; in mousedev_event()
393 mousedev_notify_readers(mousedev, &mousedev->packet); in mousedev_event()
394 mousedev_notify_readers(mousedev_mix, &mousedev->packet); in mousedev_event()
396 mousedev->packet.dx = mousedev->packet.dy = in mousedev_event()
397 mousedev->packet.dz = 0; in mousedev_event()
398 mousedev->packet.abs_event = 0; in mousedev_event()
404 static int mousedev_fasync(int fd, struct file *file, int on) in mousedev_fasync() argument
406 struct mousedev_client *client = file->private_data; in mousedev_fasync()
408 return fasync_helper(fd, file, on, &client->fasync); in mousedev_fasync()
415 input_put_device(mousedev->handle.dev); in mousedev_free()
423 retval = mutex_lock_interruptible(&mousedev->mutex); in mousedev_open_device()
427 if (!mousedev->exist) in mousedev_open_device()
428 retval = -ENODEV; in mousedev_open_device()
429 else if (!mousedev->open++) { in mousedev_open_device()
430 retval = input_open_device(&mousedev->handle); in mousedev_open_device()
432 mousedev->open--; in mousedev_open_device()
435 mutex_unlock(&mousedev->mutex); in mousedev_open_device()
441 mutex_lock(&mousedev->mutex); in mousedev_close_device()
443 if (mousedev->exist && !--mousedev->open) in mousedev_close_device()
444 input_close_device(&mousedev->handle); in mousedev_close_device()
446 mutex_unlock(&mousedev->mutex); in mousedev_close_device()
451 * stream. Note that this function is called with mousedev_mix->mutex
458 error = mutex_lock_interruptible(&mixdev->mutex); in mixdev_open_devices()
462 if (!mixdev->open++) { in mixdev_open_devices()
466 if (!mousedev->opened_by_mixdev) { in mixdev_open_devices()
470 mousedev->opened_by_mixdev = true; in mixdev_open_devices()
475 mutex_unlock(&mixdev->mutex); in mixdev_open_devices()
481 * device. Note that this function is called with mousedev_mix->mutex
486 mutex_lock(&mixdev->mutex); in mixdev_close_devices()
488 if (!--mixdev->open) { in mixdev_close_devices()
492 if (mousedev->opened_by_mixdev) { in mixdev_close_devices()
493 mousedev->opened_by_mixdev = false; in mixdev_close_devices()
499 mutex_unlock(&mixdev->mutex); in mixdev_close_devices()
506 spin_lock(&mousedev->client_lock); in mousedev_attach_client()
507 list_add_tail_rcu(&client->node, &mousedev->client_list); in mousedev_attach_client()
508 spin_unlock(&mousedev->client_lock); in mousedev_attach_client()
514 spin_lock(&mousedev->client_lock); in mousedev_detach_client()
515 list_del_rcu(&client->node); in mousedev_detach_client()
516 spin_unlock(&mousedev->client_lock); in mousedev_detach_client()
522 struct mousedev_client *client = file->private_data; in mousedev_release()
523 struct mousedev *mousedev = client->mousedev; in mousedev_release()
528 mousedev->close_device(mousedev); in mousedev_release()
544 mousedev = container_of(inode->i_cdev, struct mousedev, cdev); in mousedev_open()
548 return -ENOMEM; in mousedev_open()
550 spin_lock_init(&client->packet_lock); in mousedev_open()
551 client->pos_x = xres / 2; in mousedev_open()
552 client->pos_y = yres / 2; in mousedev_open()
553 client->mousedev = mousedev; in mousedev_open()
556 error = mousedev->open_device(mousedev); in mousedev_open()
560 file->private_data = client; in mousedev_open()
573 struct mousedev_motion *p = &client->packets[client->tail]; in mousedev_packet()
576 dx = clamp_val(p->dx, -127, 127); in mousedev_packet()
577 p->dx -= dx; in mousedev_packet()
579 dy = clamp_val(p->dy, -127, 127); in mousedev_packet()
580 p->dy -= dy; in mousedev_packet()
584 ps2_data[0] |= p->buttons & 0x07; in mousedev_packet()
588 switch (client->mode) { in mousedev_packet()
590 dz = clamp_val(p->dz, -7, 7); in mousedev_packet()
591 p->dz -= dz; in mousedev_packet()
593 ps2_data[3] = (dz & 0x0f) | ((p->buttons & 0x18) << 1); in mousedev_packet()
594 client->bufsiz = 4; in mousedev_packet()
598 dz = clamp_val(p->dz, -127, 127); in mousedev_packet()
599 p->dz -= dz; in mousedev_packet()
601 ps2_data[0] |= ((p->buttons & 0x10) >> 3) | in mousedev_packet()
602 ((p->buttons & 0x08) >> 1); in mousedev_packet()
605 client->bufsiz = 4; in mousedev_packet()
610 p->dz = 0; in mousedev_packet()
612 ps2_data[0] |= ((p->buttons & 0x10) >> 3) | in mousedev_packet()
613 ((p->buttons & 0x08) >> 1); in mousedev_packet()
615 client->bufsiz = 3; in mousedev_packet()
619 if (!p->dx && !p->dy && !p->dz) { in mousedev_packet()
620 if (client->tail == client->head) { in mousedev_packet()
621 client->ready = 0; in mousedev_packet()
622 client->last_buttons = p->buttons; in mousedev_packet()
624 client->tail = (client->tail + 1) % PACKET_QUEUE_LEN; in mousedev_packet()
631 client->ps2[0] = 0xfa; /* ACK */ in mousedev_generate_response()
636 mousedev_packet(client, &client->ps2[1]); in mousedev_generate_response()
637 client->bufsiz++; /* account for leading ACK */ in mousedev_generate_response()
641 switch (client->mode) { in mousedev_generate_response()
643 client->ps2[1] = 0; in mousedev_generate_response()
646 client->ps2[1] = 3; in mousedev_generate_response()
649 client->ps2[1] = 4; in mousedev_generate_response()
652 client->bufsiz = 2; in mousedev_generate_response()
656 client->ps2[1] = 0x60; client->ps2[2] = 3; client->ps2[3] = 200; in mousedev_generate_response()
657 client->bufsiz = 4; in mousedev_generate_response()
661 client->impsseq = client->imexseq = 0; in mousedev_generate_response()
662 client->mode = MOUSEDEV_EMUL_PS2; in mousedev_generate_response()
663 client->ps2[1] = 0xaa; client->ps2[2] = 0x00; in mousedev_generate_response()
664 client->bufsiz = 3; in mousedev_generate_response()
668 client->bufsiz = 1; in mousedev_generate_response()
671 client->buffer = client->bufsiz; in mousedev_generate_response()
677 struct mousedev_client *client = file->private_data; in mousedev_write()
684 return -EFAULT; in mousedev_write()
686 spin_lock_irq(&client->packet_lock); in mousedev_write()
688 if (c == mousedev_imex_seq[client->imexseq]) { in mousedev_write()
689 if (++client->imexseq == MOUSEDEV_SEQ_LEN) { in mousedev_write()
690 client->imexseq = 0; in mousedev_write()
691 client->mode = MOUSEDEV_EMUL_EXPS; in mousedev_write()
694 client->imexseq = 0; in mousedev_write()
696 if (c == mousedev_imps_seq[client->impsseq]) { in mousedev_write()
697 if (++client->impsseq == MOUSEDEV_SEQ_LEN) { in mousedev_write()
698 client->impsseq = 0; in mousedev_write()
699 client->mode = MOUSEDEV_EMUL_IMPS; in mousedev_write()
702 client->impsseq = 0; in mousedev_write()
706 spin_unlock_irq(&client->packet_lock); in mousedev_write()
710 kill_fasync(&client->fasync, SIGIO, POLL_IN); in mousedev_write()
711 wake_up_interruptible(&client->mousedev->wait); in mousedev_write()
719 struct mousedev_client *client = file->private_data; in mousedev_read()
720 struct mousedev *mousedev = client->mousedev; in mousedev_read()
721 u8 data[sizeof(client->ps2)]; in mousedev_read()
724 if (!client->ready && !client->buffer && mousedev->exist && in mousedev_read()
725 (file->f_flags & O_NONBLOCK)) in mousedev_read()
726 return -EAGAIN; in mousedev_read()
728 retval = wait_event_interruptible(mousedev->wait, in mousedev_read()
729 !mousedev->exist || client->ready || client->buffer); in mousedev_read()
733 if (!mousedev->exist) in mousedev_read()
734 return -ENODEV; in mousedev_read()
736 spin_lock_irq(&client->packet_lock); in mousedev_read()
738 if (!client->buffer && client->ready) { in mousedev_read()
739 mousedev_packet(client, client->ps2); in mousedev_read()
740 client->buffer = client->bufsiz; in mousedev_read()
743 if (count > client->buffer) in mousedev_read()
744 count = client->buffer; in mousedev_read()
746 memcpy(data, client->ps2 + client->bufsiz - client->buffer, count); in mousedev_read()
747 client->buffer -= count; in mousedev_read()
749 spin_unlock_irq(&client->packet_lock); in mousedev_read()
752 return -EFAULT; in mousedev_read()
757 /* No kernel lock - fine */
760 struct mousedev_client *client = file->private_data; in mousedev_poll()
761 struct mousedev *mousedev = client->mousedev; in mousedev_poll()
764 poll_wait(file, &mousedev->wait, wait); in mousedev_poll()
766 mask = mousedev->exist ? EPOLLOUT | EPOLLWRNORM : EPOLLHUP | EPOLLERR; in mousedev_poll()
767 if (client->ready || client->buffer) in mousedev_poll()
785 * Mark device non-existent. This disables writes, ioctls and
791 mutex_lock(&mousedev->mutex); in mousedev_mark_dead()
792 mousedev->exist = false; in mousedev_mark_dead()
793 mutex_unlock(&mousedev->mutex); in mousedev_mark_dead()
797 * Wake up users waiting for IO so they can disconnect from
804 spin_lock(&mousedev->client_lock); in mousedev_hangup()
805 list_for_each_entry(client, &mousedev->client_list, node) in mousedev_hangup()
806 kill_fasync(&client->fasync, SIGIO, POLL_HUP); in mousedev_hangup()
807 spin_unlock(&mousedev->client_lock); in mousedev_hangup()
809 wake_up_interruptible(&mousedev->wait); in mousedev_hangup()
814 struct input_handle *handle = &mousedev->handle; in mousedev_cleanup()
819 /* mousedev is marked dead so no one else accesses mousedev->open */ in mousedev_cleanup()
820 if (mousedev->open) in mousedev_cleanup()
858 error = -ENOMEM; in mousedev_create()
862 INIT_LIST_HEAD(&mousedev->client_list); in mousedev_create()
863 INIT_LIST_HEAD(&mousedev->mixdev_node); in mousedev_create()
864 spin_lock_init(&mousedev->client_lock); in mousedev_create()
865 mutex_init(&mousedev->mutex); in mousedev_create()
866 lockdep_set_subclass(&mousedev->mutex, in mousedev_create()
868 init_waitqueue_head(&mousedev->wait); in mousedev_create()
871 dev_set_name(&mousedev->dev, "mice"); in mousedev_create()
873 mousedev->open_device = mixdev_open_devices; in mousedev_create()
874 mousedev->close_device = mixdev_close_devices; in mousedev_create()
879 dev_no -= MOUSEDEV_MINOR_BASE; in mousedev_create()
880 dev_set_name(&mousedev->dev, "mouse%d", dev_no); in mousedev_create()
882 mousedev->open_device = mousedev_open_device; in mousedev_create()
883 mousedev->close_device = mousedev_close_device; in mousedev_create()
886 mousedev->exist = true; in mousedev_create()
887 mousedev->handle.dev = input_get_device(dev); in mousedev_create()
888 mousedev->handle.name = dev_name(&mousedev->dev); in mousedev_create()
889 mousedev->handle.handler = handler; in mousedev_create()
890 mousedev->handle.private = mousedev; in mousedev_create()
892 mousedev->dev.class = &input_class; in mousedev_create()
894 mousedev->dev.parent = &dev->dev; in mousedev_create()
895 mousedev->dev.devt = MKDEV(INPUT_MAJOR, minor); in mousedev_create()
896 mousedev->dev.release = mousedev_free; in mousedev_create()
897 device_initialize(&mousedev->dev); in mousedev_create()
900 error = input_register_handle(&mousedev->handle); in mousedev_create()
905 cdev_init(&mousedev->cdev, &mousedev_fops); in mousedev_create()
907 error = cdev_device_add(&mousedev->cdev, &mousedev->dev); in mousedev_create()
916 input_unregister_handle(&mousedev->handle); in mousedev_create()
918 put_device(&mousedev->dev); in mousedev_create()
927 cdev_device_del(&mousedev->cdev, &mousedev->dev); in mousedev_destroy()
929 input_free_minor(MINOR(mousedev->dev.devt)); in mousedev_destroy()
931 input_unregister_handle(&mousedev->handle); in mousedev_destroy()
932 put_device(&mousedev->dev); in mousedev_destroy()
939 retval = mutex_lock_interruptible(&mousedev_mix->mutex); in mixdev_add_device()
943 if (mousedev_mix->open) { in mixdev_add_device()
948 mousedev->opened_by_mixdev = true; in mixdev_add_device()
951 get_device(&mousedev->dev); in mixdev_add_device()
952 list_add_tail(&mousedev->mixdev_node, &mousedev_mix_list); in mixdev_add_device()
955 mutex_unlock(&mousedev_mix->mutex); in mixdev_add_device()
961 mutex_lock(&mousedev_mix->mutex); in mixdev_remove_device()
963 if (mousedev->opened_by_mixdev) { in mixdev_remove_device()
964 mousedev->opened_by_mixdev = false; in mixdev_remove_device()
968 list_del_init(&mousedev->mixdev_node); in mixdev_remove_device()
969 mutex_unlock(&mousedev_mix->mutex); in mixdev_remove_device()
971 put_device(&mousedev->dev); in mixdev_remove_device()
996 struct mousedev *mousedev = handle->private; in mousedev_disconnect()
1045 }, /* Mouse-like device with absolute X and Y but ordinary