aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPali Rohár <pali.rohar@gmail.com>2015-01-14 16:18:30 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2015-02-15 18:44:19 -0500
commit04aae283ba6a8cd4851d937bf9c6d6ef0361d794 (patch)
tree98fa424384af30ad1ceb63be9d88e85e291375d1
parenta09221e83e13e09a33109b9b037484eade901cea (diff)
Input: ALPS - do not mix trackstick and external PS/2 mouse data
Previously dev2 device was used for both external PS/2 mouse and internal trackstick device (if available). This change introduces dev3 device which is used for external PS/2 mouse data and dev2 is now used only for trackstick. In case that trackstick is not present dev2 is not created, so userspace does not see non existent device in system. Because laptops with ALPS devices often do not use i8042 active multiplexing all data (from touchpad, trackstick and external PS/2 mouse) come to one port. So it is not possible to know if external PS/2 mouse is connected or not. In most cases external PS/2 mouse is not connected so driver will create dev3 input device after first bare PS/2 packet will be received. So there will not be "ghost" input device. This change also helps in identifying possible problems in future if driver decides to report 6-bytes trackstick packets as 3-bytes bare PS/2 (data will be reported to dev3 instead dev2). Signed-off-by: Pali Rohár <pali.rohar@gmail.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r--drivers/input/mouse/alps.c190
-rw-r--r--drivers/input/mouse/alps.h14
2 files changed, 151 insertions, 53 deletions
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index d164690bfdf7..a4d69ef0f846 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -165,8 +165,7 @@ static bool alps_is_valid_first_byte(struct alps_data *priv,
165 return (data & priv->mask0) == priv->byte0; 165 return (data & priv->mask0) == priv->byte0;
166} 166}
167 167
168static void alps_report_buttons(struct psmouse *psmouse, 168static void alps_report_buttons(struct input_dev *dev1, struct input_dev *dev2,
169 struct input_dev *dev1, struct input_dev *dev2,
170 int left, int right, int middle) 169 int left, int right, int middle)
171{ 170{
172 struct input_dev *dev; 171 struct input_dev *dev;
@@ -176,20 +175,21 @@ static void alps_report_buttons(struct psmouse *psmouse,
176 * other device (dev2) then this event should be also 175 * other device (dev2) then this event should be also
177 * sent through that device. 176 * sent through that device.
178 */ 177 */
179 dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1; 178 dev = (dev2 && test_bit(BTN_LEFT, dev2->key)) ? dev2 : dev1;
180 input_report_key(dev, BTN_LEFT, left); 179 input_report_key(dev, BTN_LEFT, left);
181 180
182 dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1; 181 dev = (dev2 && test_bit(BTN_RIGHT, dev2->key)) ? dev2 : dev1;
183 input_report_key(dev, BTN_RIGHT, right); 182 input_report_key(dev, BTN_RIGHT, right);
184 183
185 dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1; 184 dev = (dev2 && test_bit(BTN_MIDDLE, dev2->key)) ? dev2 : dev1;
186 input_report_key(dev, BTN_MIDDLE, middle); 185 input_report_key(dev, BTN_MIDDLE, middle);
187 186
188 /* 187 /*
189 * Sync the _other_ device now, we'll do the first 188 * Sync the _other_ device now, we'll do the first
190 * device later once we report the rest of the events. 189 * device later once we report the rest of the events.
191 */ 190 */
192 input_sync(dev2); 191 if (dev2)
192 input_sync(dev2);
193} 193}
194 194
195static void alps_process_packet_v1_v2(struct psmouse *psmouse) 195static void alps_process_packet_v1_v2(struct psmouse *psmouse)
@@ -236,13 +236,13 @@ static void alps_process_packet_v1_v2(struct psmouse *psmouse)
236 input_report_rel(dev2, REL_X, (x > 383 ? (x - 768) : x)); 236 input_report_rel(dev2, REL_X, (x > 383 ? (x - 768) : x));
237 input_report_rel(dev2, REL_Y, -(y > 255 ? (y - 512) : y)); 237 input_report_rel(dev2, REL_Y, -(y > 255 ? (y - 512) : y));
238 238
239 alps_report_buttons(psmouse, dev2, dev, left, right, middle); 239 alps_report_buttons(dev2, dev, left, right, middle);
240 240
241 input_sync(dev2); 241 input_sync(dev2);
242 return; 242 return;
243 } 243 }
244 244
245 alps_report_buttons(psmouse, dev, dev2, left, right, middle); 245 alps_report_buttons(dev, dev2, left, right, middle);
246 246
247 /* Convert hardware tap to a reasonable Z value */ 247 /* Convert hardware tap to a reasonable Z value */
248 if (ges && !fin) 248 if (ges && !fin)
@@ -1123,23 +1123,89 @@ static void alps_process_packet_v7(struct psmouse *psmouse)
1123 alps_process_touchpad_packet_v7(psmouse); 1123 alps_process_touchpad_packet_v7(psmouse);
1124} 1124}
1125 1125
1126static void alps_report_bare_ps2_packet(struct psmouse *psmouse, 1126static DEFINE_MUTEX(alps_mutex);
1127
1128static void alps_register_bare_ps2_mouse(struct work_struct *work)
1129{
1130 struct alps_data *priv =
1131 container_of(work, struct alps_data, dev3_register_work.work);
1132 struct psmouse *psmouse = priv->psmouse;
1133 struct input_dev *dev3;
1134 int error = 0;
1135
1136 mutex_lock(&alps_mutex);
1137
1138 if (priv->dev3)
1139 goto out;
1140
1141 dev3 = input_allocate_device();
1142 if (!dev3) {
1143 psmouse_err(psmouse, "failed to allocate secondary device\n");
1144 error = -ENOMEM;
1145 goto out;
1146 }
1147
1148 snprintf(priv->phys3, sizeof(priv->phys3), "%s/%s",
1149 psmouse->ps2dev.serio->phys,
1150 (priv->dev2 ? "input2" : "input1"));
1151 dev3->phys = priv->phys3;
1152
1153 /*
1154 * format of input device name is: "protocol vendor name"
1155 * see function psmouse_switch_protocol() in psmouse-base.c
1156 */
1157 dev3->name = "PS/2 ALPS Mouse";
1158
1159 dev3->id.bustype = BUS_I8042;
1160 dev3->id.vendor = 0x0002;
1161 dev3->id.product = PSMOUSE_PS2;
1162 dev3->id.version = 0x0000;
1163 dev3->dev.parent = &psmouse->ps2dev.serio->dev;
1164
1165 input_set_capability(dev3, EV_REL, REL_X);
1166 input_set_capability(dev3, EV_REL, REL_Y);
1167 input_set_capability(dev3, EV_KEY, BTN_LEFT);
1168 input_set_capability(dev3, EV_KEY, BTN_RIGHT);
1169 input_set_capability(dev3, EV_KEY, BTN_MIDDLE);
1170
1171 __set_bit(INPUT_PROP_POINTER, dev3->propbit);
1172
1173 error = input_register_device(dev3);
1174 if (error) {
1175 psmouse_err(psmouse,
1176 "failed to register secondary device: %d\n",
1177 error);
1178 input_free_device(dev3);
1179 goto out;
1180 }
1181
1182 priv->dev3 = dev3;
1183
1184out:
1185 /*
1186 * Save the error code so that we can detect that we
1187 * already tried to create the device.
1188 */
1189 if (error)
1190 priv->dev3 = ERR_PTR(error);
1191
1192 mutex_unlock(&alps_mutex);
1193}
1194
1195static void alps_report_bare_ps2_packet(struct input_dev *dev,
1127 unsigned char packet[], 1196 unsigned char packet[],
1128 bool report_buttons) 1197 bool report_buttons)
1129{ 1198{
1130 struct alps_data *priv = psmouse->private;
1131 struct input_dev *dev2 = priv->dev2;
1132
1133 if (report_buttons) 1199 if (report_buttons)
1134 alps_report_buttons(psmouse, dev2, psmouse->dev, 1200 alps_report_buttons(dev, NULL,
1135 packet[0] & 1, packet[0] & 2, packet[0] & 4); 1201 packet[0] & 1, packet[0] & 2, packet[0] & 4);
1136 1202
1137 input_report_rel(dev2, REL_X, 1203 input_report_rel(dev, REL_X,
1138 packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0); 1204 packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0);
1139 input_report_rel(dev2, REL_Y, 1205 input_report_rel(dev, REL_Y,
1140 packet[2] ? ((packet[0] << 3) & 0x100) - packet[2] : 0); 1206 packet[2] ? ((packet[0] << 3) & 0x100) - packet[2] : 0);
1141 1207
1142 input_sync(dev2); 1208 input_sync(dev);
1143} 1209}
1144 1210
1145static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse) 1211static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse)
@@ -1204,8 +1270,8 @@ static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse)
1204 * de-synchronization. 1270 * de-synchronization.
1205 */ 1271 */
1206 1272
1207 alps_report_bare_ps2_packet(psmouse, &psmouse->packet[3], 1273 alps_report_bare_ps2_packet(priv->dev2,
1208 false); 1274 &psmouse->packet[3], false);
1209 1275
1210 /* 1276 /*
1211 * Continue with the standard ALPS protocol handling, 1277 * Continue with the standard ALPS protocol handling,
@@ -1261,9 +1327,18 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
1261 * properly we only do this if the device is fully synchronized. 1327 * properly we only do this if the device is fully synchronized.
1262 */ 1328 */
1263 if (!psmouse->out_of_sync_cnt && (psmouse->packet[0] & 0xc8) == 0x08) { 1329 if (!psmouse->out_of_sync_cnt && (psmouse->packet[0] & 0xc8) == 0x08) {
1330
1331 /* Register dev3 mouse if we received PS/2 packet first time */
1332 if (unlikely(!priv->dev3))
1333 psmouse_queue_work(psmouse,
1334 &priv->dev3_register_work, 0);
1335
1264 if (psmouse->pktcnt == 3) { 1336 if (psmouse->pktcnt == 3) {
1265 alps_report_bare_ps2_packet(psmouse, psmouse->packet, 1337 /* Once dev3 mouse device is registered report data */
1266 true); 1338 if (likely(!IS_ERR_OR_NULL(priv->dev3)))
1339 alps_report_bare_ps2_packet(priv->dev3,
1340 psmouse->packet,
1341 true);
1267 return PSMOUSE_FULL_PACKET; 1342 return PSMOUSE_FULL_PACKET;
1268 } 1343 }
1269 return PSMOUSE_GOOD_DATA; 1344 return PSMOUSE_GOOD_DATA;
@@ -2378,7 +2453,10 @@ static void alps_disconnect(struct psmouse *psmouse)
2378 2453
2379 psmouse_reset(psmouse); 2454 psmouse_reset(psmouse);
2380 del_timer_sync(&priv->timer); 2455 del_timer_sync(&priv->timer);
2381 input_unregister_device(priv->dev2); 2456 if (priv->dev2)
2457 input_unregister_device(priv->dev2);
2458 if (!IS_ERR_OR_NULL(priv->dev3))
2459 input_unregister_device(priv->dev3);
2382 kfree(priv); 2460 kfree(priv);
2383} 2461}
2384 2462
@@ -2412,17 +2490,9 @@ static void alps_set_abs_params_mt(struct alps_data *priv,
2412int alps_init(struct psmouse *psmouse) 2490int alps_init(struct psmouse *psmouse)
2413{ 2491{
2414 struct alps_data *priv = psmouse->private; 2492 struct alps_data *priv = psmouse->private;
2415 struct input_dev *dev1 = psmouse->dev, *dev2; 2493 struct input_dev *dev1 = psmouse->dev;
2416 int error; 2494 int error;
2417 2495
2418 dev2 = input_allocate_device();
2419 if (!dev2) {
2420 error = -ENOMEM;
2421 goto init_fail;
2422 }
2423
2424 priv->dev2 = dev2;
2425
2426 error = priv->hw_init(psmouse); 2496 error = priv->hw_init(psmouse);
2427 if (error) 2497 if (error)
2428 goto init_fail; 2498 goto init_fail;
@@ -2474,36 +2544,57 @@ int alps_init(struct psmouse *psmouse)
2474 } 2544 }
2475 2545
2476 if (priv->flags & ALPS_DUALPOINT) { 2546 if (priv->flags & ALPS_DUALPOINT) {
2547 struct input_dev *dev2;
2548
2549 dev2 = input_allocate_device();
2550 if (!dev2) {
2551 psmouse_err(psmouse,
2552 "failed to allocate trackstick device\n");
2553 error = -ENOMEM;
2554 goto init_fail;
2555 }
2556
2557 snprintf(priv->phys2, sizeof(priv->phys2), "%s/input1",
2558 psmouse->ps2dev.serio->phys);
2559 dev2->phys = priv->phys2;
2560
2477 /* 2561 /*
2478 * format of input device name is: "protocol vendor name" 2562 * format of input device name is: "protocol vendor name"
2479 * see function psmouse_switch_protocol() in psmouse-base.c 2563 * see function psmouse_switch_protocol() in psmouse-base.c
2480 */ 2564 */
2481 dev2->name = "AlpsPS/2 ALPS DualPoint Stick"; 2565 dev2->name = "AlpsPS/2 ALPS DualPoint Stick";
2566
2567 dev2->id.bustype = BUS_I8042;
2568 dev2->id.vendor = 0x0002;
2482 dev2->id.product = PSMOUSE_ALPS; 2569 dev2->id.product = PSMOUSE_ALPS;
2483 dev2->id.version = priv->proto_version; 2570 dev2->id.version = priv->proto_version;
2484 } else { 2571 dev2->dev.parent = &psmouse->ps2dev.serio->dev;
2485 dev2->name = "PS/2 ALPS Mouse";
2486 dev2->id.product = PSMOUSE_PS2;
2487 dev2->id.version = 0x0000;
2488 }
2489
2490 snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys);
2491 dev2->phys = priv->phys;
2492 dev2->id.bustype = BUS_I8042;
2493 dev2->id.vendor = 0x0002;
2494 dev2->dev.parent = &psmouse->ps2dev.serio->dev;
2495 2572
2496 dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); 2573 input_set_capability(dev2, EV_REL, REL_X);
2497 dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); 2574 input_set_capability(dev2, EV_REL, REL_Y);
2498 dev2->keybit[BIT_WORD(BTN_LEFT)] = 2575 input_set_capability(dev2, EV_KEY, BTN_LEFT);
2499 BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); 2576 input_set_capability(dev2, EV_KEY, BTN_RIGHT);
2577 input_set_capability(dev2, EV_KEY, BTN_MIDDLE);
2500 2578
2501 __set_bit(INPUT_PROP_POINTER, dev2->propbit); 2579 __set_bit(INPUT_PROP_POINTER, dev2->propbit);
2502 if (priv->flags & ALPS_DUALPOINT)
2503 __set_bit(INPUT_PROP_POINTING_STICK, dev2->propbit); 2580 __set_bit(INPUT_PROP_POINTING_STICK, dev2->propbit);
2504 2581
2505 if (input_register_device(priv->dev2)) 2582 error = input_register_device(dev2);
2506 goto init_fail; 2583 if (error) {
2584 psmouse_err(psmouse,
2585 "failed to register trackstick device: %d\n",
2586 error);
2587 input_free_device(dev2);
2588 goto init_fail;
2589 }
2590
2591 priv->dev2 = dev2;
2592 }
2593
2594 priv->psmouse = psmouse;
2595
2596 INIT_DELAYED_WORK(&priv->dev3_register_work,
2597 alps_register_bare_ps2_mouse);
2507 2598
2508 psmouse->protocol_handler = alps_process_byte; 2599 psmouse->protocol_handler = alps_process_byte;
2509 psmouse->poll = alps_poll; 2600 psmouse->poll = alps_poll;
@@ -2521,7 +2612,6 @@ int alps_init(struct psmouse *psmouse)
2521 2612
2522init_fail: 2613init_fail:
2523 psmouse_reset(psmouse); 2614 psmouse_reset(psmouse);
2524 input_free_device(dev2);
2525 /* 2615 /*
2526 * Even though we did not allocate psmouse->private we do free 2616 * Even though we did not allocate psmouse->private we do free
2527 * it here. 2617 * it here.
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
index c79523562608..02513c0502fc 100644
--- a/drivers/input/mouse/alps.h
+++ b/drivers/input/mouse/alps.h
@@ -141,8 +141,12 @@ struct alps_fields {
141 141
142/** 142/**
143 * struct alps_data - private data structure for the ALPS driver 143 * struct alps_data - private data structure for the ALPS driver
144 * @dev2: "Relative" device used to report trackstick or mouse activity. 144 * @psmouse: Pointer to parent psmouse device
145 * @phys: Physical path for the relative device. 145 * @dev2: Trackstick device (can be NULL).
146 * @dev3: Generic PS/2 mouse (can be NULL, delayed registering).
147 * @phys2: Physical path for the trackstick device.
148 * @phys3: Physical path for the generic PS/2 mouse.
149 * @dev3_register_work: Delayed work for registering PS/2 mouse.
146 * @nibble_commands: Command mapping used for touchpad register accesses. 150 * @nibble_commands: Command mapping used for touchpad register accesses.
147 * @addr_command: Command used to tell the touchpad that a register address 151 * @addr_command: Command used to tell the touchpad that a register address
148 * follows. 152 * follows.
@@ -169,8 +173,12 @@ struct alps_fields {
169 * @timer: Timer for flushing out the final report packet in the stream. 173 * @timer: Timer for flushing out the final report packet in the stream.
170 */ 174 */
171struct alps_data { 175struct alps_data {
176 struct psmouse *psmouse;
172 struct input_dev *dev2; 177 struct input_dev *dev2;
173 char phys[32]; 178 struct input_dev *dev3;
179 char phys2[32];
180 char phys3[32];
181 struct delayed_work dev3_register_work;
174 182
175 /* these are autodetected when the device is identified */ 183 /* these are autodetected when the device is identified */
176 const struct alps_nibble_commands *nibble_commands; 184 const struct alps_nibble_commands *nibble_commands;