From 87826b75d9c6975ca8051985007bdcdf33466034 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 21 Jan 2010 20:53:04 +0530 Subject: tegra: power management for mouse/keyboard drivers Added suspend and resume hooks. tested on harmony bug 642578 Change-Id: I7c5065403e1c5581fce16c6f3653baeb48af5820 --- drivers/input/keyboard/tegra-kbc.c | 48 ++++++++++++++++ drivers/input/keyboard/tegra-nvec.c | 106 +++++++++++++++++++++++++++++++++++- drivers/input/mouse/nvec_mouse.c | 54 +++++++++++++++++- 3 files changed, 204 insertions(+), 4 deletions(-) diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index 980ddf6ef757..ea400bdeadca 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c @@ -224,9 +224,57 @@ static int tegra_kbc_remove(struct platform_device *pdev) return 0; } +static int tegra_kbc_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct tegra_kbc_driver_data *kbc = platform_get_drvdata(pdev); + NvError e = NvError_Success; + + if (!kbc) + return -1; + + if (!kbc->ddkHandle) { + printk("%s: device handle is NULL\n", __func__); + return -1; + } + + /* power down hardware */ + e = NvDdkKbcSuspend(kbc->ddkHandle); + if (e != NvSuccess) { + printk("%s: hardware power down fail\n", __func__); + return -1; + } + + return 0; +} + +static int tegra_kbc_resume(struct platform_device *pdev) +{ + struct tegra_kbc_driver_data *kbc = platform_get_drvdata(pdev); + NvError e = NvError_Success; + + if (!kbc) + return -1; + + if (!kbc->ddkHandle) { + printk("%s: device handle is NULL\n", __func__); + return -1; + } + + /* power up hardware */ + e = NvDdkKbcResume(kbc->ddkHandle); + if (e != NvSuccess) { + printk("%s: hardware power up fail\n", __func__); + return -1; + } + + return 0; +} + static struct platform_driver tegra_kbc_driver = { .probe = tegra_kbc_probe, .remove = tegra_kbc_remove, + .suspend = tegra_kbc_suspend, + .resume = tegra_kbc_resume, .driver = { .name = "tegra_kbc", }, diff --git a/drivers/input/keyboard/tegra-nvec.c b/drivers/input/keyboard/tegra-nvec.c index 586de4ffffdf..7081e92377b3 100644 --- a/drivers/input/keyboard/tegra-nvec.c +++ b/drivers/input/keyboard/tegra-nvec.c @@ -312,7 +312,6 @@ static void nvec_keyboard_close(struct input_dev *dev) return; } - static int __devinit nvec_keyboard_probe(struct platform_device *pdev) { int error; @@ -362,6 +361,12 @@ static int __devinit nvec_keyboard_probe(struct platform_device *pdev) __set_bit(extcode_tab_us102[i], input_dev->keybit); } + /* get EC handle */ + nverr = NvEcOpen(&keyboard->hNvec, 0 /* instance */); + if (nverr != NvError_Success) { + goto fail_input_register; + } + error = input_register_device(keyboard->input_dev); if (error) goto fail_input_register; @@ -374,6 +379,8 @@ fail_thread_create: NvOdmKeyboardDeInit(); fail_keyboard_init: fail: + NvEcClose(keyboard->hNvec); + keyboard->hNvec = NULL; input_free_device(input_dev); kfree(keyboard); @@ -383,16 +390,108 @@ fail: static int __devexit nvec_keyboard_remove(struct platform_device *dev) { struct input_dev *input_dev = platform_get_drvdata(dev); - struct nvec_keyboard *keyboard = platform_get_drvdata(dev); + struct nvec_keyboard *keyboard = input_get_drvdata(input_dev); (void)kthread_stop(keyboard->task); NvOdmKeyboardDeInit(); + NvEcClose(keyboard->hNvec); + keyboard->hNvec = NULL; input_free_device(input_dev); kfree(keyboard); return 0; } +static int nvec_keyboard_suspend(struct platform_device *pdev, pm_message_t state) +{ + NvEcRequest Request = {0}; + NvEcResponse Response = {0}; + struct input_dev *input_dev = platform_get_drvdata(pdev); + struct nvec_keyboard *keyboard = input_get_drvdata(input_dev); + NvError err = NvError_Success; + + if (!keyboard) { + printk("%s: device handle is NULL\n", __func__); + return -1; + } + + /* disable keyboard scanning */ + Request.PacketType = NvEcPacketType_Request; + Request.RequestType = NvEcRequestResponseType_Keyboard; + Request.RequestSubtype = + (NvEcRequestResponseSubtype)NvEcKeyboardSubtype_Disable; + Request.NumPayloadBytes = 0; + + err = NvEcSendRequest( + keyboard->hNvec, + &Request, + &Response, + sizeof(Request), + sizeof(Response)); + if (err != NvError_Success) { + printk("%s: scanning disable request send fail\n", __func__); + return -1; + } + + if (Response.Status != NvEcStatus_Success) { + printk("%s: scanning could not be disabled\n", __func__); + return -1; + } + + /* power down hardware */ + if (!NvOdmKeyboardPowerHandler(NV_TRUE)) { + printk("%s: hardware power down fail\n", __func__); + return -1; + } + + return 0; +} + +static int nvec_keyboard_resume(struct platform_device *pdev) +{ + NvEcRequest Request = {0}; + NvEcResponse Response = {0}; + struct input_dev *input_dev = platform_get_drvdata(pdev); + struct nvec_keyboard *keyboard = input_get_drvdata(input_dev); + NvError err = NvError_Success; + + if (!keyboard) { + printk("%s: device handle is NULL\n", __func__); + return -1; + } + + /* power up hardware */ + if (!NvOdmKeyboardPowerHandler(NV_FALSE)) { + printk("%s: hardware power up fail\n", __func__); + return -1; + } + + /* re-enable keyboard scanning */ + Request.PacketType = NvEcPacketType_Request; + Request.RequestType = NvEcRequestResponseType_Keyboard; + Request.RequestSubtype = + (NvEcRequestResponseSubtype)NvEcKeyboardSubtype_Enable; + Request.NumPayloadBytes = 0; + + err = NvEcSendRequest( + keyboard->hNvec, + &Request, + &Response, + sizeof(Request), + sizeof(Response)); + if (err != NvError_Success) { + printk("%s: scanning enable request send fail\n", __func__); + return -1; + } + + if (Response.Status != NvEcStatus_Success) { + printk("%s: scanning could not be enabled\n", __func__); + return -1; + } + + return 0; +} + static struct platform_driver nvec_keyboard_driver = { .driver = { .name = "nvec_keyboard", @@ -400,9 +499,10 @@ static struct platform_driver nvec_keyboard_driver = { }, .probe = nvec_keyboard_probe, .remove = __devexit_p(nvec_keyboard_remove), + .suspend = nvec_keyboard_suspend, + .resume = nvec_keyboard_resume, }; - static int __init nvec_keyboard_init(void) { int err; diff --git a/drivers/input/mouse/nvec_mouse.c b/drivers/input/mouse/nvec_mouse.c index 7bf09627505d..2d66070aa498 100644 --- a/drivers/input/mouse/nvec_mouse.c +++ b/drivers/input/mouse/nvec_mouse.c @@ -304,6 +304,7 @@ static int __devinit nvec_mouse_probe(struct platform_device *pdev) printk("**nvec_mouse_probe\n"); mouse = kzalloc(sizeof(struct nvec_mouse), GFP_KERNEL); + memset(mouse, 0, sizeof(struct nvec_mouse)); input_dev = input_allocate_device(); if (!mouse || !input_dev) { printk("**nvec_mouse_probe: input_allocate_device: fail\n"); @@ -397,12 +398,15 @@ fail_input_register: (void)kthread_stop(mouse->task); fail_thread_create: NvOdmOsSemaphoreDestroy(mouse->semaphore); + mouse->semaphore = NULL; fail_semaphore_create: fail_no_mouse_found: NvOdmMouseDeviceClose(mouse->hDevice); + mouse->hDevice = NULL; fail: input_free_device(input_dev); kfree(mouse); + mouse = NULL; return error; } @@ -415,14 +419,61 @@ static int __devexit nvec_mouse_remove(struct platform_device *dev) printk("**nvec_mouse_remove\n"); (void)kthread_stop(mouse->task); NvOdmOsSemaphoreDestroy(mouse->semaphore); + mouse->semaphore = NULL; NvOdmMouseDeviceClose(mouse->hDevice); + mouse->hDevice = NULL; input_free_device(input_dev); kfree(mouse); + mouse = NULL; printk("**nvec_mouse_remove end\n"); return 0; } +static int nvec_mouse_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct input_dev *input_dev = platform_get_drvdata(pdev); + struct nvec_mouse *mouse = input_get_drvdata(input_dev); + + if (!mouse) + return -1; + + if (!mouse->hDevice) { + printk("%s: device handle NULL\n", __func__); + return -1; + } + + /* power down hardware */ + if (!NvOdmMousePowerSuspend(mouse->hDevice)) { + printk("%s: hardware power down fail\n", __func__); + return -1; + } + + return 0; +} + +static int nvec_mouse_resume(struct platform_device *pdev) +{ + struct input_dev *input_dev = platform_get_drvdata(pdev); + struct nvec_mouse *mouse = input_get_drvdata(input_dev); + + if (!mouse) + return -1; + + if (!mouse->hDevice) { + printk("%s: device handle NULL\n", __func__); + return -1; + } + + /* power up hardware */ + if (!NvOdmMousePowerResume(mouse->hDevice)) { + printk("%s: hardware power up fail\n", __func__); + return -1; + } + + return 0; +} + static struct platform_driver nvec_mouse_driver = { .driver = { .name = "nvec_mouse", @@ -430,9 +481,10 @@ static struct platform_driver nvec_mouse_driver = { }, .probe = nvec_mouse_probe, .remove = __devexit_p(nvec_mouse_remove), + .suspend = nvec_mouse_suspend, + .resume = nvec_mouse_resume, }; - static int __init nvec_mouse_init(void) { int err; -- cgit v1.2.3