summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorGary King <gking@nvidia.com>2010-02-09 20:00:25 -0800
committerGerrit Code Review <gerrit2@git-master-01.nvidia.com>2010-02-09 20:00:25 -0800
commit7d1617c9c1b0cdcd2e97d7cf1641d9c79d3692bf (patch)
treef18d3aa2558ca8485a3d2c543e95779e32a1c2f7 /drivers
parent7471c8873c7d9e3a461818177abe0b29252ef95a (diff)
parent8665c535e1ff59058b647f9edeb714a6b381877d (diff)
Merge "tegra: Add early_suspend and late_resume hooks to touch-screen driver" into android-tegra-2.6.29
Diffstat (limited to 'drivers')
-rwxr-xr-xdrivers/input/touchscreen/tegra_odm.c75
1 files changed, 74 insertions, 1 deletions
diff --git a/drivers/input/touchscreen/tegra_odm.c b/drivers/input/touchscreen/tegra_odm.c
index bd0d1a71ebad..6581fea05ce9 100755
--- a/drivers/input/touchscreen/tegra_odm.c
+++ b/drivers/input/touchscreen/tegra_odm.c
@@ -25,6 +25,8 @@
#include <linux/platform_device.h>
#include <linux/kthread.h>
#include <linux/delay.h>
+#include <linux/earlysuspend.h>
+#include <linux/freezer.h>
#include <nvodm_services.h>
#include <nvodm_touch.h>
@@ -42,12 +44,66 @@ struct tegra_touch_driver_data
NvU32 MinX;
NvU32 MaxY;
NvU32 MinY;
+ int shutdown;
+ struct early_suspend early_suspend;
};
#define NVODM_TOUCH_NAME "nvodm_touch"
#define swapv(x, y) do { typeof(x) z = x; x = y; y = z; } while (0)
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void tegra_touch_early_suspend(struct early_suspend *es)
+{
+ struct tegra_touch_driver_data *touch;
+ touch = container_of(es, struct tegra_touch_driver_data, early_suspend);
+
+ if (touch && touch->hTouchDevice) {
+ NvOdmTouchPowerOnOff(touch->hTouchDevice, NV_FALSE);
+ }
+ else {
+ pr_err("tegra_touch_early_suspend: NULL handles passed\n");
+ }
+}
+
+static void tegra_touch_late_resume(struct early_suspend *es)
+{
+ struct tegra_touch_driver_data *touch;
+ touch = container_of(es, struct tegra_touch_driver_data, early_suspend);
+
+ if (touch && touch->hTouchDevice) {
+ NvOdmTouchPowerOnOff(touch->hTouchDevice, NV_TRUE);
+ }
+ else {
+ pr_err("tegra_touch_late_resume: NULL handles passed\n");
+ }
+}
+#else
+static int tegra_touch_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct tegra_touch_driver_data *touch = platform_get_drvdata(input_dev);
+
+ if (touch && touch->hTouchDevice) {
+ NvOdmTouchPowerOnOff(touch->hTouchDevice, NV_FALSE);
+ return 0;
+ }
+ pr_err("tegra_touch_suspend: NULL handles passed\n");
+ return -1;
+}
+
+static int tegra_touch_resume(struct platform_device *pdev)
+{
+ struct tegra_touch_driver_data *touch = platform_get_drvdata(pdev);
+
+ if (touch && touch->hTouchDevice) {
+ NvOdmTouchPowerOnOff(touch->hTouchDevice, NV_TRUE);
+ return 0;
+ }
+ pr_err("tegra_touch_resume: NULL handles passed\n");
+ return -1;
+}
+#endif
+
static int tegra_touch_thread(void *pdata)
{
struct tegra_touch_driver_data *touch =
@@ -60,6 +116,9 @@ static int tegra_touch_thread(void *pdata)
NvOdmTouchCapabilities *caps = &touch->caps;
NvU32 max_fingers = caps->MaxNumberOfFingerCoordReported;
+ /* touch event thread should be frozen before suspend */
+ set_freezable_with_signal();
+
for (;;) {
if (touch->bPollingMode)
msleep(touch->pollingIntervalMS);
@@ -274,8 +333,14 @@ static int __init tegra_touch_probe(struct platform_device *pdev)
goto err_input_register_device_failed;
}
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ touch->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+ touch->early_suspend.suspend = tegra_touch_early_suspend;
+ touch->early_suspend.resume = tegra_touch_late_resume;
+ register_early_suspend(&touch->early_suspend);
+#endif
printk(KERN_INFO NVODM_TOUCH_NAME
- ": Successfully registered the ODM touch driver\n");
+ ": Successfully registered the ODM touch driver %x\n", touch->hTouchDevice);
return 0;
err_input_register_device_failed:
@@ -294,6 +359,10 @@ static int tegra_touch_remove(struct platform_device *pdev)
{
struct tegra_touch_driver_data *touch = platform_get_drvdata(pdev);
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ unregister_early_suspend(&touch->early_suspend);
+#endif
+ touch->shutdown = 1;
/* FIXME How to destroy the thread? Maybe we should use workqueues? */
input_unregister_device(touch->input_dev);
/* NvOsSemaphoreDestroy(touch->semaphore); */
@@ -305,6 +374,10 @@ static int tegra_touch_remove(struct platform_device *pdev)
static struct platform_driver tegra_touch_driver = {
.probe = tegra_touch_probe,
.remove = tegra_touch_remove,
+#ifndef CONFIG_HAS_EARLYSUSPEND
+ .suspend = tegra_touch_suspend,
+ .resume = tegra_touch_resume,
+#endif
.driver = {
.name = "tegra_touch",
},