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 | } |