Skip to content

Commit 04aae28

Browse files
palidtor
authored andcommitted
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>
1 parent a09221e commit 04aae28

File tree

2 files changed

+151
-53
lines changed

2 files changed

+151
-53
lines changed

drivers/input/mouse/alps.c

Lines changed: 140 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,7 @@ static bool alps_is_valid_first_byte(struct alps_data *priv,
165165
return (data & priv->mask0) == priv->byte0;
166166
}
167167

168-
static void alps_report_buttons(struct psmouse *psmouse,
169-
struct input_dev *dev1, struct input_dev *dev2,
168+
static void alps_report_buttons(struct input_dev *dev1, struct input_dev *dev2,
170169
int left, int right, int middle)
171170
{
172171
struct input_dev *dev;
@@ -176,20 +175,21 @@ static void alps_report_buttons(struct psmouse *psmouse,
176175
* other device (dev2) then this event should be also
177176
* sent through that device.
178177
*/
179-
dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1;
178+
dev = (dev2 && test_bit(BTN_LEFT, dev2->key)) ? dev2 : dev1;
180179
input_report_key(dev, BTN_LEFT, left);
181180

182-
dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1;
181+
dev = (dev2 && test_bit(BTN_RIGHT, dev2->key)) ? dev2 : dev1;
183182
input_report_key(dev, BTN_RIGHT, right);
184183

185-
dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1;
184+
dev = (dev2 && test_bit(BTN_MIDDLE, dev2->key)) ? dev2 : dev1;
186185
input_report_key(dev, BTN_MIDDLE, middle);
187186

188187
/*
189188
* Sync the _other_ device now, we'll do the first
190189
* device later once we report the rest of the events.
191190
*/
192-
input_sync(dev2);
191+
if (dev2)
192+
input_sync(dev2);
193193
}
194194

195195
static void alps_process_packet_v1_v2(struct psmouse *psmouse)
@@ -236,13 +236,13 @@ static void alps_process_packet_v1_v2(struct psmouse *psmouse)
236236
input_report_rel(dev2, REL_X, (x > 383 ? (x - 768) : x));
237237
input_report_rel(dev2, REL_Y, -(y > 255 ? (y - 512) : y));
238238

239-
alps_report_buttons(psmouse, dev2, dev, left, right, middle);
239+
alps_report_buttons(dev2, dev, left, right, middle);
240240

241241
input_sync(dev2);
242242
return;
243243
}
244244

245-
alps_report_buttons(psmouse, dev, dev2, left, right, middle);
245+
alps_report_buttons(dev, dev2, left, right, middle);
246246

247247
/* Convert hardware tap to a reasonable Z value */
248248
if (ges && !fin)
@@ -1123,23 +1123,89 @@ static void alps_process_packet_v7(struct psmouse *psmouse)
11231123
alps_process_touchpad_packet_v7(psmouse);
11241124
}
11251125

