summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNinad Malwade <nmalwade@nvidia.com>2010-02-26 13:54:32 +0530
committerNinad Malwade <nmalwade@nvidia.com>2010-02-26 14:19:05 +0530
commit92891e2ab3df0eafc3f064c410d8ac47187ccb07 (patch)
treeaf90e4b0c5db5d2d6a461987f7b301a42871b935
parent18af2d21101948f32922b18cb9057c9708b288b9 (diff)
tegra NVEC: Bus driver architecture for nvec drivers
- nvec_user is the bus driver - tegra-nvec [keyboard], nvec_mouse [touchpad], nvec_battery are the client drivers for nvec. - verified: suspend-resume ordering: This is synchronous now. - Issues: after few suspend-resume EC is failed to suspend. [working on this issue] - Bug 648447 - Adding device_unregister for nvec bus driver. Change-Id: I3c30ceb50a89f67d71050089766897bd7691848d
-rw-r--r--arch/arm/mach-tegra/include/nvec_device.h81
-rw-r--r--arch/arm/mach-tegra/nvec_user.c648
-rw-r--r--drivers/input/keyboard/tegra-nvec.c76
-rw-r--r--drivers/input/mouse/nvec_mouse.c986
-rw-r--r--drivers/power/nvec_battery.c61
5 files changed, 1004 insertions, 848 deletions
diff --git a/arch/arm/mach-tegra/include/nvec_device.h b/arch/arm/mach-tegra/include/nvec_device.h
new file mode 100644
index 000000000000..71c1f761906b
--- /dev/null
+++ b/arch/arm/mach-tegra/include/nvec_device.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_NVEC_DEVICE_H
+#define INCLUDED_NVEC_DEVICE_H
+
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+#define nvec_get_drvdata(f) dev_get_drvdata(&(f)->dev)
+#define nvec_set_drvdata(f,d) dev_set_drvdata(&(f)->dev, d)
+
+struct nvec_driver;
+
+struct nvec_device {
+ char *name;
+ struct device *parent;
+ struct device dev;
+ struct bus_type *bus; /* type of bus device is on */
+ struct nvec_driver *driver; /* which driver has allocated this
+ device */
+};
+
+extern int nvec_register_device(struct nvec_device *pdev);
+extern void nvec_unregister_device(struct nvec_device *pdev);
+
+/*
+ * NVEC function device driver
+ */
+struct nvec_driver {
+ char *name;
+ struct device_driver driver;
+ struct device dev;
+
+ int (*probe)(struct nvec_device *);
+ void (*remove)(struct nvec_device *);
+
+ int (*suspend)(struct nvec_device *dev, pm_message_t state);
+ int (*resume)(struct nvec_device *dev);
+};
+
+extern int nvec_register_driver(struct nvec_driver *);
+extern void nvec_unregister_driver(struct nvec_driver *);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // INCLUDED_NVEC_DEVICE_H
diff --git a/arch/arm/mach-tegra/nvec_user.c b/arch/arm/mach-tegra/nvec_user.c
index b11c00e0c0c4..8ee0240b219a 100644
--- a/arch/arm/mach-tegra/nvec_user.c
+++ b/arch/arm/mach-tegra/nvec_user.c
@@ -1,271 +1,377 @@
-/*
- * arch/arm/mach-tegra/nvec_user.c
- *
- * User-land access to NvEc embedded controller features
- *
- * Copyright (c) 2008-2009, NVIDIA Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <linux/module.h>
-#include <linux/proc_fs.h>
-#include <linux/platform_device.h>
-#include <linux/miscdevice.h>
-#include "linux/nvos_ioctl.h"
-#include "nvec.h"
-#include "linux/nvec_ioctls.h"
-#include "nvreftrack.h"
-#include "nvassert.h"
-
-static NvRtHandle s_RtHandle = NULL;
-
-NvError NvECPackage_Dispatch(void *InBuffer, NvU32 InSize, void *OutBuffer,
- NvU32 OutSize, NvDispatchCtx* Ctx);
-
-static int nvec_open(struct inode *inode, struct file *file);
-static int nvec_close(struct inode *inode, struct file *file);
-static long nvec_unlocked_ioctl(struct file *file,
- unsigned int cmd, unsigned long arg);
-
-int nvec_open(struct inode *inode, struct file *file)
-{
- NvRtClientHandle Client;
-
- if (NvRtRegisterClient(s_RtHandle, &Client) != NvSuccess)
- return -ENOMEM;
-
- file->private_data = (void*)Client;
- return 0;
-}
-
-int nvec_close(struct inode *inode, struct file *file)
-{
- NvRtClientHandle client = (NvRtClientHandle)file->private_data;
-
- if (NvRtUnregisterClient(s_RtHandle, client)) {
- NvDispatchCtx dctx;
-
- dctx.Rt = s_RtHandle;
- dctx.Client = client;
- dctx.PackageIdx = 0;
-
- // TODO: Enable this code for freeing up leaked handles
- #if 0
- for (;;)
- {
- void* ptr = NvRtFreeObjRef(&dctx,
- NvRtObjType_NvEc_NvEcHandle, NULL);
- if (!ptr) break;
- NVRT_LEAK("NvEc", "NvEcHandle", ptr);
- NvEcClose(ptr);
- }
- #endif
-
- NvRtUnregisterClient(s_RtHandle, client);
- }
- return 0;
-}
-
-long nvec_unlocked_ioctl(struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- NvError err;
- NvOsIoctlParams p;
- NvU32 size;
- NvU32 small_buf[8];
- void *ptr = 0;
- long e;
- NvBool bAlloc = NV_FALSE;
-
- switch( cmd ) {
- case NvECKernelIoctls_Generic:
- {
- NvDispatchCtx dctx;
-
- dctx.Rt = s_RtHandle;
- dctx.Client = (NvRtClientHandle)file->private_data;
- dctx.PackageIdx = 0;
-
- err = NvOsCopyIn(&p, (void *)arg, sizeof(p));
- if (err != NvSuccess) {
- printk("NvECKernelIoctls_Generic: copy in failed\n");
- goto fail;
- }
-
- size = p.InBufferSize + p.InOutBufferSize + p.OutBufferSize;
- if (size <= sizeof(small_buf)) {
- ptr = small_buf;
- } else {
- ptr = NvOsAlloc(size);
- if (!ptr) {
- printk("NvECKernelIoctls_Generic: alloc err\n");
- goto fail;
- }
-
- bAlloc = NV_TRUE;
- }
-
- err = NvOsCopyIn(ptr, p.pBuffer, p.InBufferSize +
- p.InOutBufferSize);
- if (err != NvSuccess) {
- printk("NvECKernelIoctls_Generic: copy in failure\n");
- goto fail;
- }
-
- err = NvECPackage_Dispatch(ptr,
- p.InBufferSize + p.InOutBufferSize,
- ((NvU8 *)ptr) + p.InBufferSize, p.InOutBufferSize +
- p.OutBufferSize, &dctx);
- if (err != NvSuccess) {
- printk("NvECKernelIoctls_Generic: dispatch failure\n");
- goto fail;
- }
-
- if (p.InOutBufferSize || p.OutBufferSize) {
- err = NvOsCopyOut(
- ((NvU8 *)((NvOsIoctlParams *)arg)->pBuffer) +
- p.InBufferSize,
- ((NvU8 *)ptr) + p.InBufferSize,
- p.InOutBufferSize + p.OutBufferSize);
- if (err != NvSuccess) {
- printk("NvECKernelIoctls_Generic: copyout err\n");
- goto fail;
- }
- }
-
- break;
- }
- default:
- printk("unknown ioctl code\n");
- goto fail;
- }
- e = 0;
- goto clean;
-
-fail:
- e = -EINVAL;
-
-clean:
- if (bAlloc)
- NvOsFree(ptr);
-
- return e;
-}
-
-#define DEVICE_NAME "nvec"
-
-static const struct file_operations nvec_fops =
-{
- .owner = THIS_MODULE,
- .open = nvec_open,
- .release = nvec_close,
- .unlocked_ioctl = nvec_unlocked_ioctl,
-};
-
-static struct miscdevice nvec_dev =
-{
- .name = DEVICE_NAME,
- .fops = &nvec_fops,
- .minor = MISC_DYNAMIC_MINOR,
-};
-
-static NvEcHandle s_NvEcHandle = NULL;
-
-static int __init nvec_probe(struct platform_device *pdev)
-{
- int e = 0;
- NvError status;
- NvU32 NumTypes = 1; // TODO: must have NvRtObjType_NvEc_Num instead;
-
- NV_ASSERT(s_RtHandle == NULL);
-
- if (NvRtCreate(1, &NumTypes, &s_RtHandle) != NvSuccess) {
- printk("nvec NvRtCreate returned error\n");
- return -ENOMEM;
- }
-
- status = NvEcOpen(&s_NvEcHandle, 0);
- if (status != NvError_Success) {
- printk("nvec NvEcOpen returned 0x%x\n", status);
- return -EINVAL;
- }
-
- e = misc_register(&nvec_dev);
- if (e < 0) {
- if (s_RtHandle) {
- NvRtDestroy(s_RtHandle);
- s_RtHandle = NULL;
- }
- printk("nvec failed to open\n");
- }
- return e;
-}
-
-static int nvec_remove(struct platform_device *pdev)
-{
- NvEcClose(s_NvEcHandle);
- misc_deregister( &nvec_dev );
- NvRtDestroy(s_RtHandle);
- s_RtHandle = NULL;
- return 0;
-}
-
-static int nvec_suspend(struct platform_device *pdev, pm_message_t state)
-{
- NvError e = NvEcPowerSuspend(NvEcPowerState_Suspend);
- if (e != NvSuccess)
- return -1;
-
- return 0;
-}
-
-static int nvec_resume(struct platform_device *pdev)
-{
- NvError e = NvEcPowerResume();
- if (e != NvSuccess)
- return -1;
-
- return 0;
-}
-
-static void nvec_shutdown(struct platform_device *pdev)
-{
- NvEcPowerSuspend(NvEcPowerState_PowerDown);
-}
-
-static struct platform_driver tegra_nvec_driver = {
- .probe = nvec_probe,
- .remove = nvec_remove,
- .suspend = nvec_suspend,
- .resume = nvec_resume,
- .shutdown = nvec_shutdown,
- .driver = {
- .name = "nvec",
- },
-};
-
-static int __devinit nvec_init( void )
-{
- return platform_driver_register(&tegra_nvec_driver);
-}
-
-static void __exit nvec_deinit( void )
-{
- return platform_driver_unregister(&tegra_nvec_driver);
-}
-
-module_init(nvec_init);
-module_exit(nvec_deinit);
+/*
+ * arch/arm/mach-tegra/nvec_user.c
+ *
+ * User-land access to NvEc embedded controller features
+ *
+ * Copyright (c) 2008-2009, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/platform_device.h>
+#include <linux/miscdevice.h>
+#include "linux/nvos_ioctl.h"
+#include "nvec.h"
+#include "linux/nvec_ioctls.h"
+#include "nvreftrack.h"
+#include "nvassert.h"
+#include "nvec_device.h"
+
+static NvRtHandle s_RtHandle = NULL;
+int device_count = 0;
+
+#define dev_to_nvec_driver(d) container_of(d, struct nvec_driver, driver)
+#define to_nvec_device(x) container_of((x), struct nvec_device, dev)
+
+NvError NvECPackage_Dispatch(void *InBuffer, NvU32 InSize, void *OutBuffer,
+ NvU32 OutSize, NvDispatchCtx* Ctx);
+
+static int nvec_open(struct inode *inode, struct file *file);
+static int nvec_close(struct inode *inode, struct file *file);
+static long nvec_unlocked_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg);
+
+int nvec_open(struct inode *inode, struct file *file)
+{
+ NvRtClientHandle Client;
+
+ if (NvRtRegisterClient(s_RtHandle, &Client) != NvSuccess)
+ return -ENOMEM;
+
+ file->private_data = (void*)Client;
+ return 0;
+}
+
+int nvec_close(struct inode *inode, struct file *file)
+{
+ NvRtClientHandle client = (NvRtClientHandle)file->private_data;
+
+ if (NvRtUnregisterClient(s_RtHandle, client)) {
+ NvDispatchCtx dctx;
+
+ dctx.Rt = s_RtHandle;
+ dctx.Client = client;
+ dctx.PackageIdx = 0;
+
+ // TODO: Enable this code for freeing up leaked handles
+ #if 0
+ for (;;)
+ {
+ void* ptr = NvRtFreeObjRef(&dctx,
+ NvRtObjType_NvEc_NvEcHandle, NULL);
+ if (!ptr) break;
+ NVRT_LEAK("NvEc", "NvEcHandle", ptr);
+ NvEcClose(ptr);
+ }
+ #endif
+
+ NvRtUnregisterClient(s_RtHandle, client);
+ }
+ return 0;
+}
+
+long nvec_unlocked_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ NvError err;
+ NvOsIoctlParams p;
+ NvU32 size;
+ NvU32 small_buf[8];
+ void *ptr = 0;
+ long e;
+ NvBool bAlloc = NV_FALSE;
+
+ switch( cmd ) {
+ case NvECKernelIoctls_Generic:
+ {
+ NvDispatchCtx dctx;
+
+ dctx.Rt = s_RtHandle;
+ dctx.Client = (NvRtClientHandle)file->private_data;
+ dctx.PackageIdx = 0;
+
+ err = NvOsCopyIn(&p, (void *)arg, sizeof(p));
+ if (err != NvSuccess) {
+ printk("NvECKernelIoctls_Generic: copy in failed\n");
+ goto fail;
+ }
+
+ size = p.InBufferSize + p.InOutBufferSize + p.OutBufferSize;
+ if (size <= sizeof(small_buf)) {
+ ptr = small_buf;
+ } else {
+ ptr = NvOsAlloc(size);
+ if (!ptr) {
+ printk("NvECKernelIoctls_Generic: alloc err\n");
+ goto fail;
+ }
+
+ bAlloc = NV_TRUE;
+ }
+
+ err = NvOsCopyIn(ptr, p.pBuffer, p.InBufferSize +
+ p.InOutBufferSize);
+ if (err != NvSuccess) {
+ printk("NvECKernelIoctls_Generic: copy in failure\n");
+ goto fail;
+ }
+
+ err = NvECPackage_Dispatch(ptr,
+ p.InBufferSize + p.InOutBufferSize,
+ ((NvU8 *)ptr) + p.InBufferSize, p.InOutBufferSize +
+ p.OutBufferSize, &dctx);
+ if (err != NvSuccess) {
+ printk("NvECKernelIoctls_Generic: dispatch failure\n");
+ goto fail;
+ }
+
+ if (p.InOutBufferSize || p.OutBufferSize) {
+ err = NvOsCopyOut(
+ ((NvU8 *)((NvOsIoctlParams *)arg)->pBuffer) +
+ p.InBufferSize,
+ ((NvU8 *)ptr) + p.InBufferSize,
+ p.InOutBufferSize + p.OutBufferSize);
+ if (err != NvSuccess) {
+ printk("NvECKernelIoctls_Generic: copyout err\n");
+ goto fail;
+ }
+ }
+
+ break;
+ }
+ default:
+ printk("unknown ioctl code\n");
+ goto fail;
+ }
+ e = 0;
+ goto clean;
+
+fail:
+ e = -EINVAL;
+
+clean:
+ if (bAlloc)
+ NvOsFree(ptr);
+
+ return e;
+}
+
+#define DEVICE_NAME "nvec"
+
+static const struct file_operations nvec_fops =
+{
+ .owner = THIS_MODULE,
+ .open = nvec_open,
+ .release = nvec_close,
+ .unlocked_ioctl = nvec_unlocked_ioctl,
+};
+
+static struct miscdevice nvec_dev =
+{
+ .name = DEVICE_NAME,
+ .fops = &nvec_fops,
+ .minor = MISC_DYNAMIC_MINOR,
+};
+
+static NvEcHandle s_NvEcHandle = NULL;
+
+static int nvec_bus_probe(struct device *_dev)
+{
+ struct nvec_driver *drv = dev_to_nvec_driver(_dev->driver);
+ struct nvec_device *dev = to_nvec_device(_dev);
+
+ return drv->probe(dev);
+}
+
+static int nvec_bus_remove(struct device *_dev)
+{
+ return 0;
+}
+
+int nvec_bus_match(struct device *_dev, struct device_driver *drv)
+{
+ struct nvec_device *dev = to_nvec_device(_dev);
+
+ return (strcmp(dev->name, drv->name) == 0);
+}
+
+static int nvec_bus_suspend(struct device *_dev, pm_message_t state)
+{
+ struct nvec_driver *drv = dev_to_nvec_driver(_dev->driver);
+ struct nvec_device *dev = to_nvec_device(_dev);
+ NvError e = NvError_Success;
+
+ device_count--;
+ drv->suspend(dev, state);
+
+ if (!device_count)
+ {
+ e = NvEcPowerSuspend(NvEcPowerState_Suspend);
+ if (e != NvSuccess) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int nvec_bus_resume(struct device *_dev)
+{
+ struct nvec_driver *drv = dev_to_nvec_driver(_dev->driver);
+ struct nvec_device *dev = to_nvec_device(_dev);
+
+ if (!device_count)
+ {
+ NvError e = NvEcPowerResume();
+ if (e != NvSuccess) {
+ return -1;
+ }
+ }
+
+ device_count++;
+ drv->resume(dev);
+ return 0;
+}
+
+static void nvec_bus_shutdown(struct device *pdev)
+{
+ NvEcPowerSuspend(NvEcPowerState_PowerDown);
+}
+
+static struct bus_type nvec_bus_type = {
+ .name = DEVICE_NAME,
+ .match = nvec_bus_match,
+ .probe = nvec_bus_probe,
+ .remove = nvec_bus_remove,
+ .suspend = nvec_bus_suspend,
+ .resume = nvec_bus_resume,
+ .shutdown = nvec_bus_shutdown,
+};
+
+static struct device nvec_bus_dev = {
+ .init_name = DEVICE_NAME
+};
+
+int nvec_register_driver(struct nvec_driver *drv)
+{
+ drv->driver.name = drv->name;
+ drv->driver.bus = &nvec_bus_type;
+ return driver_register(&drv->driver);
+}
+EXPORT_SYMBOL_GPL(nvec_register_driver);
+
+void nvec_unregister_driver(struct nvec_driver *drv)
+{
+ drv->driver.bus = &nvec_bus_type;
+ driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL_GPL(nvec_unregister_driver);
+
+int nvec_register_device(struct nvec_device *pdev)
+{
+ if (!pdev)
+ return -EINVAL;
+
+ if (!pdev->dev.parent)
+ pdev->dev.parent = &nvec_bus_dev;
+
+ pdev->dev.bus = &nvec_bus_type;
+
+ dev_set_name(&pdev->dev, pdev->name);
+
+ device_count++;
+ return device_register(&pdev->dev);
+}
+EXPORT_SYMBOL_GPL(nvec_register_device);
+
+void nvec_unregister_device(struct nvec_device *pdev)
+{
+ if (pdev) {
+ device_count--;
+ device_unregister(&pdev->dev);
+ }
+}
+EXPORT_SYMBOL_GPL(nvec_unregister_device);
+
+static int __init nvec_init(void)
+{
+ int err = 0;
+ NvError status = NvSuccess;
+ NvU32 NumTypes = 1; // TODO: must have NvRtObjType_NvEc_Num instead;
+
+ err = device_register(&nvec_bus_dev);
+ if (err)
+ return err;
+
+ err = bus_register(&nvec_bus_type);
+ if (err){
+ device_unregister(&nvec_bus_dev);
+ return err;
+ }
+
+
+ NV_ASSERT(s_RtHandle == NULL);
+
+ if (NvRtCreate(1, &NumTypes, &s_RtHandle) != NvSuccess) {
+ printk("nvec NvRtCreate returned error\n");
+ bus_unregister(&nvec_bus_type);
+ device_unregister(&nvec_bus_dev);
+ return -ENOMEM;
+ }
+
+ status = NvEcOpen(&s_NvEcHandle, 0);
+ if (status != NvError_Success) {
+ printk("nvec NvEcOpen returned 0x%x\n", status);
+ NvRtDestroy(s_RtHandle);
+ s_RtHandle = NULL;
+ bus_unregister(&nvec_bus_type);
+ device_unregister(&nvec_bus_dev);
+ return -EINVAL;
+ }
+
+ err = misc_register(&nvec_dev);
+ if (err < 0) {
+ if (s_RtHandle) {
+ NvEcClose(s_NvEcHandle);
+ s_NvEcHandle = NULL;
+ NvRtDestroy(s_RtHandle);
+ s_RtHandle = NULL;
+ bus_unregister(&nvec_bus_type);
+ device_unregister(&nvec_bus_dev);
+ }
+ printk("nvec failed to open\n");
+ }
+
+ return err;
+}
+
+static void __exit nvec_exit(void)
+{
+ NvEcClose(s_NvEcHandle);
+ s_NvEcHandle = NULL;
+ misc_deregister( &nvec_dev );
+ NvRtDestroy(s_RtHandle);
+ s_RtHandle = NULL;
+
+ bus_unregister(&nvec_bus_type);
+ device_unregister(&nvec_bus_dev);
+}
+
+module_init(nvec_init);
+module_exit(nvec_exit);
+
+MODULE_LICENSE("GPL"); \ No newline at end of file
diff --git a/drivers/input/keyboard/tegra-nvec.c b/drivers/input/keyboard/tegra-nvec.c
index 266a3a29cacf..5f0cdbb6793f 100644
--- a/drivers/input/keyboard/tegra-nvec.c
+++ b/drivers/input/keyboard/tegra-nvec.c
@@ -23,7 +23,7 @@
#include <linux/module.h>
#include <linux/input.h>
-#include <linux/platform_device.h>
+#include <linux/device.h>
#include <linux/kthread.h>
#include <linux/tegra_devices.h>
#include <linux/freezer.h>
@@ -32,6 +32,7 @@
#include "nvec.h"
#include "nvodm_services.h"
#include "nvodm_keyboard.h"
+#include "nvec_device.h"
#define DRIVER_DESC "NvEc keyboard driver"
#define DRIVER_LICENSE "GPL"
@@ -262,8 +263,6 @@ struct nvec_keyboard
NvEcEventRegistrationHandle hEvent;
};
-static struct platform_device *nvec_keyboard_device;
-
static int nvec_keyboard_recv(void *arg)
{
struct input_dev *input_dev = (struct input_dev *)arg;
@@ -317,7 +316,7 @@ static void nvec_keyboard_close(struct input_dev *dev)
return;
}
-static int __devinit nvec_keyboard_probe(struct platform_device *pdev)
+static int __devinit nvec_keyboard_probe(struct nvec_device *pdev)
{
int error;
NvError nverr;
@@ -334,7 +333,7 @@ static int __devinit nvec_keyboard_probe(struct platform_device *pdev)
keyboard->input_dev = input_dev;
input_set_drvdata(input_dev, keyboard);
- platform_set_drvdata(pdev, input_dev);
+ nvec_set_drvdata(pdev, input_dev);
if (!NvOdmKeyboardInit()) {
error = -ENODEV;
@@ -393,9 +392,9 @@ fail:
return error;
}
-static int __devexit nvec_keyboard_remove(struct platform_device *dev)
+static int nvec_keyboard_remove(struct nvec_device *dev)
{
- struct input_dev *input_dev = platform_get_drvdata(dev);
+ struct input_dev *input_dev = nvec_get_drvdata(dev);
struct nvec_keyboard *keyboard = input_get_drvdata(input_dev);
(void)kthread_stop(keyboard->task);
@@ -409,12 +408,11 @@ static int __devexit nvec_keyboard_remove(struct platform_device *dev)
return 0;
}
-#ifdef ENABLE_NVEC_KBD_SUSPEND
-static int nvec_keyboard_suspend(struct platform_device *pdev, pm_message_t state)
+static int nvec_keyboard_suspend(struct nvec_device *pdev, pm_message_t state)
{
NvEcRequest Request = {0};
NvEcResponse Response = {0};
- struct input_dev *input_dev = platform_get_drvdata(pdev);
+ struct input_dev *input_dev = nvec_get_drvdata(pdev);
struct nvec_keyboard *keyboard = input_get_drvdata(input_dev);
NvError err = NvError_Success;
@@ -455,11 +453,11 @@ static int nvec_keyboard_suspend(struct platform_device *pdev, pm_message_t stat
return 0;
}
-static int nvec_keyboard_resume(struct platform_device *pdev)
+static int nvec_keyboard_resume(struct nvec_device *pdev)
{
NvEcRequest Request = {0};
NvEcResponse Response = {0};
- struct input_dev *input_dev = platform_get_drvdata(pdev);
+ struct input_dev *input_dev = nvec_get_drvdata(pdev);
struct nvec_keyboard *keyboard = input_get_drvdata(input_dev);
NvError err = NvError_Success;
@@ -499,54 +497,46 @@ static int nvec_keyboard_resume(struct platform_device *pdev)
return 0;
}
-#endif /* ENABLE_NVEC_KBD_SUSPEND */
-
-static struct platform_driver nvec_keyboard_driver = {
- .driver = {
- .name = "nvec_keyboard",
- .owner = THIS_MODULE,
- },
- .probe = nvec_keyboard_probe,
- .remove = __devexit_p(nvec_keyboard_remove),
-#ifdef ENABLE_NVEC_KBD_SUSPEND
+
+static struct nvec_driver nvec_keyboard_driver = {
+ .name = "nvec_keyboard",
+ .probe = nvec_keyboard_probe,
+ .remove = nvec_keyboard_remove,
.suspend = nvec_keyboard_suspend,
.resume = nvec_keyboard_resume,
-#endif
+};
+
+static struct nvec_device nvec_keyboard_device = {
+ .name = "nvec_keyboard",
+ .driver = &nvec_keyboard_driver,
};
static int __init nvec_keyboard_init(void)
{
int err;
- err = platform_driver_register(&nvec_keyboard_driver);
- if (err) {
- goto error;
- }
-
- nvec_keyboard_device = platform_device_alloc("nvec_keyboard", -1);
- if (!nvec_keyboard_device) {
- err = -ENOMEM;
- goto error_unregister_driver;
+ err = nvec_register_driver(&nvec_keyboard_driver);
+ if (err)
+ {
+ pr_err("**nvec_keyboard_init: nvec_register_driver: fail\n");
+ return err;
}
- err = platform_device_add(nvec_keyboard_device);
+ err = nvec_register_device(&nvec_keyboard_device);
if (err)
- goto error_free_device;
+ {
+ pr_err("**nvec_keyboard_init: nvec_device_add: fail\n");
+ nvec_unregister_driver(&nvec_keyboard_driver);
+ return err;
+ }
return 0;
-
-error_free_device:
- platform_device_put(nvec_keyboard_device);
-error_unregister_driver:
- platform_driver_unregister(&nvec_keyboard_driver);
-error:
- return err;
}
static void __exit nvec_keyboard_exit(void)
{
- platform_device_unregister(nvec_keyboard_device);
- platform_driver_unregister(&nvec_keyboard_driver);
+ nvec_unregister_device(&nvec_keyboard_device);
+ nvec_unregister_driver(&nvec_keyboard_driver);
}
module_init(nvec_keyboard_init);
diff --git a/drivers/input/mouse/nvec_mouse.c b/drivers/input/mouse/nvec_mouse.c
index daebda669d9c..06014b92dd17 100644
--- a/drivers/input/mouse/nvec_mouse.c
+++ b/drivers/input/mouse/nvec_mouse.c
@@ -1,514 +1,472 @@
-/*
- * drivers/input/mouse/nvec_mouse.c
- *
- * Mouse class input driver for mice and touchpads connected to an NvEc
- * compliant embedded controller
- *
- * Copyright (c) 2009, NVIDIA Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <linux/module.h>
-#include <linux/input.h>
-#include <linux/platform_device.h>
-#include <linux/kthread.h>
-#include <linux/tegra_devices.h>
-#include <linux/earlysuspend.h>
-#include <linux/freezer.h>
-
-#include "nvos.h"
-#include "nvec.h"
-#include "nvodm_services.h"
-#include "nvodm_mouse.h"
-
-#define DRIVER_DESC "NvEc mouse driver"
-#define DRIVER_LICENSE "GPL"
-
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE(DRIVER_LICENSE);
-
-enum nvec_mouse_type {
- nvec_mouse_type_none,
- nvec_mouse_type_standard,
- nvec_mouse_type_intellimouse,
- nvec_mouse_type_intelli5buttonmouse,
-};
-
-#define NVEC_PAYLOAD 32
-
-struct nvec_mouse
-{
- struct input_dev *input_dev;
- struct task_struct *task;
- NvOdmOsSemaphoreHandle semaphore;
- char name[128];
- NvOdmMouseDeviceHandle hDevice;
- enum nvec_mouse_type type;
- unsigned char data[NVEC_PAYLOAD];
- int valid_data_size;
- int enableWake;
- int packetSize;
- unsigned char previousState;
- int shutdown;
- struct early_suspend early_suspend;
-};
-
-static struct platform_device *nvec_mouse_device;
-
-// Commands sent to the mouse.
-//
-static const NvU8 cmdReadId = 0xF2;
-static const NvU8 cmdSetSampleRate = 0xF3;
-static const NvU8 cmdEnable = 0xF4;
-static const NvU8 cmdReset = 0xFF;
-static const NvU8 cmdSetResolution = 0xE8;
-static const NvU8 cmdSetScaling1_1 = 0xE6;
-static const NvU8 cmdSetResolution2_1 = 0xE7;
-static const NvU8 cmdSetStreamMode = 0xEA;
-
-//
-// Mouse Responses
-//
-static const NvU8 responseAck = 0xFA;
-static const NvU8 responseResend = 0xFE;
-static const NvU8 responseStandardMouseId = 0x00;
-static const NvU8 responseIntelliMouseId = 0x03;
-static const NvU8 responseIntelli5buttonMouseId = 0x04;
-static const NvU8 responseBatSuccess = 0xAA;
-static const NvU8 responseBatError = 0xFC;
-
-
-int nvec_mouse_cmd(struct nvec_mouse *mouse, unsigned int cmd,
- int resp_size)
-{
- volatile int cnt = 3;
-
- while (cnt--) {
- if (!NvOdmMouseSendRequest(mouse->hDevice, cmd, resp_size,
- &mouse->valid_data_size, mouse->data)) {
- pr_err("**nvec_mouse_cmd: SendRequest: fail\n");
- return -1;
- } if (mouse->valid_data_size != resp_size) {
- pr_err("**nvec_mouse_cmd: not valid data size\n");
- continue;
- }
- if (mouse->valid_data_size == 0 ||
- mouse->data[0] == responseAck) {
- return 0;
- }
- }
- pr_err("**nvec_mouse_cmd error\n");
-
- return -1;
-}
-
-int nvec_IsStandardMouse(struct nvec_mouse *mouse)
-{
- if (!nvec_mouse_cmd(mouse, cmdReset, 3) &&
- (mouse->data[1] == responseBatSuccess) &&
- (mouse->data[2] == responseStandardMouseId)) {
- return 0;
- }
- return -ENODEV;
-}
-
-static int nvec_setSampleRate(struct nvec_mouse *mouse,
- unsigned int SamplesPerSecond)
-{
- if (!nvec_mouse_cmd(mouse, cmdSetSampleRate, 1) &&
- !nvec_mouse_cmd(mouse, SamplesPerSecond, 1)) {
- return 0;
- }
- return -EINVAL;
-}
-
-int nvec_IsIntellimouse(struct nvec_mouse *mouse)
-{
- if (((!nvec_setSampleRate(mouse, 0xC8)) &&
- (!nvec_setSampleRate(mouse, 0x64)) &&
- (!nvec_setSampleRate(mouse, 0x50)))
- && ((!nvec_mouse_cmd(mouse, cmdReadId, 1)) &&
- (mouse->data[1] == responseIntelliMouseId))) {
-
- printk("mouse->data[1]=0x%x\n", mouse->data[1]);
- return 0;
- }
- return -ENODEV;
-}
-
-int nvec_IsIntelli5buttonmouse(struct nvec_mouse *mouse)
-{
- if (((!nvec_setSampleRate(mouse, 0xC8)) &&
- (!nvec_setSampleRate(mouse, 0xC8)) &&
- (!nvec_setSampleRate(mouse, 0x50)))
- && ((!nvec_mouse_cmd(mouse, cmdReadId, 1)) &&
- mouse->data[1] == responseIntelli5buttonMouseId)) {
- printk("mouse->data[1]=0x%x\n", mouse->data[1]);
- return 0;
- }
- return -ENODEV;
-}
-
-static int nvec_mouse_receive_thread(void *arg)
-{
- struct input_dev *input_dev = (struct input_dev *)arg;
- struct nvec_mouse *mouse = input_get_drvdata(input_dev);
- NvU8 buttonState;
- NvU8 updatedState;
- NvS8 dataBuffer[4] = {0};
- NvU32 x,y;
-
- /* mouse event thread should be frozen before suspending the
- * mouse and NVEC drivers */
- set_freezable_with_signal();
-
- if (!NvOdmMouseEnableInterrupt(mouse->hDevice, mouse->semaphore)) {
- pr_err("**nvec_mouse_receive_thread: EnableInterrupt: fail\n");
- return -1;
- }
-
- while (!mouse->shutdown) {
- unsigned char data[4];
- int size;
-
- NvOdmOsSemaphoreWait(mouse->semaphore);
- if (mouse->shutdown)
- break;
-
- if (!NvOdmMouseGetEventInfo(mouse->hDevice, &size, data))
- continue;
-
- /* Short packets are not valid? */
- if (size < 3) continue;
-
- NvOsMemcpy(&dataBuffer, data, 4);
-
- updatedState = dataBuffer[0] ^ mouse->previousState;
- if (updatedState) {
- buttonState = dataBuffer[0];
-
- if (updatedState & 0x01)
- input_report_key(input_dev, BTN_LEFT,
- buttonState & 0x01);
- if (updatedState & 0x02)
- input_report_key(input_dev, BTN_RIGHT,
- (buttonState>>1) & 0x01);
- if (updatedState & 0x04)
- input_report_key(input_dev, BTN_MIDDLE,
- (buttonState>>2) & 0x01);
-
- mouse->previousState = dataBuffer[0];
- } else {
- x = dataBuffer[1];
- y = -dataBuffer[2];
-
- input_report_rel(input_dev, REL_X, x);
- input_report_rel(input_dev, REL_Y, y);
-
- input_sync(input_dev);
- }
-
- if (mouse->packetSize == 4 && dataBuffer[3])
- input_report_rel(input_dev, REL_WHEEL, dataBuffer[3]);
-
- input_sync(input_dev);
- }
- return 0;
-}
-
-static int nvec_mouse_open(struct input_dev *dev)
-{
- struct nvec_mouse *mouse = input_get_drvdata(dev);
-
- /* Set the resolution */
- /*
- * Factor Resolution
- * ------ ----------
- * 0x00 1 count/mm
- * 0x01 2 count/mm
- * 0x02 4 count/mm
- * 0x03 8 count/mm
- */
- if (nvec_mouse_cmd(mouse, cmdSetResolution, 1) ||
- nvec_mouse_cmd(mouse, 2, 1)) {
- pr_err("**nvec_mouse_open: cmd fail\n");
- return -EINVAL;
- }
-
- /* Set scaling */
- if (nvec_mouse_cmd(mouse, cmdSetScaling1_1, 1)) {
- pr_err("**nvec_mouse_open: cmdsetscaling fail\n");
- return -EINVAL;
- }
-
- if (nvec_setSampleRate(mouse, 0x64)) {
- pr_err("**nvec_mouse_open: setsamplerate fail\n");
- return -EINVAL;
- }
-
- if (nvec_mouse_cmd(mouse, cmdEnable, 1)) {
- pr_err("**nvec_mouse_open: mouse cmd fail\n");
- return -EINVAL;
- }
-
- if (!NvOdmMouseStartStreaming(mouse->hDevice, mouse->packetSize)) {
- pr_err("**nvec_mouse_open: streaming fail\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void nvec_mouse_close(struct input_dev *dev)
-{
- return;
-}
-
-static int mouse_resume(struct nvec_mouse *m)
-{
- if (!m || !m->hDevice || !NvOdmMousePowerResume(m->hDevice))
- return -1;
-
- return 0;
-}
-
-static int mouse_suspend(struct nvec_mouse *m)
-{
- if (!m || !m->hDevice || !NvOdmMousePowerSuspend(m->hDevice))
- return -1;
-
- return 0;
-}
-
-#ifndef CONFIG_HAS_EARLYSUSPEND
-
-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);
-
- return mouse_suspend(mouse);
-}
-
-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);
-
- return mouse_resume(mouse);
-}
-
-#else
-
-static void nvec_mouse_early_suspend(struct early_suspend *es)
-{
- struct nvec_mouse *mouse;
- mouse = container_of(es, struct nvec_mouse, early_suspend);
-
- mouse_suspend(mouse);
-}
-
-static void nvec_mouse_late_resume(struct early_suspend *es)
-{
- struct nvec_mouse *mouse;
- mouse = container_of(es, struct nvec_mouse, early_suspend);
-
- mouse_resume(mouse);
-}
-#endif
-
-static int __devinit nvec_mouse_probe(struct platform_device *pdev)
-{
- int error;
- struct nvec_mouse *mouse;
- struct input_dev *input_dev;
-
- mouse = kzalloc(sizeof(struct nvec_mouse), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!mouse || !input_dev) {
- pr_err("**nvec_mouse_probe: input_allocate_device: fail\n");
- error = -ENOMEM;
- goto fail;
- }
-
- if (!NvOdmMouseDeviceOpen(&mouse->hDevice)) {
- pr_err("NvOdmMouseDeviceOpen failed\n");
- error = -ENODEV;
- goto fail;
- }
-
- mouse->input_dev = input_dev;
- input_set_drvdata(input_dev, mouse);
-
- mouse->type = nvec_mouse_type_none;
- mouse->enableWake = 0;
-
- /* Probe for the type of the mouse */
- if (!nvec_IsStandardMouse(mouse)) {
- if (!nvec_IsIntellimouse(mouse)) {
- mouse->packetSize = 4;
- if (!nvec_IsIntelli5buttonmouse(mouse))
- mouse->type = nvec_mouse_type_intelli5buttonmouse;
- else
- mouse->type = nvec_mouse_type_intellimouse;
- } else {
- mouse->packetSize = 3;
- mouse->type = nvec_mouse_type_standard;
- }
- } else {
- error = -ENODEV;
- goto fail_no_mouse_found;
- }
-
- platform_set_drvdata(pdev, input_dev);
-
- mouse->semaphore = NvOdmOsSemaphoreCreate(0);
- if (mouse->semaphore == NULL) {
- error = -1;
- pr_err("nvec_mouse: Semaphore creation failed\n");
- goto fail_semaphore_create;
- }
-
- mouse->task = kthread_create(nvec_mouse_receive_thread,
- input_dev, "nvec_mouse");
-
- if (!mouse->task) {
- pr_err("**nvec_mouse_probe: kthread_create: fail\n");
- error = -ENOMEM;
- goto fail_thread_create;
- }
- wake_up_process(mouse->task);
-
- if (!strlen(mouse->name))
- snprintf(mouse->name, sizeof(mouse->name), "nvec mouse");
-
- input_dev->name = mouse->name;
- input_dev->open = nvec_mouse_open;
- input_dev->close = nvec_mouse_close;
-
- input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
-
- input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
- BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
- input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
- input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);
-
- error = input_register_device(mouse->input_dev);
- if (error) {
- pr_err("**nvec_mouse_probe: input_register_device: fail\n");
- goto fail_input_register;
- }
-
- mouse->previousState = 0;
-#ifdef CONFIG_HAS_EARLYSUSPEND
- mouse->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
- mouse->early_suspend.suspend = nvec_mouse_early_suspend;
- mouse->early_suspend.resume = nvec_mouse_late_resume;
- register_early_suspend(&mouse->early_suspend);
-#endif
-
- printk(KERN_INFO DRIVER_DESC ": registered NVEC mouse driver\n");
- return 0;
-
-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;
-}
-
-static int __devexit nvec_mouse_remove(struct platform_device *dev)
-{
- struct input_dev *input_dev = platform_get_drvdata(dev);
- struct nvec_mouse *mouse = platform_get_drvdata(dev);
-
- unregister_early_suspend(&mouse->early_suspend);
- mouse->shutdown = 1;
- NvOdmOsSemaphoreSignal(mouse->semaphore);
- (void)kthread_stop(mouse->task);
- NvOdmOsSemaphoreDestroy(mouse->semaphore);
- NvOdmMouseDeviceClose(mouse->hDevice);
- input_free_device(input_dev);
- kfree(mouse);
- mouse = NULL;
- return 0;
-}
-
-static struct platform_driver nvec_mouse_driver = {
- .driver = {
- .name = "nvec_mouse",
- .owner = THIS_MODULE,
- },
- .probe = nvec_mouse_probe,
- .remove = __devexit_p(nvec_mouse_remove),
-#ifndef CONFIG_HAS_EARLYSUSPEND
- .suspend = nvec_mouse_suspend,
- .resume = nvec_mouse_resume,
-#endif
-};
-
-static int __init nvec_mouse_init(void)
-{
- int err;
-
- err = platform_driver_register(&nvec_mouse_driver);
- if (err) {
- pr_err("**nvec_mouse_init: platform_driver_register: fail\n");
- goto error;
- }
-
- nvec_mouse_device = platform_device_alloc("nvec_mouse", -1);
- if (!nvec_mouse_device) {
- pr_err("**nvec_mouse_init: platform_device_alloc: fail\n");
- err = -ENOMEM;
- goto error_unregister_driver;
- }
-
- err = platform_device_add(nvec_mouse_device);
- if (err)
- {
- pr_err("**nvec_mouse_init: platform_device_add: fail\n");
- goto error_free_device;
- }
- return 0;
-
-error_free_device:
- platform_device_put(nvec_mouse_device);
-error_unregister_driver:
- platform_driver_unregister(&nvec_mouse_driver);
-error:
- return err;
-}
-
-static void __exit nvec_mouse_exit(void)
-{
- platform_device_unregister(nvec_mouse_device);
- platform_driver_unregister(&nvec_mouse_driver);
-}
-
-module_init(nvec_mouse_init);
-module_exit(nvec_mouse_exit);
-
+/*
+ * drivers/input/mouse/nvec_mouse.c
+ *
+ * Mouse class input driver for mice and touchpads connected to an NvEc
+ * compliant embedded controller
+ *
+ * Copyright (c) 2009, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/device.h>
+#include <linux/kthread.h>
+#include <linux/tegra_devices.h>
+#include <linux/earlysuspend.h>
+#include <linux/freezer.h>
+
+#include "nvos.h"
+#include "nvec.h"
+#include "nvodm_services.h"
+#include "nvodm_mouse.h"
+#include "nvec_device.h"
+
+#define DRIVER_DESC "NvEc mouse driver"
+#define DRIVER_LICENSE "GPL"
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE(DRIVER_LICENSE);
+
+enum nvec_mouse_type {
+ nvec_mouse_type_none,
+ nvec_mouse_type_standard,
+ nvec_mouse_type_intellimouse,
+ nvec_mouse_type_intelli5buttonmouse,
+};
+
+#define NVEC_PAYLOAD 32
+
+struct nvec_mouse
+{
+ struct input_dev *input_dev;
+ struct task_struct *task;
+ NvOdmOsSemaphoreHandle semaphore;
+ char name[128];
+ NvOdmMouseDeviceHandle hDevice;
+ enum nvec_mouse_type type;
+ unsigned char data[NVEC_PAYLOAD];
+ int valid_data_size;
+ int enableWake;
+ int packetSize;
+ unsigned char previousState;
+ int shutdown;
+};
+
+// Commands sent to the mouse.
+//
+static const NvU8 cmdReadId = 0xF2;
+static const NvU8 cmdSetSampleRate = 0xF3;
+static const NvU8 cmdEnable = 0xF4;
+static const NvU8 cmdReset = 0xFF;
+static const NvU8 cmdSetResolution = 0xE8;
+static const NvU8 cmdSetScaling1_1 = 0xE6;
+static const NvU8 cmdSetResolution2_1 = 0xE7;
+static const NvU8 cmdSetStreamMode = 0xEA;
+
+//
+// Mouse Responses
+//
+static const NvU8 responseAck = 0xFA;
+static const NvU8 responseResend = 0xFE;
+static const NvU8 responseStandardMouseId = 0x00;
+static const NvU8 responseIntelliMouseId = 0x03;
+static const NvU8 responseIntelli5buttonMouseId = 0x04;
+static const NvU8 responseBatSuccess = 0xAA;
+static const NvU8 responseBatError = 0xFC;
+
+
+int nvec_mouse_cmd(struct nvec_mouse *mouse, unsigned int cmd,
+ int resp_size)
+{
+ volatile int cnt = 3;
+
+ while (cnt--) {
+ if (!NvOdmMouseSendRequest(mouse->hDevice, cmd, resp_size,
+ &mouse->valid_data_size, mouse->data)) {
+ pr_err("**nvec_mouse_cmd: SendRequest: fail\n");
+ return -1;
+ } if (mouse->valid_data_size != resp_size) {
+ pr_err("**nvec_mouse_cmd: not valid data size\n");
+ continue;
+ }
+ if (mouse->valid_data_size == 0 ||
+ mouse->data[0] == responseAck) {
+ return 0;
+ }
+ }
+ pr_err("**nvec_mouse_cmd error\n");
+
+ return -1;
+}
+
+int nvec_IsStandardMouse(struct nvec_mouse *mouse)
+{
+ if (!nvec_mouse_cmd(mouse, cmdReset, 3) &&
+ (mouse->data[1] == responseBatSuccess) &&
+ (mouse->data[2] == responseStandardMouseId)) {
+ return 0;
+ }
+ return -ENODEV;
+}
+
+static int nvec_setSampleRate(struct nvec_mouse *mouse,
+ unsigned int SamplesPerSecond)
+{
+ if (!nvec_mouse_cmd(mouse, cmdSetSampleRate, 1) &&
+ !nvec_mouse_cmd(mouse, SamplesPerSecond, 1)) {
+ return 0;
+ }
+ return -EINVAL;
+}
+
+int nvec_IsIntellimouse(struct nvec_mouse *mouse)
+{
+ if (((!nvec_setSampleRate(mouse, 0xC8)) &&
+ (!nvec_setSampleRate(mouse, 0x64)) &&
+ (!nvec_setSampleRate(mouse, 0x50)))
+ && ((!nvec_mouse_cmd(mouse, cmdReadId, 1)) &&
+ (mouse->data[1] == responseIntelliMouseId))) {
+
+ printk("mouse->data[1]=0x%x\n", mouse->data[1]);
+ return 0;
+ }
+ return -ENODEV;
+}
+
+int nvec_IsIntelli5buttonmouse(struct nvec_mouse *mouse)
+{
+ if (((!nvec_setSampleRate(mouse, 0xC8)) &&
+ (!nvec_setSampleRate(mouse, 0xC8)) &&
+ (!nvec_setSampleRate(mouse, 0x50)))
+ && ((!nvec_mouse_cmd(mouse, cmdReadId, 1)) &&
+ mouse->data[1] == responseIntelli5buttonMouseId)) {
+ printk("mouse->data[1]=0x%x\n", mouse->data[1]);
+ return 0;
+ }
+ return -ENODEV;
+}
+
+static int nvec_mouse_receive_thread(void *arg)
+{
+ struct input_dev *input_dev = (struct input_dev *)arg;
+ struct nvec_mouse *mouse = input_get_drvdata(input_dev);
+ NvU8 buttonState;
+ NvU8 updatedState;
+ NvS8 dataBuffer[4] = {0};
+ NvU32 x,y;
+
+ /* mouse event thread should be frozen before suspending the
+ * mouse and NVEC drivers */
+ set_freezable_with_signal();
+
+ if (!NvOdmMouseEnableInterrupt(mouse->hDevice, mouse->semaphore)) {
+ pr_err("**nvec_mouse_receive_thread: EnableInterrupt: fail\n");
+ return -1;
+ }
+
+ while (!mouse->shutdown) {
+ unsigned char data[4];
+ int size;
+
+ NvOdmOsSemaphoreWait(mouse->semaphore);
+ if (mouse->shutdown)
+ break;
+
+ if (!NvOdmMouseGetEventInfo(mouse->hDevice, &size, data))
+ continue;
+
+ /* Short packets are not valid? */
+ if (size < 3) continue;
+
+ NvOsMemcpy(&dataBuffer, data, 4);
+
+ updatedState = dataBuffer[0] ^ mouse->previousState;
+ if (updatedState) {
+ buttonState = dataBuffer[0];
+
+ if (updatedState & 0x01)
+ input_report_key(input_dev, BTN_LEFT,
+ buttonState & 0x01);
+ if (updatedState & 0x02)
+ input_report_key(input_dev, BTN_RIGHT,
+ (buttonState>>1) & 0x01);
+ if (updatedState & 0x04)
+ input_report_key(input_dev, BTN_MIDDLE,
+ (buttonState>>2) & 0x01);
+
+ mouse->previousState = dataBuffer[0];
+ } else {
+ x = dataBuffer[1];
+ y = -dataBuffer[2];
+
+ input_report_rel(input_dev, REL_X, x);
+ input_report_rel(input_dev, REL_Y, y);
+
+ input_sync(input_dev);
+ }
+
+ if (mouse->packetSize == 4 && dataBuffer[3])
+ input_report_rel(input_dev, REL_WHEEL, dataBuffer[3]);
+
+ input_sync(input_dev);
+ }
+ return 0;
+}
+
+static int nvec_mouse_open(struct input_dev *dev)
+{
+ struct nvec_mouse *mouse = input_get_drvdata(dev);
+
+ /* Set the resolution */
+ /*
+ * Factor Resolution
+ * ------ ----------
+ * 0x00 1 count/mm
+ * 0x01 2 count/mm
+ * 0x02 4 count/mm
+ * 0x03 8 count/mm
+ */
+ if (nvec_mouse_cmd(mouse, cmdSetResolution, 1) ||
+ nvec_mouse_cmd(mouse, 2, 1)) {
+ pr_err("**nvec_mouse_open: cmd fail\n");
+ return -EINVAL;
+ }
+
+ /* Set scaling */
+ if (nvec_mouse_cmd(mouse, cmdSetScaling1_1, 1)) {
+ pr_err("**nvec_mouse_open: cmdsetscaling fail\n");
+ return -EINVAL;
+ }
+
+ if (nvec_setSampleRate(mouse, 0x64)) {
+ pr_err("**nvec_mouse_open: setsamplerate fail\n");
+ return -EINVAL;
+ }
+
+ if (nvec_mouse_cmd(mouse, cmdEnable, 1)) {
+ pr_err("**nvec_mouse_open: mouse cmd fail\n");
+ return -EINVAL;
+ }
+
+ if (!NvOdmMouseStartStreaming(mouse->hDevice, mouse->packetSize)) {
+ pr_err("**nvec_mouse_open: streaming fail\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void nvec_mouse_close(struct input_dev *dev)
+{
+ return;
+}
+
+static int mouse_resume(struct nvec_mouse *m)
+{
+ if (!m || !m->hDevice || !NvOdmMousePowerResume(m->hDevice))
+ return -1;
+
+ return 0;
+}
+
+static int mouse_suspend(struct nvec_mouse *m)
+{
+ if (!m || !m->hDevice || !NvOdmMousePowerSuspend(m->hDevice))
+ return -1;
+
+ return 0;
+}
+
+static int nvec_mouse_suspend(struct nvec_device *pdev, pm_message_t state)
+{
+ struct input_dev *input_dev = nvec_get_drvdata(pdev);
+ struct nvec_mouse *mouse = input_get_drvdata(input_dev);
+
+ return mouse_suspend(mouse);
+}
+
+static int nvec_mouse_resume(struct nvec_device *pdev)
+{
+ struct input_dev *input_dev = nvec_get_drvdata(pdev);
+ struct nvec_mouse *mouse = input_get_drvdata(input_dev);
+
+ return mouse_resume(mouse);
+}
+
+static int __devinit nvec_mouse_probe(struct nvec_device *pdev)
+{
+ int error;
+ struct nvec_mouse *mouse;
+ struct input_dev *input_dev;
+
+ mouse = kzalloc(sizeof(struct nvec_mouse), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!mouse || !input_dev) {
+ pr_err("**nvec_mouse_probe: input_allocate_device: fail\n");
+ error = -ENOMEM;
+ goto fail;
+ }
+
+ if (!NvOdmMouseDeviceOpen(&mouse->hDevice)) {
+ pr_err("NvOdmMouseDeviceOpen failed\n");
+ error = -ENODEV;
+ goto fail;
+ }
+
+ mouse->input_dev = input_dev;
+ input_set_drvdata(input_dev, mouse);
+
+ mouse->type = nvec_mouse_type_none;
+ mouse->enableWake = 0;
+
+ /* Probe for the type of the mouse */
+ if (!nvec_IsStandardMouse(mouse)) {
+ if (!nvec_IsIntellimouse(mouse)) {
+ mouse->packetSize = 4;
+ if (!nvec_IsIntelli5buttonmouse(mouse))
+ mouse->type = nvec_mouse_type_intelli5buttonmouse;
+ else
+ mouse->type = nvec_mouse_type_intellimouse;
+ } else {
+ mouse->packetSize = 3;
+ mouse->type = nvec_mouse_type_standard;
+ }
+ } else {
+ error = -ENODEV;
+ goto fail_no_mouse_found;
+ }
+
+ nvec_set_drvdata(pdev, input_dev);
+
+ mouse->semaphore = NvOdmOsSemaphoreCreate(0);
+ if (mouse->semaphore == NULL) {
+ error = -1;
+ pr_err("nvec_mouse: Semaphore creation failed\n");
+ goto fail_semaphore_create;
+ }
+
+ mouse->task = kthread_create(nvec_mouse_receive_thread,
+ input_dev, "nvec_mouse");
+
+ if (!mouse->task) {
+ pr_err("**nvec_mouse_probe: kthread_create: fail\n");
+ error = -ENOMEM;
+ goto fail_thread_create;
+ }
+ wake_up_process(mouse->task);
+
+ if (!strlen(mouse->name))
+ snprintf(mouse->name, sizeof(mouse->name), "nvec mouse");
+
+ input_dev->name = mouse->name;
+ input_dev->open = nvec_mouse_open;
+ input_dev->close = nvec_mouse_close;
+
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+
+ input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+ BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
+ input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+ input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);
+
+ error = input_register_device(mouse->input_dev);
+ if (error) {
+ pr_err("**nvec_mouse_probe: input_register_device: fail\n");
+ goto fail_input_register;
+ }
+
+ mouse->previousState = 0;
+
+ printk(KERN_INFO DRIVER_DESC ": registered NVEC mouse driver\n");
+ return 0;
+
+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;
+}
+
+static void nvec_mouse_remove(struct nvec_device *dev)
+{
+ struct input_dev *input_dev = nvec_get_drvdata(dev);
+ struct nvec_mouse *mouse = input_get_drvdata(input_dev);
+
+ mouse->shutdown = 1;
+ NvOdmOsSemaphoreSignal(mouse->semaphore);
+ (void)kthread_stop(mouse->task);
+ NvOdmOsSemaphoreDestroy(mouse->semaphore);
+ NvOdmMouseDeviceClose(mouse->hDevice);
+ input_free_device(input_dev);
+ kfree(mouse);
+ mouse = NULL;
+}
+
+static struct nvec_driver nvec_mouse = {
+ .name = "nvec_mouse",
+ .probe = nvec_mouse_probe,
+ .remove = nvec_mouse_remove,
+ .suspend = nvec_mouse_suspend,
+ .resume = nvec_mouse_resume,
+};
+
+static struct nvec_device nvec_mouse_device = {
+ .name = "nvec_mouse",
+ .driver = &nvec_mouse,
+};
+
+static int __init nvec_mouse_init(void)
+{
+ int err;
+
+ err = nvec_register_driver(&nvec_mouse);
+ if (err)
+ {
+ pr_err("**nvec_mouse_init: nvec_register_driver: fail\n");
+ return err;
+ }
+
+ err = nvec_register_device(&nvec_mouse_device);
+ if (err)
+ {
+ pr_err("**nvec_mouse_init: nvec_device_add: fail\n");
+ nvec_unregister_driver(&nvec_mouse);
+ return err;
+ }
+
+ return 0;
+}
+
+static void __exit nvec_mouse_exit(void)
+{
+ nvec_unregister_device(&nvec_mouse_device);
+ nvec_unregister_driver(&nvec_mouse);
+}
+
+module_init(nvec_mouse_init);
+module_exit(nvec_mouse_exit);
+
diff --git a/drivers/power/nvec_battery.c b/drivers/power/nvec_battery.c
index d0b2a06410d4..5db17a6a10be 100644
--- a/drivers/power/nvec_battery.c
+++ b/drivers/power/nvec_battery.c
@@ -25,7 +25,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/device.h>
#include <linux/debugfs.h>
#include <linux/power_supply.h>
#include <linux/wakelock.h>
@@ -34,6 +34,8 @@
#include "nvcommon.h"
#include "nvos.h"
#include "nvodm_battery.h"
+#include "nvec_device.h"
+
/* This defines the manufacturer name and model name length */
#define BATTERY_INFO_NAME_LEN 30
@@ -416,7 +418,7 @@ static void tegra_battery_poll_timer_func(unsigned long unused)
jiffies + msecs_to_jiffies(NVBATTERY_POLLING_INTERVAL));
}
-static int tegra_battery_probe(struct platform_device *pdev)
+static int nvec_battery_probe(struct nvec_device *pdev)
{
int i;
NvBool result = NV_FALSE;
@@ -445,7 +447,7 @@ static int tegra_battery_probe(struct platform_device *pdev)
return 0;
}
-static int tegra_battery_remove(struct platform_device *pdev)
+static int nvec_battery_remove(struct nvec_device *pdev)
{
unsigned int i = 0;
@@ -469,7 +471,7 @@ static int tegra_battery_remove(struct platform_device *pdev)
return 0;
}
-static int tegra_battery_suspend(struct platform_device *dev,
+static int nvec_battery_suspend(struct nvec_device *dev,
pm_message_t state)
{
/* Kill the Battery Polling timer */
@@ -477,7 +479,7 @@ static int tegra_battery_suspend(struct platform_device *dev,
return 0;
}
-static int tegra_battery_resume(struct platform_device *dev)
+static int nvec_battery_resume(struct nvec_device *dev)
{
/*Create Battery Polling timer */
setup_timer(&battery_poll_timer, tegra_battery_poll_timer_func, 0);
@@ -486,29 +488,48 @@ static int tegra_battery_resume(struct platform_device *dev)
return 0;
}
-static struct platform_driver tegra_battery_driver = {
- .probe = tegra_battery_probe,
- .remove = tegra_battery_remove,
- .suspend= tegra_battery_suspend,
- .resume = tegra_battery_resume,
- .driver = {
- .name = "tegra_battery",
- .owner = THIS_MODULE,
- },
+static struct nvec_driver nvec_battery_driver = {
+ .name = "nvec_battery",
+ .probe = nvec_battery_probe,
+ .remove = nvec_battery_remove,
+ .suspend = nvec_battery_suspend,
+ .resume = nvec_battery_resume,
+};
+
+static struct nvec_device nvec_battery_device = {
+ .name = "nvec_battery",
+ .driver = &nvec_battery_driver,
};
-static int __init tegra_battery_init(void)
+static int __init nvec_battery_init(void)
{
- platform_driver_register(&tegra_battery_driver);
+ int err;
+
+ err = nvec_register_driver(&nvec_battery_driver);
+ if (err)
+ {
+ pr_err("**nvec_battery_init: nvec_register_driver: fail\n");
+ return err;
+ }
+
+ err = nvec_register_device(&nvec_battery_device);
+ if (err)
+ {
+ pr_err("**nvec_battery_init: nvec_device_add: fail\n");
+ nvec_unregister_driver(&nvec_battery_driver);
+ return err;
+ }
+
return 0;
}
-static void __exit tegra_battery_exit(void)
+static void __exit nvec_battery_exit(void)
{
- platform_driver_unregister(&tegra_battery_driver);
+ nvec_unregister_device(&nvec_battery_device);
+ nvec_unregister_driver(&nvec_battery_driver);
}
-module_init(tegra_battery_init);
-module_exit(tegra_battery_exit);
+module_init(nvec_battery_init);
+module_exit(nvec_battery_exit);
MODULE_DESCRIPTION("TEGRA EC based Battery Driver");