^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Input driver to ExplorerPS/2 device driver module.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 1999-2002 Vojtech Pavlik
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2004 Dmitry Torokhov
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define MOUSEDEV_MINOR_BASE 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define MOUSEDEV_MINORS 31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #define MOUSEDEV_MIX 63
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/random.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/major.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/cdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) MODULE_DESCRIPTION("Mouse (ExplorerPS/2) device interfaces");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #ifndef CONFIG_INPUT_MOUSEDEV_SCREEN_X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define CONFIG_INPUT_MOUSEDEV_SCREEN_X 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #ifndef CONFIG_INPUT_MOUSEDEV_SCREEN_Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define CONFIG_INPUT_MOUSEDEV_SCREEN_Y 768
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static int xres = CONFIG_INPUT_MOUSEDEV_SCREEN_X;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) module_param(xres, uint, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) MODULE_PARM_DESC(xres, "Horizontal screen resolution");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static int yres = CONFIG_INPUT_MOUSEDEV_SCREEN_Y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) module_param(yres, uint, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) MODULE_PARM_DESC(yres, "Vertical screen resolution");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static unsigned tap_time = 200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) module_param(tap_time, uint, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) MODULE_PARM_DESC(tap_time, "Tap time for touchpads in absolute mode (msecs)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct mousedev_hw_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) int dx, dy, dz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) int x, y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) int abs_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) unsigned long buttons;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct mousedev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) int open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct input_handle handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) wait_queue_head_t wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct list_head client_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) spinlock_t client_lock; /* protects client_list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct mutex mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct device dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct cdev cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) bool exist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct list_head mixdev_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) bool opened_by_mixdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct mousedev_hw_data packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) unsigned int pkt_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) int old_x[4], old_y[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) int frac_dx, frac_dy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) unsigned long touch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int (*open_device)(struct mousedev *mousedev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) void (*close_device)(struct mousedev *mousedev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) enum mousedev_emul {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) MOUSEDEV_EMUL_PS2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) MOUSEDEV_EMUL_IMPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) MOUSEDEV_EMUL_EXPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct mousedev_motion {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) int dx, dy, dz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) unsigned long buttons;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define PACKET_QUEUE_LEN 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct mousedev_client {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct fasync_struct *fasync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct mousedev *mousedev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct list_head node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct mousedev_motion packets[PACKET_QUEUE_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) unsigned int head, tail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) spinlock_t packet_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) int pos_x, pos_y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) u8 ps2[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) unsigned char ready, buffer, bufsiz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) unsigned char imexseq, impsseq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) enum mousedev_emul mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) unsigned long last_buttons;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define MOUSEDEV_SEQ_LEN 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static unsigned char mousedev_imps_seq[] = { 0xf3, 200, 0xf3, 100, 0xf3, 80 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static unsigned char mousedev_imex_seq[] = { 0xf3, 200, 0xf3, 200, 0xf3, 80 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static struct mousedev *mousedev_mix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static LIST_HEAD(mousedev_mix_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static void mousedev_touchpad_event(struct input_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct mousedev *mousedev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) unsigned int code, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) int size, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) enum { FRACTION_DENOM = 128 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) switch (code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) case ABS_X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) fx(0) = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (mousedev->touch && mousedev->pkt_count >= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) size = input_abs_get_max(dev, ABS_X) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) input_abs_get_min(dev, ABS_X);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) size = 256 * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) tmp = ((value - fx(2)) * 256 * FRACTION_DENOM) / size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) tmp += mousedev->frac_dx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) mousedev->packet.dx = tmp / FRACTION_DENOM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) mousedev->frac_dx =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) tmp - mousedev->packet.dx * FRACTION_DENOM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) case ABS_Y:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) fy(0) = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (mousedev->touch && mousedev->pkt_count >= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* use X size for ABS_Y to keep the same scale */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) size = input_abs_get_max(dev, ABS_X) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) input_abs_get_min(dev, ABS_X);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) size = 256 * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) tmp = -((value - fy(2)) * 256 * FRACTION_DENOM) / size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) tmp += mousedev->frac_dy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) mousedev->packet.dy = tmp / FRACTION_DENOM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) mousedev->frac_dy = tmp -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) mousedev->packet.dy * FRACTION_DENOM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) unsigned int code, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) int min, max, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) switch (code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) case ABS_X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) min = input_abs_get_min(dev, ABS_X);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) max = input_abs_get_max(dev, ABS_X);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) size = max - min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) size = xres ? : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) value = clamp(value, min, max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) mousedev->packet.x = ((value - min) * xres) / size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) mousedev->packet.abs_event = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) case ABS_Y:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) min = input_abs_get_min(dev, ABS_Y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) max = input_abs_get_max(dev, ABS_Y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) size = max - min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) size = yres ? : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) value = clamp(value, min, max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) mousedev->packet.y = yres - ((value - min) * yres) / size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) mousedev->packet.abs_event = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static void mousedev_rel_event(struct mousedev *mousedev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) unsigned int code, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) switch (code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) case REL_X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) mousedev->packet.dx += value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) case REL_Y:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) mousedev->packet.dy -= value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) case REL_WHEEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) mousedev->packet.dz -= value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static void mousedev_key_event(struct mousedev *mousedev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) unsigned int code, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) switch (code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) case BTN_TOUCH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) case BTN_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) case BTN_LEFT: index = 0; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) case BTN_STYLUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) case BTN_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) case BTN_RIGHT: index = 1; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) case BTN_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) case BTN_FORWARD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) case BTN_STYLUS2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) case BTN_MIDDLE: index = 2; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) case BTN_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) case BTN_BACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) case BTN_SIDE: index = 3; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) case BTN_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) case BTN_EXTRA: index = 4; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) default: return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) set_bit(index, &mousedev->packet.buttons);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) set_bit(index, &mousedev_mix->packet.buttons);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) clear_bit(index, &mousedev->packet.buttons);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) clear_bit(index, &mousedev_mix->packet.buttons);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static void mousedev_notify_readers(struct mousedev *mousedev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct mousedev_hw_data *packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) struct mousedev_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct mousedev_motion *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) unsigned int new_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) int wake_readers = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) list_for_each_entry_rcu(client, &mousedev->client_list, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /* Just acquire the lock, interrupts already disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) spin_lock(&client->packet_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) p = &client->packets[client->head];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (client->ready && p->buttons != mousedev->packet.buttons) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) new_head = (client->head + 1) % PACKET_QUEUE_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (new_head != client->tail) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) p = &client->packets[client->head = new_head];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) memset(p, 0, sizeof(struct mousedev_motion));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (packet->abs_event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) p->dx += packet->x - client->pos_x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) p->dy += packet->y - client->pos_y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) client->pos_x = packet->x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) client->pos_y = packet->y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) client->pos_x += packet->dx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) client->pos_x = clamp_val(client->pos_x, 0, xres);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) client->pos_y += packet->dy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) client->pos_y = clamp_val(client->pos_y, 0, yres);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) p->dx += packet->dx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) p->dy += packet->dy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) p->dz += packet->dz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) p->buttons = mousedev->packet.buttons;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (p->dx || p->dy || p->dz ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) p->buttons != client->last_buttons)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) client->ready = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) spin_unlock(&client->packet_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (client->ready) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) kill_fasync(&client->fasync, SIGIO, POLL_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) wake_readers = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (wake_readers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) wake_up_interruptible(&mousedev->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) static void mousedev_touchpad_touch(struct mousedev *mousedev, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (!value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (mousedev->touch &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) time_before(jiffies,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) mousedev->touch + msecs_to_jiffies(tap_time))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * Toggle left button to emulate tap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * We rely on the fact that mousedev_mix always has 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * motion packet so we won't mess current position.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) set_bit(0, &mousedev->packet.buttons);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) set_bit(0, &mousedev_mix->packet.buttons);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) mousedev_notify_readers(mousedev, &mousedev_mix->packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) mousedev_notify_readers(mousedev_mix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) &mousedev_mix->packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) clear_bit(0, &mousedev->packet.buttons);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) clear_bit(0, &mousedev_mix->packet.buttons);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) mousedev->touch = mousedev->pkt_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) mousedev->frac_dx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) mousedev->frac_dy = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) } else if (!mousedev->touch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) mousedev->touch = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static void mousedev_event(struct input_handle *handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) unsigned int type, unsigned int code, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct mousedev *mousedev = handle->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) case EV_ABS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /* Ignore joysticks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (test_bit(BTN_TRIGGER, handle->dev->keybit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) mousedev_touchpad_event(handle->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) mousedev, code, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) mousedev_abs_event(handle->dev, mousedev, code, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) case EV_REL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) mousedev_rel_event(mousedev, code, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) case EV_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (value != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (code == BTN_TOUCH &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) test_bit(BTN_TOOL_FINGER, handle->dev->keybit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) mousedev_touchpad_touch(mousedev, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) mousedev_key_event(mousedev, code, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) case EV_SYN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (code == SYN_REPORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (mousedev->touch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) mousedev->pkt_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * Input system eats duplicate events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * but we need all of them to do correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * averaging so apply present one forward
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) fx(0) = fx(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) fy(0) = fy(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) mousedev_notify_readers(mousedev, &mousedev->packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) mousedev_notify_readers(mousedev_mix, &mousedev->packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) mousedev->packet.dx = mousedev->packet.dy =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) mousedev->packet.dz = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) mousedev->packet.abs_event = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) static int mousedev_fasync(int fd, struct file *file, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct mousedev_client *client = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return fasync_helper(fd, file, on, &client->fasync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) static void mousedev_free(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) struct mousedev *mousedev = container_of(dev, struct mousedev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) input_put_device(mousedev->handle.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) kfree(mousedev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) static int mousedev_open_device(struct mousedev *mousedev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) retval = mutex_lock_interruptible(&mousedev->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (!mousedev->exist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) retval = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) else if (!mousedev->open++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) retval = input_open_device(&mousedev->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) mousedev->open--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) mutex_unlock(&mousedev->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static void mousedev_close_device(struct mousedev *mousedev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) mutex_lock(&mousedev->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (mousedev->exist && !--mousedev->open)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) input_close_device(&mousedev->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) mutex_unlock(&mousedev->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * Open all available devices so they can all be multiplexed in one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * stream. Note that this function is called with mousedev_mix->mutex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) static int mixdev_open_devices(struct mousedev *mixdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) error = mutex_lock_interruptible(&mixdev->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (!mixdev->open++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct mousedev *mousedev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (!mousedev->opened_by_mixdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (mousedev_open_device(mousedev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) mousedev->opened_by_mixdev = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) mutex_unlock(&mixdev->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * Close all devices that were opened as part of multiplexed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * device. Note that this function is called with mousedev_mix->mutex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static void mixdev_close_devices(struct mousedev *mixdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) mutex_lock(&mixdev->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (!--mixdev->open) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) struct mousedev *mousedev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (mousedev->opened_by_mixdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) mousedev->opened_by_mixdev = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) mousedev_close_device(mousedev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) mutex_unlock(&mixdev->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) static void mousedev_attach_client(struct mousedev *mousedev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) struct mousedev_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) spin_lock(&mousedev->client_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) list_add_tail_rcu(&client->node, &mousedev->client_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) spin_unlock(&mousedev->client_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) static void mousedev_detach_client(struct mousedev *mousedev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) struct mousedev_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) spin_lock(&mousedev->client_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) list_del_rcu(&client->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) spin_unlock(&mousedev->client_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) synchronize_rcu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) static int mousedev_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) struct mousedev_client *client = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) struct mousedev *mousedev = client->mousedev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) mousedev_detach_client(mousedev, client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) kfree(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) mousedev->close_device(mousedev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) static int mousedev_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) struct mousedev_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) struct mousedev *mousedev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (imajor(inode) == MISC_MAJOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) mousedev = mousedev_mix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) mousedev = container_of(inode->i_cdev, struct mousedev, cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (!client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) spin_lock_init(&client->packet_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) client->pos_x = xres / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) client->pos_y = yres / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) client->mousedev = mousedev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) mousedev_attach_client(mousedev, client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) error = mousedev->open_device(mousedev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) goto err_free_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) file->private_data = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) stream_open(inode, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) err_free_client:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) mousedev_detach_client(mousedev, client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) kfree(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) static void mousedev_packet(struct mousedev_client *client, u8 *ps2_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) struct mousedev_motion *p = &client->packets[client->tail];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) s8 dx, dy, dz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) dx = clamp_val(p->dx, -127, 127);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) p->dx -= dx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) dy = clamp_val(p->dy, -127, 127);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) p->dy -= dy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) ps2_data[0] = BIT(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) ps2_data[0] |= ((dx & BIT(7)) >> 3) | ((dy & BIT(7)) >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) ps2_data[0] |= p->buttons & 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) ps2_data[1] = dx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) ps2_data[2] = dy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) switch (client->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) case MOUSEDEV_EMUL_EXPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) dz = clamp_val(p->dz, -7, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) p->dz -= dz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) ps2_data[3] = (dz & 0x0f) | ((p->buttons & 0x18) << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) client->bufsiz = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) case MOUSEDEV_EMUL_IMPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) dz = clamp_val(p->dz, -127, 127);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) p->dz -= dz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) ps2_data[0] |= ((p->buttons & 0x10) >> 3) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) ((p->buttons & 0x08) >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) ps2_data[3] = dz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) client->bufsiz = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) case MOUSEDEV_EMUL_PS2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) p->dz = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) ps2_data[0] |= ((p->buttons & 0x10) >> 3) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) ((p->buttons & 0x08) >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) client->bufsiz = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) if (!p->dx && !p->dy && !p->dz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (client->tail == client->head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) client->ready = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) client->last_buttons = p->buttons;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) client->tail = (client->tail + 1) % PACKET_QUEUE_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) static void mousedev_generate_response(struct mousedev_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) int command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) client->ps2[0] = 0xfa; /* ACK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) switch (command) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) case 0xeb: /* Poll */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) mousedev_packet(client, &client->ps2[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) client->bufsiz++; /* account for leading ACK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) case 0xf2: /* Get ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) switch (client->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) case MOUSEDEV_EMUL_PS2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) client->ps2[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) case MOUSEDEV_EMUL_IMPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) client->ps2[1] = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) case MOUSEDEV_EMUL_EXPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) client->ps2[1] = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) client->bufsiz = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) case 0xe9: /* Get info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) client->ps2[1] = 0x60; client->ps2[2] = 3; client->ps2[3] = 200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) client->bufsiz = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) case 0xff: /* Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) client->impsseq = client->imexseq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) client->mode = MOUSEDEV_EMUL_PS2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) client->ps2[1] = 0xaa; client->ps2[2] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) client->bufsiz = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) client->bufsiz = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) client->buffer = client->bufsiz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) static ssize_t mousedev_write(struct file *file, const char __user *buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) struct mousedev_client *client = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) unsigned char c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) for (i = 0; i < count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (get_user(c, buffer + i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) spin_lock_irq(&client->packet_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if (c == mousedev_imex_seq[client->imexseq]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (++client->imexseq == MOUSEDEV_SEQ_LEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) client->imexseq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) client->mode = MOUSEDEV_EMUL_EXPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) client->imexseq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) if (c == mousedev_imps_seq[client->impsseq]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (++client->impsseq == MOUSEDEV_SEQ_LEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) client->impsseq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) client->mode = MOUSEDEV_EMUL_IMPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) client->impsseq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) mousedev_generate_response(client, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) spin_unlock_irq(&client->packet_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) kill_fasync(&client->fasync, SIGIO, POLL_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) wake_up_interruptible(&client->mousedev->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) static ssize_t mousedev_read(struct file *file, char __user *buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) struct mousedev_client *client = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) struct mousedev *mousedev = client->mousedev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) u8 data[sizeof(client->ps2)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (!client->ready && !client->buffer && mousedev->exist &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) (file->f_flags & O_NONBLOCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) retval = wait_event_interruptible(mousedev->wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) !mousedev->exist || client->ready || client->buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (!mousedev->exist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) spin_lock_irq(&client->packet_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) if (!client->buffer && client->ready) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) mousedev_packet(client, client->ps2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) client->buffer = client->bufsiz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (count > client->buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) count = client->buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) memcpy(data, client->ps2 + client->bufsiz - client->buffer, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) client->buffer -= count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) spin_unlock_irq(&client->packet_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (copy_to_user(buffer, data, count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) /* No kernel lock - fine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) static __poll_t mousedev_poll(struct file *file, poll_table *wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) struct mousedev_client *client = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) struct mousedev *mousedev = client->mousedev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) __poll_t mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) poll_wait(file, &mousedev->wait, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) mask = mousedev->exist ? EPOLLOUT | EPOLLWRNORM : EPOLLHUP | EPOLLERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (client->ready || client->buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) mask |= EPOLLIN | EPOLLRDNORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) return mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) static const struct file_operations mousedev_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) .read = mousedev_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) .write = mousedev_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) .poll = mousedev_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) .open = mousedev_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) .release = mousedev_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) .fasync = mousedev_fasync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) .llseek = noop_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) * Mark device non-existent. This disables writes, ioctls and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) * prevents new users from opening the device. Already posted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) * blocking reads will stay, however new ones will fail.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) static void mousedev_mark_dead(struct mousedev *mousedev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) mutex_lock(&mousedev->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) mousedev->exist = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) mutex_unlock(&mousedev->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) * Wake up users waiting for IO so they can disconnect from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) * dead device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) static void mousedev_hangup(struct mousedev *mousedev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) struct mousedev_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) spin_lock(&mousedev->client_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) list_for_each_entry(client, &mousedev->client_list, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) kill_fasync(&client->fasync, SIGIO, POLL_HUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) spin_unlock(&mousedev->client_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) wake_up_interruptible(&mousedev->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) static void mousedev_cleanup(struct mousedev *mousedev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) struct input_handle *handle = &mousedev->handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) mousedev_mark_dead(mousedev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) mousedev_hangup(mousedev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) /* mousedev is marked dead so no one else accesses mousedev->open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (mousedev->open)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) input_close_device(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) static int mousedev_reserve_minor(bool mixdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) int minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (mixdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) minor = input_get_new_minor(MOUSEDEV_MIX, 1, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (minor < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) pr_err("failed to reserve mixdev minor: %d\n", minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) minor = input_get_new_minor(MOUSEDEV_MINOR_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) MOUSEDEV_MINORS, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) if (minor < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) pr_err("failed to reserve new minor: %d\n", minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) return minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) static struct mousedev *mousedev_create(struct input_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) struct input_handler *handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) bool mixdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) struct mousedev *mousedev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) int minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) minor = mousedev_reserve_minor(mixdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) if (minor < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) error = minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (!mousedev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) goto err_free_minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) INIT_LIST_HEAD(&mousedev->client_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) INIT_LIST_HEAD(&mousedev->mixdev_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) spin_lock_init(&mousedev->client_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) mutex_init(&mousedev->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) lockdep_set_subclass(&mousedev->mutex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) mixdev ? SINGLE_DEPTH_NESTING : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) init_waitqueue_head(&mousedev->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if (mixdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) dev_set_name(&mousedev->dev, "mice");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) mousedev->open_device = mixdev_open_devices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) mousedev->close_device = mixdev_close_devices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) int dev_no = minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) /* Normalize device number if it falls into legacy range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) if (dev_no < MOUSEDEV_MINOR_BASE + MOUSEDEV_MINORS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) dev_no -= MOUSEDEV_MINOR_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) dev_set_name(&mousedev->dev, "mouse%d", dev_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) mousedev->open_device = mousedev_open_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) mousedev->close_device = mousedev_close_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) mousedev->exist = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) mousedev->handle.dev = input_get_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) mousedev->handle.name = dev_name(&mousedev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) mousedev->handle.handler = handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) mousedev->handle.private = mousedev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) mousedev->dev.class = &input_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) if (dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) mousedev->dev.parent = &dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) mousedev->dev.devt = MKDEV(INPUT_MAJOR, minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) mousedev->dev.release = mousedev_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) device_initialize(&mousedev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if (!mixdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) error = input_register_handle(&mousedev->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) goto err_free_mousedev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) cdev_init(&mousedev->cdev, &mousedev_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) error = cdev_device_add(&mousedev->cdev, &mousedev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) goto err_cleanup_mousedev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) return mousedev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) err_cleanup_mousedev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) mousedev_cleanup(mousedev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) if (!mixdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) input_unregister_handle(&mousedev->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) err_free_mousedev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) put_device(&mousedev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) err_free_minor:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) input_free_minor(minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) return ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) static void mousedev_destroy(struct mousedev *mousedev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) cdev_device_del(&mousedev->cdev, &mousedev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) mousedev_cleanup(mousedev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) input_free_minor(MINOR(mousedev->dev.devt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (mousedev != mousedev_mix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) input_unregister_handle(&mousedev->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) put_device(&mousedev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) static int mixdev_add_device(struct mousedev *mousedev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) retval = mutex_lock_interruptible(&mousedev_mix->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) if (mousedev_mix->open) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) retval = mousedev_open_device(mousedev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) mousedev->opened_by_mixdev = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) get_device(&mousedev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) list_add_tail(&mousedev->mixdev_node, &mousedev_mix_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) mutex_unlock(&mousedev_mix->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) static void mixdev_remove_device(struct mousedev *mousedev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) mutex_lock(&mousedev_mix->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) if (mousedev->opened_by_mixdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) mousedev->opened_by_mixdev = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) mousedev_close_device(mousedev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) list_del_init(&mousedev->mixdev_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) mutex_unlock(&mousedev_mix->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) put_device(&mousedev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) static int mousedev_connect(struct input_handler *handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) struct input_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) const struct input_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) struct mousedev *mousedev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) mousedev = mousedev_create(dev, handler, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) if (IS_ERR(mousedev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) return PTR_ERR(mousedev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) error = mixdev_add_device(mousedev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) mousedev_destroy(mousedev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) static void mousedev_disconnect(struct input_handle *handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) struct mousedev *mousedev = handle->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) mixdev_remove_device(mousedev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) mousedev_destroy(mousedev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) static const struct input_device_id mousedev_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) INPUT_DEVICE_ID_MATCH_KEYBIT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) INPUT_DEVICE_ID_MATCH_RELBIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) .keybit = { [BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) .relbit = { BIT_MASK(REL_X) | BIT_MASK(REL_Y) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) }, /* A mouse like device, at least one button,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) two relative axes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) INPUT_DEVICE_ID_MATCH_RELBIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) .relbit = { BIT_MASK(REL_WHEEL) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }, /* A separate scrollwheel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) INPUT_DEVICE_ID_MATCH_KEYBIT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) INPUT_DEVICE_ID_MATCH_ABSBIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) }, /* A tablet like device, at least touch detection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) two absolute axes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) INPUT_DEVICE_ID_MATCH_KEYBIT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) INPUT_DEVICE_ID_MATCH_ABSBIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) .keybit = { [BIT_WORD(BTN_TOOL_FINGER)] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) BIT_MASK(BTN_TOOL_FINGER) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) BIT_MASK(ABS_PRESSURE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) BIT_MASK(ABS_TOOL_WIDTH) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) }, /* A touchpad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) INPUT_DEVICE_ID_MATCH_KEYBIT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) INPUT_DEVICE_ID_MATCH_ABSBIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) .keybit = { [BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }, /* Mouse-like device with absolute X and Y but ordinary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) clicks, like hp ILO2 High Performance mouse */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) { }, /* Terminating entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) MODULE_DEVICE_TABLE(input, mousedev_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) static struct input_handler mousedev_handler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) .event = mousedev_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) .connect = mousedev_connect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) .disconnect = mousedev_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) .legacy_minors = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) .minor = MOUSEDEV_MINOR_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) .name = "mousedev",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) .id_table = mousedev_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) #include <linux/miscdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) static struct miscdevice psaux_mouse = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) .minor = PSMOUSE_MINOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) .name = "psaux",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) .fops = &mousedev_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) static bool psaux_registered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) static void __init mousedev_psaux_register(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) error = misc_register(&psaux_mouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) pr_warn("could not register psaux device, error: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) psaux_registered = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) static void __exit mousedev_psaux_unregister(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (psaux_registered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) misc_deregister(&psaux_mouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) static inline void mousedev_psaux_register(void) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) static inline void mousedev_psaux_unregister(void) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) static int __init mousedev_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) mousedev_mix = mousedev_create(NULL, &mousedev_handler, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) if (IS_ERR(mousedev_mix))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) return PTR_ERR(mousedev_mix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) error = input_register_handler(&mousedev_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) mousedev_destroy(mousedev_mix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) mousedev_psaux_register();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) pr_info("PS/2 mouse device common for all mice\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) static void __exit mousedev_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) mousedev_psaux_unregister();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) input_unregister_handler(&mousedev_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) mousedev_destroy(mousedev_mix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) module_init(mousedev_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) module_exit(mousedev_exit);