1126-
static void alps_report_bare_ps2_packet(struct psmouse *psmouse,
1126+
static DEFINE_MUTEX(alps_mutex);
1127+
1128+
static 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+
1184+
out:
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+
1195+
static void alps_report_bare_ps2_packet(struct input_dev *dev,
11271196
unsigned char packet[],
11281197
bool report_buttons)
11291198
{
1130-
struct alps_data *priv = psmouse->private;
1131-
struct input_dev *dev2 = priv->dev2;
1132-
11331199
if (report_buttons)
1134-
alps_report_buttons(psmouse, dev2, psmouse->dev,
1200+
alps_report_buttons(dev, NULL,
11351201
packet[0] & 1, packet[0] & 2, packet[0] & 4);
11361202

1137-
input_report_rel(dev2, REL_X,
1203+
input_report_rel(dev, REL_X,
11381204
packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0);
1139-
input_report_rel(dev2, REL_Y,
1205+
input_report_rel(dev, REL_Y,
11401206
packet[2] ? ((packet[0] << 3) & 0x100) - packet[2] : 0);
11411207

1142-
input_sync(dev2);
1208+
input_sync(dev);
11431209
}
11441210

11451211
static 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)
12041270
* de-synchronization.
12051271
*/
12061272

1207-
alps_report_bare_ps2_packet(psmouse, &psmouse->packet[3],
1208-
false);
1273+
alps_report_bare_ps2_packet(priv->dev2,
1274+
&psmouse->packet[3], false);
12091275

12101276
/*
12111277
* Continue with the standard ALPS protocol handling,
@@ -1261,9 +1327,18 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
12611327
* properly we only do this if the device is fully synchronized.
12621328
*/
12631329
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+
12641336
if (psmouse->pktcnt == 3) {
1265-
alps_report_bare_ps2_packet(psmouse, psmouse->packet,
1266-
true);
1337+
/* Once dev3 mouse device is registered report data */
1338+
if (likely(!IS_ERR_OR_NULL(priv->dev3)))
1339+
alps_report_bare_ps2_packet(priv->dev3,
1340+
psmouse->packet,
1341+
true);
12671342
return PSMOUSE_FULL_PACKET;
12681343
}
12691344
return PSMOUSE_GOOD_DATA;
@@ -2378,7 +2453,10 @@ static void alps_disconnect(struct psmouse *psmouse)
23782453

23792454
psmouse_reset(psmouse);
23802455
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);
23822460
kfree(priv);
23832461
}
23842462

@@ -2412,17 +2490,9 @@ static void alps_set_abs_params_mt(struct alps_data *priv,
24122490
int alps_init(struct psmouse *psmouse)
24132491
{
24142492
struct alps_data *priv = psmouse->private;
2415-
struct input_dev *dev1 = psmouse->dev, *dev2;
2493+
struct input_dev *dev1 = psmouse->dev;
24162494
int error;
24172495

2418-
dev2 = input_allocate_device();
2419-
if (!dev2) {
2420-
error = -ENOMEM;
2421-
goto init_fail;
2422-
}
2423-
2424-
priv->dev2 = dev2;
2425-
24262496
error = priv->hw_init(psmouse);
24272497
if (error)
24282498
goto init_fail;
@@ -2474,36 +2544,57 @@ int alps_init(struct psmouse *psmouse)
24742544
}
24752545

24762546
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+
24772561
/*
24782562
* format of input device name is: "protocol vendor name"
24792563
* see function psmouse_switch_protocol() in psmouse-base.c
24802564
*/
24812565
dev2->name = "AlpsPS/2 ALPS DualPoint Stick";
2566+
2567+
dev2->id.bustype = BUS_I8042;
2568+
dev2->id.vendor = 0x0002;
24822569
dev2->id.product = PSMOUSE_ALPS;
24832570
dev2->id.version = priv->proto_version;
2484-
} else {
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;
2571+
dev2->dev.parent = &psmouse->ps2dev.serio->dev;
24952572

2496-
dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
2497-
dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
2498-
dev2->keybit[BIT_WORD(BTN_LEFT)] =
2499-
BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
2573+
input_set_capability(dev2, EV_REL, REL_X);
2574+
input_set_capability(dev2, EV_REL, REL_Y);
2575+
input_set_capability(dev2, EV_KEY, BTN_LEFT);
2576+
input_set_capability(dev2, EV_KEY, BTN_RIGHT);
2577+
input_set_capability(dev2, EV_KEY, BTN_MIDDLE);
25002578

2501-
__set_bit(INPUT_PROP_POINTER, dev2->propbit);
2502-
if (priv->flags & ALPS_DUALPOINT)
2579+
__set_bit(INPUT_PROP_POINTER, dev2->propbit);
25032580
__set_bit(INPUT_PROP_POINTING_STICK, dev2->propbit);
25042581

2505-
if (input_register_device(priv->dev2))
2506-
goto init_fail;
2582+
error = input_register_device(dev2);
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);
25072598

25082599
psmouse->protocol_handler = alps_process_byte;
25092600
psmouse->poll = alps_poll;
@@ -2521,7 +2612,6 @@ int alps_init(struct psmouse *psmouse)
25212612

25222613
init_fail:
25232614
psmouse_reset(psmouse);
2524-
input_free_device(dev2);
25252615
/*
25262616
* Even though we did not allocate psmouse->private we do free
25272617
* it here.

drivers/input/mouse/alps.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,12 @@ struct alps_fields {
141141

142142
/**
143143
* struct alps_data - private data structure for the ALPS driver
144-
* @dev2: "Relative" device used to report trackstick or mouse activity.
145-
* @phys: Physical path for the relative device.
144+
* @psmouse: Pointer to parent psmouse 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.
146150
* @nibble_commands: Command mapping used for touchpad register accesses.
147151
* @addr_command: Command used to tell the touchpad that a register address
148152
* follows.
@@ -169,8 +173,12 @@ struct alps_fields {
169173
* @timer: Timer for flushing out the final report packet in the stream.
170174
*/
171175
struct alps_data {
176+
struct psmouse *psmouse;
172177
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;
174182

175183
/* these are autodetected when the device is identified */
176184
const struct alps_nibble_commands *nibble_commands;

0 commit comments

Comments
 (0)