aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/mouse/alps.c78
1 files changed, 56 insertions, 22 deletions
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index b97832b622cb..d164690bfdf7 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -1796,7 +1796,7 @@ static int alps_setup_trackstick_v3(struct psmouse *psmouse, int reg_base)
1796 * all. 1796 * all.
1797 */ 1797 */
1798 if (alps_rpt_cmd(psmouse, 0, PSMOUSE_CMD_SETSCALE21, param)) { 1798 if (alps_rpt_cmd(psmouse, 0, PSMOUSE_CMD_SETSCALE21, param)) {
1799 psmouse_warn(psmouse, "trackstick E7 report failed\n"); 1799 psmouse_warn(psmouse, "Failed to initialize trackstick (E7 report failed)\n");
1800 ret = -ENODEV; 1800 ret = -ENODEV;
1801 } else { 1801 } else {
1802 psmouse_dbg(psmouse, "trackstick E7 report: %3ph\n", param); 1802 psmouse_dbg(psmouse, "trackstick E7 report: %3ph\n", param);
@@ -1961,8 +1961,6 @@ static int alps_hw_init_rushmore_v3(struct psmouse *psmouse)
1961 ALPS_REG_BASE_RUSHMORE); 1961 ALPS_REG_BASE_RUSHMORE);
1962 if (reg_val == -EIO) 1962 if (reg_val == -EIO)
1963 goto error; 1963 goto error;
1964 if (reg_val == -ENODEV)
1965 priv->flags &= ~ALPS_DUALPOINT;
1966 } 1964 }
1967 1965
1968 if (alps_enter_command_mode(psmouse) || 1966 if (alps_enter_command_mode(psmouse) ||
@@ -2305,6 +2303,7 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
2305{ 2303{
2306 const struct alps_protocol_info *protocol; 2304 const struct alps_protocol_info *protocol;
2307 unsigned char e6[4], e7[4], ec[4]; 2305 unsigned char e6[4], e7[4], ec[4];
2306 int error;
2308 2307
2309 /* 2308 /*
2310 * First try "E6 report". 2309 * First try "E6 report".
@@ -2350,10 +2349,15 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
2350 } 2349 }
2351 } 2350 }
2352 2351
2353 /* Save the Firmware version */ 2352 if (priv) {
2354 memcpy(priv->fw_ver, ec, 3); 2353 /* Save the Firmware version */
2354 memcpy(priv->fw_ver, ec, 3);
2355 error = alps_set_protocol(psmouse, priv, protocol);
2356 if (error)
2357 return error;
2358 }
2355 2359
2356 return alps_set_protocol(psmouse, priv, protocol); 2360 return 0;
2357} 2361}
2358 2362
2359static int alps_reconnect(struct psmouse *psmouse) 2363static int alps_reconnect(struct psmouse *psmouse)
@@ -2407,22 +2411,20 @@ static void alps_set_abs_params_mt(struct alps_data *priv,
2407 2411
2408int alps_init(struct psmouse *psmouse) 2412int alps_init(struct psmouse *psmouse)
2409{ 2413{
2410 struct alps_data *priv; 2414 struct alps_data *priv = psmouse->private;
2411 struct input_dev *dev1 = psmouse->dev, *dev2; 2415 struct input_dev *dev1 = psmouse->dev, *dev2;
2416 int error;
2412 2417
2413 priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL);
2414 dev2 = input_allocate_device(); 2418 dev2 = input_allocate_device();
2415 if (!priv || !dev2) 2419 if (!dev2) {
2420 error = -ENOMEM;
2416 goto init_fail; 2421 goto init_fail;
2422 }
2417 2423
2418 priv->dev2 = dev2; 2424 priv->dev2 = dev2;
2419 2425
2420 psmouse_reset(psmouse); 2426 error = priv->hw_init(psmouse);
2421 2427 if (error)
2422 if (alps_identify(psmouse, priv) < 0)
2423 goto init_fail;
2424
2425 if (priv->hw_init(psmouse))
2426 goto init_fail; 2428 goto init_fail;
2427 2429
2428 /* 2430 /*
@@ -2520,24 +2522,56 @@ int alps_init(struct psmouse *psmouse)
2520init_fail: 2522init_fail:
2521 psmouse_reset(psmouse); 2523 psmouse_reset(psmouse);
2522 input_free_device(dev2); 2524 input_free_device(dev2);
2523 kfree(priv); 2525 /*
2526 * Even though we did not allocate psmouse->private we do free
2527 * it here.
2528 */
2529 kfree(psmouse->private);
2524 psmouse->private = NULL; 2530 psmouse->private = NULL;
2525 return -1; 2531 return error;
2526} 2532}
2527 2533
2528int alps_detect(struct psmouse *psmouse, bool set_properties) 2534int alps_detect(struct psmouse *psmouse, bool set_properties)
2529{ 2535{
2530 struct alps_data dummy; 2536 struct alps_data *priv;
2537 int error;
2531 2538
2532 if (alps_identify(psmouse, &dummy) < 0) 2539 error = alps_identify(psmouse, NULL);
2533 return -1; 2540 if (error)
2541 return error;
2542
2543 /*
2544 * Reset the device to make sure it is fully operational:
2545 * on some laptops, like certain Dell Latitudes, we may
2546 * fail to properly detect presence of trackstick if device
2547 * has not been reset.
2548 */
2549 psmouse_reset(psmouse);
2550
2551 priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL);
2552 if (!priv)
2553 return -ENOMEM;
2554
2555 error = alps_identify(psmouse, priv);
2556 if (error)
2557 return error;
2534 2558
2535 if (set_properties) { 2559 if (set_properties) {
2536 psmouse->vendor = "ALPS"; 2560 psmouse->vendor = "ALPS";
2537 psmouse->name = dummy.flags & ALPS_DUALPOINT ? 2561 psmouse->name = priv->flags & ALPS_DUALPOINT ?
2538 "DualPoint TouchPad" : "GlidePoint"; 2562 "DualPoint TouchPad" : "GlidePoint";
2539 psmouse->model = dummy.proto_version; 2563 psmouse->model = priv->proto_version;
2564 } else {
2565 /*
2566 * Destroy alps_data structure we allocated earlier since
2567 * this was just a "trial run". Otherwise we'll keep it
2568 * to be used by alps_init() which has to be called if
2569 * we succeed and set_properties is true.
2570 */
2571 kfree(priv);
2572 psmouse->private = NULL;
2540 } 2573 }
2574
2541 return 0; 2575 return 0;
2542} 2576}
2543 2577