Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Revert "Input: Add driver for PixArt PS/2 touchpad"

This reverts commit 740ff03d7238214a318cdcfd96dec51832b053d2 because
current PixArt detection is too greedy and claims devices that are
not PixArt.

Reported-by: Benjamin Tissoires <bentiss@kernel.org>
Closes: https://bugzilla.redhat.com/show_bug.cgi?id=2314756
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

+1 -368
-12
drivers/input/mouse/Kconfig
··· 69 69 70 70 If unsure, say Y. 71 71 72 - config MOUSE_PS2_PIXART 73 - bool "PixArt PS/2 touchpad protocol extension" if EXPERT 74 - default y 75 - depends on MOUSE_PS2 76 - help 77 - This driver supports the PixArt PS/2 touchpad found in some 78 - laptops. 79 - Say Y here if you have a PixArt PS/2 TouchPad connected to 80 - your system. 81 - 82 - If unsure, say Y. 83 - 84 72 config MOUSE_PS2_SYNAPTICS 85 73 bool "Synaptics PS/2 mouse protocol extension" if EXPERT 86 74 default y
-1
drivers/input/mouse/Makefile
··· 32 32 psmouse-$(CONFIG_MOUSE_PS2_OLPC) += hgpk.o 33 33 psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP) += logips2pp.o 34 34 psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK) += lifebook.o 35 - psmouse-$(CONFIG_MOUSE_PS2_PIXART) += pixart_ps2.o 36 35 psmouse-$(CONFIG_MOUSE_PS2_SENTELIC) += sentelic.o 37 36 psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o 38 37 psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT) += touchkit_ps2.o
-300
drivers/input/mouse/pixart_ps2.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-or-later 2 - /* 3 - * Pixart Touchpad Controller 1336U PS2 driver 4 - * 5 - * Author: Jon Xie <jon_xie@pixart.com> 6 - * Jay Lee <jay_lee@pixart.com> 7 - * Further cleanup and restructuring by: 8 - * Binbin Zhou <zhoubinbin@loongson.cn> 9 - * 10 - * Copyright (C) 2021-2024 Pixart Imaging. 11 - * Copyright (C) 2024 Loongson Technology Corporation Limited. 12 - * 13 - */ 14 - 15 - #include <linux/bitfield.h> 16 - #include <linux/delay.h> 17 - #include <linux/device.h> 18 - #include <linux/input.h> 19 - #include <linux/input/mt.h> 20 - #include <linux/libps2.h> 21 - #include <linux/serio.h> 22 - #include <linux/slab.h> 23 - 24 - #include "pixart_ps2.h" 25 - 26 - static int pixart_read_tp_mode(struct ps2dev *ps2dev, u8 *mode) 27 - { 28 - int error; 29 - u8 param[1] = { 0 }; 30 - 31 - error = ps2_command(ps2dev, param, PIXART_CMD_REPORT_FORMAT); 32 - if (error) 33 - return error; 34 - 35 - *mode = param[0] == 1 ? PIXART_MODE_ABS : PIXART_MODE_REL; 36 - 37 - return 0; 38 - } 39 - 40 - static int pixart_read_tp_type(struct ps2dev *ps2dev, u8 *type) 41 - { 42 - int error; 43 - u8 param[3] = { 0 }; 44 - 45 - param[0] = 0x0a; 46 - error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); 47 - if (error) 48 - return error; 49 - 50 - param[0] = 0x0; 51 - error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); 52 - if (error) 53 - return error; 54 - 55 - error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); 56 - if (error) 57 - return error; 58 - 59 - error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); 60 - if (error) 61 - return error; 62 - 63 - param[0] = 0x03; 64 - error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); 65 - if (error) 66 - return error; 67 - 68 - error = ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO); 69 - if (error) 70 - return error; 71 - 72 - *type = param[0] == 0x0e ? PIXART_TYPE_TOUCHPAD : PIXART_TYPE_CLICKPAD; 73 - 74 - return 0; 75 - } 76 - 77 - static void pixart_reset(struct psmouse *psmouse) 78 - { 79 - ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); 80 - 81 - /* according to PixArt, 100ms is required for the upcoming reset */ 82 - msleep(100); 83 - psmouse_reset(psmouse); 84 - } 85 - 86 - static void pixart_process_packet(struct psmouse *psmouse) 87 - { 88 - struct pixart_data *priv = psmouse->private; 89 - struct input_dev *dev = psmouse->dev; 90 - const u8 *pkt = psmouse->packet; 91 - unsigned int contact_cnt = FIELD_GET(CONTACT_CNT_MASK, pkt[0]); 92 - unsigned int i, id, abs_x, abs_y; 93 - bool tip; 94 - 95 - for (i = 0; i < contact_cnt; i++) { 96 - const u8 *p = &pkt[i * 3]; 97 - 98 - id = FIELD_GET(SLOT_ID_MASK, p[3]); 99 - abs_y = FIELD_GET(ABS_Y_MASK, p[3]) << 8 | p[1]; 100 - abs_x = FIELD_GET(ABS_X_MASK, p[3]) << 8 | p[2]; 101 - 102 - if (i == PIXART_MAX_FINGERS - 1) 103 - tip = pkt[14] & BIT(1); 104 - else 105 - tip = pkt[3 * contact_cnt + 1] & BIT(2 * i + 1); 106 - 107 - input_mt_slot(dev, id); 108 - if (input_mt_report_slot_state(dev, MT_TOOL_FINGER, tip)) { 109 - input_report_abs(dev, ABS_MT_POSITION_Y, abs_y); 110 - input_report_abs(dev, ABS_MT_POSITION_X, abs_x); 111 - } 112 - } 113 - 114 - input_mt_sync_frame(dev); 115 - 116 - if (priv->type == PIXART_TYPE_CLICKPAD) { 117 - input_report_key(dev, BTN_LEFT, pkt[0] & 0x03); 118 - } else { 119 - input_report_key(dev, BTN_LEFT, pkt[0] & BIT(0)); 120 - input_report_key(dev, BTN_RIGHT, pkt[0] & BIT(1)); 121 - } 122 - 123 - input_sync(dev); 124 - } 125 - 126 - static psmouse_ret_t pixart_protocol_handler(struct psmouse *psmouse) 127 - { 128 - u8 *pkt = psmouse->packet; 129 - u8 contact_cnt; 130 - 131 - if ((pkt[0] & 0x8c) != 0x80) 132 - return PSMOUSE_BAD_DATA; 133 - 134 - contact_cnt = FIELD_GET(CONTACT_CNT_MASK, pkt[0]); 135 - if (contact_cnt > PIXART_MAX_FINGERS) 136 - return PSMOUSE_BAD_DATA; 137 - 138 - if (contact_cnt == PIXART_MAX_FINGERS && 139 - psmouse->pktcnt < psmouse->pktsize) { 140 - return PSMOUSE_GOOD_DATA; 141 - } 142 - 143 - if (contact_cnt == 0 && psmouse->pktcnt < 5) 144 - return PSMOUSE_GOOD_DATA; 145 - 146 - if (psmouse->pktcnt < 3 * contact_cnt + 2) 147 - return PSMOUSE_GOOD_DATA; 148 - 149 - pixart_process_packet(psmouse); 150 - 151 - return PSMOUSE_FULL_PACKET; 152 - } 153 - 154 - static void pixart_disconnect(struct psmouse *psmouse) 155 - { 156 - pixart_reset(psmouse); 157 - kfree(psmouse->private); 158 - psmouse->private = NULL; 159 - } 160 - 161 - static int pixart_reconnect(struct psmouse *psmouse) 162 - { 163 - struct ps2dev *ps2dev = &psmouse->ps2dev; 164 - u8 mode; 165 - int error; 166 - 167 - pixart_reset(psmouse); 168 - 169 - error = pixart_read_tp_mode(ps2dev, &mode); 170 - if (error) 171 - return error; 172 - 173 - if (mode != PIXART_MODE_ABS) 174 - return -EIO; 175 - 176 - error = ps2_command(ps2dev, NULL, PIXART_CMD_SWITCH_PROTO); 177 - if (error) 178 - return error; 179 - 180 - return 0; 181 - } 182 - 183 - static int pixart_set_input_params(struct input_dev *dev, 184 - struct pixart_data *priv) 185 - { 186 - /* No relative support */ 187 - __clear_bit(EV_REL, dev->evbit); 188 - __clear_bit(REL_X, dev->relbit); 189 - __clear_bit(REL_Y, dev->relbit); 190 - __clear_bit(BTN_MIDDLE, dev->keybit); 191 - 192 - /* Buttons */ 193 - __set_bit(EV_KEY, dev->evbit); 194 - __set_bit(BTN_LEFT, dev->keybit); 195 - if (priv->type == PIXART_TYPE_CLICKPAD) 196 - __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); 197 - else 198 - __set_bit(BTN_RIGHT, dev->keybit); 199 - 200 - /* Absolute position */ 201 - input_set_abs_params(dev, ABS_X, 0, PIXART_PAD_WIDTH, 0, 0); 202 - input_set_abs_params(dev, ABS_Y, 0, PIXART_PAD_HEIGHT, 0, 0); 203 - 204 - input_set_abs_params(dev, ABS_MT_POSITION_X, 205 - 0, PIXART_PAD_WIDTH, 0, 0); 206 - input_set_abs_params(dev, ABS_MT_POSITION_Y, 207 - 0, PIXART_PAD_HEIGHT, 0, 0); 208 - 209 - return input_mt_init_slots(dev, PIXART_MAX_FINGERS, INPUT_MT_POINTER); 210 - } 211 - 212 - static int pixart_query_hardware(struct ps2dev *ps2dev, u8 *mode, u8 *type) 213 - { 214 - int error; 215 - 216 - error = pixart_read_tp_type(ps2dev, type); 217 - if (error) 218 - return error; 219 - 220 - error = pixart_read_tp_mode(ps2dev, mode); 221 - if (error) 222 - return error; 223 - 224 - return 0; 225 - } 226 - 227 - int pixart_detect(struct psmouse *psmouse, bool set_properties) 228 - { 229 - u8 type; 230 - int error; 231 - 232 - pixart_reset(psmouse); 233 - 234 - error = pixart_read_tp_type(&psmouse->ps2dev, &type); 235 - if (error) 236 - return error; 237 - 238 - if (set_properties) { 239 - psmouse->vendor = "PixArt"; 240 - psmouse->name = (type == PIXART_TYPE_TOUCHPAD) ? 241 - "touchpad" : "clickpad"; 242 - } 243 - 244 - return 0; 245 - } 246 - 247 - int pixart_init(struct psmouse *psmouse) 248 - { 249 - int error; 250 - struct pixart_data *priv; 251 - 252 - priv = kzalloc(sizeof(*priv), GFP_KERNEL); 253 - if (!priv) 254 - return -ENOMEM; 255 - 256 - psmouse->private = priv; 257 - pixart_reset(psmouse); 258 - 259 - error = pixart_query_hardware(&psmouse->ps2dev, 260 - &priv->mode, &priv->type); 261 - if (error) { 262 - psmouse_err(psmouse, "init: Unable to query PixArt touchpad hardware.\n"); 263 - goto err_exit; 264 - } 265 - 266 - /* Relative mode follows standard PS/2 mouse protocol */ 267 - if (priv->mode != PIXART_MODE_ABS) { 268 - error = -EIO; 269 - goto err_exit; 270 - } 271 - 272 - /* Set absolute mode */ 273 - error = ps2_command(&psmouse->ps2dev, NULL, PIXART_CMD_SWITCH_PROTO); 274 - if (error) { 275 - psmouse_err(psmouse, "init: Unable to initialize PixArt absolute mode.\n"); 276 - goto err_exit; 277 - } 278 - 279 - error = pixart_set_input_params(psmouse->dev, priv); 280 - if (error) { 281 - psmouse_err(psmouse, "init: Unable to set input params.\n"); 282 - goto err_exit; 283 - } 284 - 285 - psmouse->pktsize = 15; 286 - psmouse->protocol_handler = pixart_protocol_handler; 287 - psmouse->disconnect = pixart_disconnect; 288 - psmouse->reconnect = pixart_reconnect; 289 - psmouse->cleanup = pixart_reset; 290 - /* resync is not supported yet */ 291 - psmouse->resync_time = 0; 292 - 293 - return 0; 294 - 295 - err_exit: 296 - pixart_reset(psmouse); 297 - kfree(priv); 298 - psmouse->private = NULL; 299 - return error; 300 - }
-36
drivers/input/mouse/pixart_ps2.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 - #ifndef _PIXART_PS2_H 3 - #define _PIXART_PS2_H 4 - 5 - #include "psmouse.h" 6 - 7 - #define PIXART_PAD_WIDTH 1023 8 - #define PIXART_PAD_HEIGHT 579 9 - #define PIXART_MAX_FINGERS 4 10 - 11 - #define PIXART_CMD_REPORT_FORMAT 0x01d8 12 - #define PIXART_CMD_SWITCH_PROTO 0x00de 13 - 14 - #define PIXART_MODE_REL 0 15 - #define PIXART_MODE_ABS 1 16 - 17 - #define PIXART_TYPE_CLICKPAD 0 18 - #define PIXART_TYPE_TOUCHPAD 1 19 - 20 - #define CONTACT_CNT_MASK GENMASK(6, 4) 21 - 22 - #define SLOT_ID_MASK GENMASK(2, 0) 23 - #define ABS_Y_MASK GENMASK(5, 4) 24 - #define ABS_X_MASK GENMASK(7, 6) 25 - 26 - struct pixart_data { 27 - u8 mode; 28 - u8 type; 29 - int x_max; 30 - int y_max; 31 - }; 32 - 33 - int pixart_detect(struct psmouse *psmouse, bool set_properties); 34 - int pixart_init(struct psmouse *psmouse); 35 - 36 - #endif /* _PIXART_PS2_H */
-17
drivers/input/mouse/psmouse-base.c
··· 36 36 #include "focaltech.h" 37 37 #include "vmmouse.h" 38 38 #include "byd.h" 39 - #include "pixart_ps2.h" 40 39 41 40 #define DRIVER_DESC "PS/2 mouse driver" 42 41 ··· 906 907 .init = byd_init, 907 908 }, 908 909 #endif 909 - #ifdef CONFIG_MOUSE_PS2_PIXART 910 - { 911 - .type = PSMOUSE_PIXART, 912 - .name = "PixArtPS/2", 913 - .alias = "pixart", 914 - .detect = pixart_detect, 915 - .init = pixart_init, 916 - }, 917 - #endif 918 910 { 919 911 .type = PSMOUSE_AUTO, 920 912 .name = "auto", ··· 1170 1180 ret = elantech_init(psmouse); 1171 1181 if (ret >= 0) 1172 1182 return ret; 1173 - } 1174 - 1175 - /* Try PixArt touchpad */ 1176 - if (max_proto > PSMOUSE_IMEX && 1177 - psmouse_try_protocol(psmouse, PSMOUSE_PIXART, &max_proto, 1178 - set_properties, true)) { 1179 - return PSMOUSE_PIXART; 1180 1183 } 1181 1184 1182 1185 if (max_proto > PSMOUSE_IMEX) {
+1 -2
drivers/input/mouse/psmouse.h
··· 69 69 PSMOUSE_BYD, 70 70 PSMOUSE_SYNAPTICS_SMBUS, 71 71 PSMOUSE_ELANTECH_SMBUS, 72 - PSMOUSE_PIXART, 73 72 PSMOUSE_AUTO /* This one should always be last */ 74 73 }; 75 74 ··· 94 95 const char *vendor; 95 96 const char *name; 96 97 const struct psmouse_protocol *protocol; 97 - unsigned char packet[16]; 98 + unsigned char packet[8]; 98 99 unsigned char badbyte; 99 100 unsigned char pktcnt; 100 101 unsigned char pktsize;