diff options
| author | Paul Fox <pgf@laptop.org> | 2010-11-15 04:33:24 -0500 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-11-15 04:33:59 -0500 |
| commit | 20a4c261ad9cec39942257b1f91765a4b238db05 (patch) | |
| tree | 8c1101136cb11760c0ba8c1559e65f04bb5cce7a /drivers/input/mouse | |
| parent | 34caed2082105a6d9f5aaba1cf4e02760cbee14e (diff) | |
Input: hgpk - fix powersave mode
Recent testing of this codepath showed that it wasn't working,
perhaps due to changes within the input layer. This fixes it.
Signed-off-by: Daniel Drake <dsd@laptop.org>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/mouse')
| -rw-r--r-- | drivers/input/mouse/hgpk.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index 1beb5da4f0f3..95577c15ae56 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c | |||
| @@ -689,11 +689,15 @@ static int hgpk_force_recalibrate(struct psmouse *psmouse) | |||
| 689 | } | 689 | } |
| 690 | 690 | ||
| 691 | /* | 691 | /* |
| 692 | * This kills power to the touchpad; according to ALPS, current consumption | 692 | * This puts the touchpad in a power saving mode; according to ALPS, current |
| 693 | * goes down to 50uA after running this. To turn power back on, we drive | 693 | * consumption goes down to 50uA after running this. To turn power back on, |
| 694 | * MS-DAT low. | 694 | * we drive MS-DAT low. Measuring with a 1mA resolution ammeter says that |
| 695 | * the current on the SUS_3.3V rail drops from 3mA or 4mA to 0 when we do this. | ||
| 696 | * | ||
| 697 | * We have no formal spec that details this operation -- the low-power | ||
| 698 | * sequence came from a long-lost email trail. | ||
| 695 | */ | 699 | */ |
| 696 | static int hgpk_toggle_power(struct psmouse *psmouse, int enable) | 700 | static int hgpk_toggle_powersave(struct psmouse *psmouse, int enable) |
| 697 | { | 701 | { |
| 698 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 702 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
| 699 | int timeo; | 703 | int timeo; |
| @@ -711,13 +715,13 @@ static int hgpk_toggle_power(struct psmouse *psmouse, int enable) | |||
| 711 | * the controller. Once we get an ACK back from it, it | 715 | * the controller. Once we get an ACK back from it, it |
| 712 | * means we can continue with the touchpad re-init. ALPS | 716 | * means we can continue with the touchpad re-init. ALPS |
| 713 | * tells us that 1s should be long enough, so set that as | 717 | * tells us that 1s should be long enough, so set that as |
| 714 | * the upper bound. | 718 | * the upper bound. (in practice, it takes about 3 loops.) |
| 715 | */ | 719 | */ |
| 716 | for (timeo = 20; timeo > 0; timeo--) { | 720 | for (timeo = 20; timeo > 0; timeo--) { |
| 717 | if (!ps2_sendbyte(&psmouse->ps2dev, | 721 | if (!ps2_sendbyte(&psmouse->ps2dev, |
| 718 | PSMOUSE_CMD_DISABLE, 20)) | 722 | PSMOUSE_CMD_DISABLE, 20)) |
| 719 | break; | 723 | break; |
| 720 | msleep(50); | 724 | msleep(25); |
| 721 | } | 725 | } |
| 722 | 726 | ||
| 723 | err = hgpk_reset_device(psmouse, false); | 727 | err = hgpk_reset_device(psmouse, false); |
| @@ -729,10 +733,9 @@ static int hgpk_toggle_power(struct psmouse *psmouse, int enable) | |||
| 729 | /* should be all set, enable the touchpad */ | 733 | /* should be all set, enable the touchpad */ |
| 730 | ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE); | 734 | ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE); |
| 731 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); | 735 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); |
| 732 | 736 | hgpk_dbg(psmouse, "Touchpad powered up.\n"); | |
| 733 | } else { | 737 | } else { |
| 734 | hgpk_dbg(psmouse, "Powering off touchpad.\n"); | 738 | hgpk_dbg(psmouse, "Powering off touchpad.\n"); |
| 735 | psmouse_set_state(psmouse, PSMOUSE_IGNORE); | ||
| 736 | 739 | ||
| 737 | if (ps2_command(ps2dev, NULL, 0xec) || | 740 | if (ps2_command(ps2dev, NULL, 0xec) || |
| 738 | ps2_command(ps2dev, NULL, 0xec) || | 741 | ps2_command(ps2dev, NULL, 0xec) || |
| @@ -740,6 +743,8 @@ static int hgpk_toggle_power(struct psmouse *psmouse, int enable) | |||
| 740 | return -1; | 743 | return -1; |
| 741 | } | 744 | } |
| 742 | 745 | ||
| 746 | psmouse_set_state(psmouse, PSMOUSE_IGNORE); | ||
| 747 | |||
| 743 | /* probably won't see an ACK, the touchpad will be off */ | 748 | /* probably won't see an ACK, the touchpad will be off */ |
| 744 | ps2_sendbyte(&psmouse->ps2dev, 0xec, 20); | 749 | ps2_sendbyte(&psmouse->ps2dev, 0xec, 20); |
| 745 | } | 750 | } |
| @@ -755,6 +760,8 @@ static int hgpk_poll(struct psmouse *psmouse) | |||
| 755 | 760 | ||
| 756 | static int hgpk_reconnect(struct psmouse *psmouse) | 761 | static int hgpk_reconnect(struct psmouse *psmouse) |
| 757 | { | 762 | { |
| 763 | struct hgpk_data *priv = psmouse->private; | ||
| 764 | |||
| 758 | /* | 765 | /* |
| 759 | * During suspend/resume the ps2 rails remain powered. We don't want | 766 | * During suspend/resume the ps2 rails remain powered. We don't want |
| 760 | * to do a reset because it's flush data out of buffers; however, | 767 | * to do a reset because it's flush data out of buffers; however, |
| @@ -765,6 +772,7 @@ static int hgpk_reconnect(struct psmouse *psmouse) | |||
| 765 | PM_EVENT_ON) | 772 | PM_EVENT_ON) |
| 766 | return 0; | 773 | return 0; |
| 767 | 774 | ||
| 775 | priv->powered = 1; | ||
| 768 | return hgpk_reset_device(psmouse, false); | 776 | return hgpk_reset_device(psmouse, false); |
| 769 | } | 777 | } |
| 770 | 778 | ||
| @@ -791,7 +799,7 @@ static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data, | |||
| 791 | * hgpk_toggle_power will deal w/ state so | 799 | * hgpk_toggle_power will deal w/ state so |
| 792 | * we're not racing w/ irq | 800 | * we're not racing w/ irq |
| 793 | */ | 801 | */ |
| 794 | err = hgpk_toggle_power(psmouse, value); | 802 | err = hgpk_toggle_powersave(psmouse, value); |
| 795 | if (!err) | 803 | if (!err) |
| 796 | priv->powered = value; | 804 | priv->powered = value; |
| 797 | } | 805 | } |
